xref: /linux/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_calcs_dchub.c (revision 49bda4826843be0ef97a162009a29ea3a63f3935)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4 
5 #include "dml2_core_dcn5_calcs_dchub.h"
6 #include "dml2_core_utils.h"
7 
dcn5_calculate_max_det_and_min_compressed_buffer_size(unsigned int ConfigReturnBufferSizeInKByte,unsigned int ConfigReturnBufferSegmentSizeInKByte,unsigned int ROBBufferSizeInKByte,unsigned int MaxNumDPP,unsigned int nomDETInKByteOverrideEnable,unsigned int nomDETInKByteOverrideValue,bool is_mrq_present,unsigned int * MaxTotalDETInKByte,unsigned int * nomDETInKByte,unsigned int * MinCompressedBufferSizeInKByte)8 void dcn5_calculate_max_det_and_min_compressed_buffer_size(
9 		unsigned int ConfigReturnBufferSizeInKByte,
10 		unsigned int ConfigReturnBufferSegmentSizeInKByte,
11 		unsigned int ROBBufferSizeInKByte,
12 		unsigned int MaxNumDPP,
13 		unsigned int nomDETInKByteOverrideEnable, // VBA_DELTA, allow DV to override default DET size
14 		unsigned int nomDETInKByteOverrideValue, // VBA_DELTA
15 		bool is_mrq_present,
16 
17 		// Output
18 		unsigned int *MaxTotalDETInKByte,
19 		unsigned int *nomDETInKByte,
20 		unsigned int *MinCompressedBufferSizeInKByte)
21 {
22 	if (is_mrq_present)
23 		*MaxTotalDETInKByte = (unsigned int) math_ceil2((double)(ConfigReturnBufferSizeInKByte + ROBBufferSizeInKByte)*4/5, 64);
24 	else
25 		*MaxTotalDETInKByte = ConfigReturnBufferSizeInKByte - ConfigReturnBufferSegmentSizeInKByte;
26 
27 	*nomDETInKByte = (unsigned int)(math_floor2((double)*MaxTotalDETInKByte / (double)MaxNumDPP, ConfigReturnBufferSegmentSizeInKByte));
28 	*MinCompressedBufferSizeInKByte = ConfigReturnBufferSizeInKByte - *MaxTotalDETInKByte;
29 
30 	DML_LOG_VERBOSE("DML::%s: is_mrq_present = %u\n", __func__, is_mrq_present);
31 	DML_LOG_VERBOSE("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, ConfigReturnBufferSizeInKByte);
32 	DML_LOG_VERBOSE("DML::%s: ConfigReturnBufferSegmentSizeInKByte = %u\n", __func__, ConfigReturnBufferSegmentSizeInKByte);
33 	DML_LOG_VERBOSE("DML::%s: ROBBufferSizeInKByte = %u\n", __func__, ROBBufferSizeInKByte);
34 	DML_LOG_VERBOSE("DML::%s: MaxNumDPP = %u\n", __func__, MaxNumDPP);
35 	DML_LOG_VERBOSE("DML::%s: MaxTotalDETInKByte = %u\n", __func__, *MaxTotalDETInKByte);
36 	DML_LOG_VERBOSE("DML::%s: nomDETInKByte = %u\n", __func__, *nomDETInKByte);
37 	DML_LOG_VERBOSE("DML::%s: MinCompressedBufferSizeInKByte = %u\n", __func__, *MinCompressedBufferSizeInKByte);
38 
39 	if (nomDETInKByteOverrideEnable) {
40 		*nomDETInKByte = nomDETInKByteOverrideValue;
41 		DML_LOG_VERBOSE("DML::%s: nomDETInKByte = %u (overrided)\n", __func__, *nomDETInKByte);
42 	}
43 }
44 
dcn5_calculate_byte_per_pixel_and_block_sizes(enum dml2_source_format_class SourcePixelFormat,enum dml2_swizzle_mode SurfaceTiling,unsigned int pitch_y,unsigned int pitch_c,unsigned int * BytePerPixelY,unsigned int * BytePerPixelC,double * BytePerPixelDETY,double * BytePerPixelDETC,unsigned int * BlockHeight256BytesY,unsigned int * BlockHeight256BytesC,unsigned int * BlockWidth256BytesY,unsigned int * BlockWidth256BytesC,unsigned int * MacroTileHeightY,unsigned int * MacroTileHeightC,unsigned int * MacroTileWidthY,unsigned int * MacroTileWidthC,bool * surf_linear128_l,bool * surf_linear128_c)45 void dcn5_calculate_byte_per_pixel_and_block_sizes(
46 	enum dml2_source_format_class SourcePixelFormat,
47 	enum dml2_swizzle_mode SurfaceTiling,
48 	unsigned int pitch_y,
49 	unsigned int pitch_c,
50 
51 	// Output
52 	unsigned int *BytePerPixelY,
53 	unsigned int *BytePerPixelC,
54 	double *BytePerPixelDETY,
55 	double *BytePerPixelDETC,
56 	unsigned int *BlockHeight256BytesY,
57 	unsigned int *BlockHeight256BytesC,
58 	unsigned int *BlockWidth256BytesY,
59 	unsigned int *BlockWidth256BytesC,
60 	unsigned int *MacroTileHeightY,
61 	unsigned int *MacroTileHeightC,
62 	unsigned int *MacroTileWidthY,
63 	unsigned int *MacroTileWidthC,
64 	bool *surf_linear128_l,
65 	bool *surf_linear128_c)
66 {
67 	*BytePerPixelDETY = 0;
68 	*BytePerPixelDETC = 0;
69 	*BytePerPixelY = 0;
70 	*BytePerPixelC = 0;
71 
72 	if (SourcePixelFormat == dml2_444_64) {
73 		*BytePerPixelDETY = 8;
74 		*BytePerPixelDETC = 0;
75 		*BytePerPixelY = 8;
76 		*BytePerPixelC = 0;
77 	} else if (SourcePixelFormat == dml2_444_32 ||
78 		   SourcePixelFormat == dml2_rgbe ||
79 		   SourcePixelFormat == dml2_422_packed_12) {
80 		*BytePerPixelDETY = 4;
81 		*BytePerPixelDETC = 0;
82 		*BytePerPixelY = 4;
83 		*BytePerPixelC = 0;
84 	} else if (SourcePixelFormat == dml2_422_packed_10) {
85 		*BytePerPixelDETY = (double)(8.0 / 3);
86 		*BytePerPixelDETC = 0;
87 		*BytePerPixelY = 4;
88 		*BytePerPixelC = 0;
89 	} else if (SourcePixelFormat == dml2_444_16 || SourcePixelFormat == dml2_mono_16 || SourcePixelFormat == dml2_422_packed_8) {
90 		*BytePerPixelDETY = 2;
91 		*BytePerPixelDETC = 0;
92 		*BytePerPixelY = 2;
93 		*BytePerPixelC = 0;
94 	} else if (SourcePixelFormat == dml2_444_8 || SourcePixelFormat == dml2_mono_8) {
95 		*BytePerPixelDETY = 1;
96 		*BytePerPixelDETC = 0;
97 		*BytePerPixelY = 1;
98 		*BytePerPixelC = 0;
99 	} else if (SourcePixelFormat == dml2_rgbe_alpha) {
100 		*BytePerPixelDETY = 4;
101 		*BytePerPixelDETC = 1;
102 		*BytePerPixelY = 4;
103 		*BytePerPixelC = 1;
104 	} else if (SourcePixelFormat == dml2_420_8 || SourcePixelFormat == dml2_422_planar_8) {
105 		*BytePerPixelDETY = 1;
106 		*BytePerPixelDETC = 2;
107 		*BytePerPixelY = 1;
108 		*BytePerPixelC = 2;
109 	} else if (SourcePixelFormat == dml2_420_12 || SourcePixelFormat == dml2_422_planar_12) {
110 		*BytePerPixelDETY = 2;
111 		*BytePerPixelDETC = 4;
112 		*BytePerPixelY = 2;
113 		*BytePerPixelC = 4;
114 	} else if (SourcePixelFormat == dml2_420_10 || SourcePixelFormat == dml2_422_planar_10) {
115 		*BytePerPixelDETY = (double)(4.0 / 3);
116 		*BytePerPixelDETC = (double)(8.0 / 3);
117 		*BytePerPixelY = 2;
118 		*BytePerPixelC = 4;
119 	} else {
120 		DML_LOG_VERBOSE("ERROR: DML::%s: SourcePixelFormat = %u not supported!\n", __func__, SourcePixelFormat);
121 		DML_ASSERT(0);
122 	}
123 
124 	DML_LOG_VERBOSE("DML::%s: SourcePixelFormat = %u\n", __func__, SourcePixelFormat);
125 	DML_LOG_VERBOSE("DML::%s: BytePerPixelDETY = %f\n", __func__, *BytePerPixelDETY);
126 	DML_LOG_VERBOSE("DML::%s: BytePerPixelDETC = %f\n", __func__, *BytePerPixelDETC);
127 	DML_LOG_VERBOSE("DML::%s: BytePerPixelY = %u\n", __func__, *BytePerPixelY);
128 	DML_LOG_VERBOSE("DML::%s: BytePerPixelC = %u\n", __func__, *BytePerPixelC);
129 	DML_LOG_VERBOSE("DML::%s: pitch_y = %u\n", __func__, pitch_y);
130 	DML_LOG_VERBOSE("DML::%s: pitch_c = %u\n", __func__, pitch_c);
131 
132 	unsigned int pixel_per_element = dml2_core_utils_is_422_packed(SourcePixelFormat) ? 2 : 1;
133 	if (dml2_core_utils_get_gfx_version(SurfaceTiling) == 11) {
134 		*surf_linear128_l = 0;
135 		*surf_linear128_c = 0;
136 	} else {
137 		if (SurfaceTiling == dml2_sw_linear) {
138 			*surf_linear128_l = (((pitch_y * pixel_per_element * *BytePerPixelY) % 256) != 0);
139 
140 			if (dml2_core_utils_is_420(SourcePixelFormat) || dml2_core_utils_is_422_planar(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha)
141 				*surf_linear128_c = (((pitch_c * *BytePerPixelC) % 256) != 0);
142 		}
143 	}
144 	DML_LOG_VERBOSE("DML::%s: surf_linear128_l = %u\n", __func__, *surf_linear128_l);
145 	DML_LOG_VERBOSE("DML::%s: surf_linear128_c = %u\n", __func__, *surf_linear128_c);
146 
147 	if (!(dml2_core_utils_is_420(SourcePixelFormat) || dml2_core_utils_is_422_planar(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha)) {
148 		if (SurfaceTiling == dml2_sw_linear) {
149 			*BlockHeight256BytesY = 1;
150 		} else if (SourcePixelFormat == dml2_444_64 || SourcePixelFormat == dml2_422_packed_10 || SourcePixelFormat == dml2_422_packed_12) {
151 			*BlockHeight256BytesY = 4;
152 		} else if (SourcePixelFormat == dml2_444_8) {
153 			*BlockHeight256BytesY = 16;
154 		} else {
155 			*BlockHeight256BytesY = 8;
156 		}
157 		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
158 		*BlockHeight256BytesC = 0;
159 		*BlockWidth256BytesC = 0;
160 	} else { // dual plane
161 		if (SurfaceTiling == dml2_sw_linear) {
162 			*BlockHeight256BytesY = 1;
163 			*BlockHeight256BytesC = 1;
164 		} else if (SourcePixelFormat == dml2_rgbe_alpha) {
165 			*BlockHeight256BytesY = 8;
166 			*BlockHeight256BytesC = 16;
167 		} else if (SourcePixelFormat == dml2_420_8 || SourcePixelFormat == dml2_422_planar_8) {
168 			*BlockHeight256BytesY = 16;
169 			*BlockHeight256BytesC = 8;
170 		} else {
171 			*BlockHeight256BytesY = 8;
172 			*BlockHeight256BytesC = 8;
173 		}
174 		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
175 		*BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC;
176 	}
177 	DML_LOG_VERBOSE("DML::%s: BlockWidth256BytesY = %u\n", __func__, *BlockWidth256BytesY);
178 	DML_LOG_VERBOSE("DML::%s: BlockHeight256BytesY = %u\n", __func__, *BlockHeight256BytesY);
179 	DML_LOG_VERBOSE("DML::%s: BlockWidth256BytesC = %u\n", __func__, *BlockWidth256BytesC);
180 	DML_LOG_VERBOSE("DML::%s: BlockHeight256BytesC = %u\n", __func__, *BlockHeight256BytesC);
181 
182 	if (dml2_core_utils_get_gfx_version(SurfaceTiling) == 11) {
183 		if (SurfaceTiling == dml2_gfx11_sw_linear) {
184 			*MacroTileHeightY = *BlockHeight256BytesY;
185 			*MacroTileWidthY = 256 / *BytePerPixelY / *MacroTileHeightY;
186 			*MacroTileHeightC = *BlockHeight256BytesC;
187 			if (*MacroTileHeightC == 0) {
188 				*MacroTileWidthC = 0;
189 			} else {
190 				*MacroTileWidthC = 256 / *BytePerPixelC / *MacroTileHeightC;
191 			}
192 		} else if (SurfaceTiling == dml2_gfx11_sw_64kb_d || SurfaceTiling == dml2_gfx11_sw_64kb_d_t || SurfaceTiling == dml2_gfx11_sw_64kb_d_x || SurfaceTiling == dml2_gfx11_sw_64kb_r_x) {
193 			*MacroTileHeightY = 16 * *BlockHeight256BytesY;
194 			*MacroTileWidthY = 65536 / *BytePerPixelY / *MacroTileHeightY;
195 			*MacroTileHeightC = 16 * *BlockHeight256BytesC;
196 			if (*MacroTileHeightC == 0) {
197 				*MacroTileWidthC = 0;
198 			} else {
199 				*MacroTileWidthC = 65536 / *BytePerPixelC / *MacroTileHeightC;
200 			}
201 		} else {
202 			*MacroTileHeightY = 32 * *BlockHeight256BytesY;
203 			*MacroTileWidthY = 65536 * 4 / *BytePerPixelY / *MacroTileHeightY;
204 			*MacroTileHeightC = 32 * *BlockHeight256BytesC;
205 			if (*MacroTileHeightC == 0) {
206 				*MacroTileWidthC = 0;
207 			} else {
208 				*MacroTileWidthC = 65536 * 4 / *BytePerPixelC / *MacroTileHeightC;
209 			}
210 		}
211 	} else {
212 		unsigned int macro_tile_size_bytes_y = dml2_core_utils_get_tile_block_size_bytes(SurfaceTiling, *BytePerPixelY);
213 		unsigned int macro_tile_size_bytes_c = dml2_core_utils_get_tile_block_size_bytes(SurfaceTiling, *BytePerPixelY);
214 		unsigned int macro_tile_scale = 1; // macro tile to 256B req scaling
215 
216 		if (SurfaceTiling == dml2_sw_linear) {
217 			macro_tile_scale = 1;
218 		} else if (SurfaceTiling == dml2_sw_4kb_2d) {
219 			macro_tile_scale = 4;
220 		} else if (SurfaceTiling == dml2_sw_64kb_2d) {
221 			macro_tile_scale = 16;
222 		} else if (SurfaceTiling == dml2_sw_256kb_2d) {
223 			macro_tile_scale = 32;
224 		} else {
225 			DML_LOG_VERBOSE("ERROR: Invalid SurfaceTiling setting! val=%u\n", SurfaceTiling);
226 			DML_ASSERT(0);
227 		}
228 
229 		*MacroTileHeightY = macro_tile_scale * *BlockHeight256BytesY;
230 		*MacroTileWidthY = macro_tile_size_bytes_y / *BytePerPixelY / *MacroTileHeightY;
231 		*MacroTileHeightC = macro_tile_scale * *BlockHeight256BytesC;
232 		if (*MacroTileHeightC == 0) {
233 			*MacroTileWidthC = 0;
234 		} else {
235 			*MacroTileWidthC = macro_tile_size_bytes_c / *BytePerPixelC / *MacroTileHeightC;
236 		}
237 	}
238 
239 	DML_LOG_VERBOSE("DML::%s: MacroTileWidthY = %u\n", __func__, *MacroTileWidthY);
240 	DML_LOG_VERBOSE("DML::%s: MacroTileHeightY = %u\n", __func__, *MacroTileHeightY);
241 	DML_LOG_VERBOSE("DML::%s: MacroTileWidthC = %u\n", __func__, *MacroTileWidthC);
242 	DML_LOG_VERBOSE("DML::%s: MacroTileHeightC = %u\n", __func__, *MacroTileHeightC);
243 }
244 
dcn5_calculate_swath_width(const struct dml2_display_cfg * display_cfg,bool ForceSingleDPP,unsigned int NumberOfActiveSurfaces,enum dml2_odm_mode ODMMode[],unsigned int BytePerPixY[],unsigned int BytePerPixC[],unsigned int Read256BytesBlockHeightY[],unsigned int Read256BytesBlockHeightC[],unsigned int Read256BytesBlockWidthY[],unsigned int Read256BytesBlockWidthC[],bool surf_linear128_l[],bool surf_linear128_c[],unsigned int DPPPerSurface[],unsigned int req_per_swath_ub_l[],unsigned int req_per_swath_ub_c[],unsigned int SwathWidthSingleDPPY[],unsigned int SwathWidthSingleDPPC[],unsigned int SwathWidthY[],unsigned int SwathWidthC[],unsigned int MaximumSwathHeightY[],unsigned int MaximumSwathHeightC[],unsigned int swath_width_luma_ub[],unsigned int swath_width_chroma_ub[],unsigned int swath_width_luma_ub_single_dpp[],unsigned int swath_width_chroma_ub_single_dpp[])245 void dcn5_calculate_swath_width(
246 		const struct dml2_display_cfg *display_cfg,
247 		bool ForceSingleDPP,
248 		unsigned int NumberOfActiveSurfaces,
249 		enum dml2_odm_mode ODMMode[],
250 		unsigned int BytePerPixY[],
251 		unsigned int BytePerPixC[],
252 		unsigned int Read256BytesBlockHeightY[],
253 		unsigned int Read256BytesBlockHeightC[],
254 		unsigned int Read256BytesBlockWidthY[],
255 		unsigned int Read256BytesBlockWidthC[],
256 		bool surf_linear128_l[],
257 		bool surf_linear128_c[],
258 		unsigned int DPPPerSurface[],
259 
260 		// Output
261 		unsigned int req_per_swath_ub_l[],
262 		unsigned int req_per_swath_ub_c[],
263 		unsigned int SwathWidthSingleDPPY[],
264 		unsigned int SwathWidthSingleDPPC[],
265 		unsigned int SwathWidthY[], // per-pipe
266 		unsigned int SwathWidthC[], // per-pipe
267 		unsigned int MaximumSwathHeightY[],
268 		unsigned int MaximumSwathHeightC[],
269 		unsigned int swath_width_luma_ub[], // per-pipe
270 		unsigned int swath_width_chroma_ub[], // per-pipe
271 		unsigned int swath_width_luma_ub_single_dpp[],
272 		unsigned int swath_width_chroma_ub_single_dpp[])
273 {
274 	(void)BytePerPixY;
275 	enum dml2_odm_mode MainSurfaceODMMode;
276 	double odm_hactive_factor = 1.0;
277 	unsigned int req_width_horz_y;
278 	unsigned int req_width_horz_c;
279 	unsigned int surface_width_ub_l;
280 	unsigned int surface_height_ub_l;
281 	unsigned int surface_width_ub_c;
282 	unsigned int surface_height_ub_c;
283 
284 	DML_LOG_VERBOSE("DML::%s: ForceSingleDPP = %u\n", __func__, ForceSingleDPP);
285 	DML_LOG_VERBOSE("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
286 
287 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
288 		if (!dml2_core_utils_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle)) {
289 			SwathWidthSingleDPPY[k] = (unsigned int)display_cfg->plane_descriptors[k].composition.viewport.plane0.width;
290 		} else {
291 			SwathWidthSingleDPPY[k] = (unsigned int)display_cfg->plane_descriptors[k].composition.viewport.plane0.height;
292 		}
293 
294 		DML_LOG_VERBOSE("DML::%s: k=%u ViewportWidth=%lu\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.plane0.width);
295 		DML_LOG_VERBOSE("DML::%s: k=%u ViewportHeight=%lu\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.plane0.height);
296 		DML_LOG_VERBOSE("DML::%s: k=%u DPPPerSurface=%u\n", __func__, k, DPPPerSurface[k]);
297 
298 		MainSurfaceODMMode = ODMMode[k];
299 
300 		if (ForceSingleDPP) {
301 			SwathWidthY[k] = SwathWidthSingleDPPY[k];
302 		} else {
303 			if (MainSurfaceODMMode == dml2_odm_mode_combine_4to1)
304 				odm_hactive_factor = 4.0;
305 			else if (MainSurfaceODMMode == dml2_odm_mode_combine_3to1)
306 				odm_hactive_factor = 3.0;
307 			else if (MainSurfaceODMMode == dml2_odm_mode_combine_2to1)
308 				odm_hactive_factor = 2.0;
309 
310 			if (MainSurfaceODMMode == dml2_odm_mode_combine_4to1 || MainSurfaceODMMode == dml2_odm_mode_combine_3to1 || MainSurfaceODMMode == dml2_odm_mode_combine_2to1) {
311 				SwathWidthY[k] = (unsigned int)(math_min2((double)SwathWidthSingleDPPY[k], math_round((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active / odm_hactive_factor * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio)));
312 			} else if (DPPPerSurface[k] == 2) {
313 				SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2;
314 			} else {
315 				SwathWidthY[k] = SwathWidthSingleDPPY[k];
316 			}
317 		}
318 
319 		DML_LOG_VERBOSE("DML::%s: k=%u HActive=%lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active);
320 		DML_LOG_VERBOSE("DML::%s: k=%u HRatio=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio);
321 		DML_LOG_VERBOSE("DML::%s: k=%u MainSurfaceODMMode=%u\n", __func__, k, MainSurfaceODMMode);
322 		DML_LOG_VERBOSE("DML::%s: k=%u SwathWidthSingleDPPY=%u\n", __func__, k, SwathWidthSingleDPPY[k]);
323 		DML_LOG_VERBOSE("DML::%s: k=%u SwathWidthY=%u\n", __func__, k, SwathWidthY[k]);
324 
325 		if (dml2_core_utils_is_420(display_cfg->plane_descriptors[k].pixel_format) || dml2_core_utils_is_422_planar(display_cfg->plane_descriptors[k].pixel_format)) {
326 			SwathWidthC[k] = SwathWidthY[k] / 2;
327 			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2;
328 		} else {
329 			SwathWidthC[k] = SwathWidthY[k];
330 			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k];
331 		}
332 
333 		if (ForceSingleDPP == true) {
334 			SwathWidthY[k] = SwathWidthSingleDPPY[k];
335 			SwathWidthC[k] = SwathWidthSingleDPPC[k];
336 		}
337 
338 		req_width_horz_y = Read256BytesBlockWidthY[k];
339 		req_width_horz_c = Read256BytesBlockWidthC[k];
340 
341 		if (surf_linear128_l[k])
342 			req_width_horz_y = req_width_horz_y / 2;
343 
344 		if (surf_linear128_c[k])
345 			req_width_horz_c = req_width_horz_c / 2;
346 
347 		surface_width_ub_l = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane0.width, req_width_horz_y);
348 		surface_height_ub_l = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane0.height, Read256BytesBlockHeightY[k]);
349 		surface_width_ub_c = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane1.width, req_width_horz_c);
350 		surface_height_ub_c = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane1.height, Read256BytesBlockHeightC[k]);
351 
352 		DML_LOG_VERBOSE("DML::%s: k=%u surface_width_ub_l=%u\n", __func__, k, surface_width_ub_l);
353 		DML_LOG_VERBOSE("DML::%s: k=%u surface_height_ub_l=%u\n", __func__, k, surface_height_ub_l);
354 		DML_LOG_VERBOSE("DML::%s: k=%u surface_width_ub_c=%u\n", __func__, k, surface_width_ub_c);
355 		DML_LOG_VERBOSE("DML::%s: k=%u surface_height_ub_c=%u\n", __func__, k, surface_height_ub_c);
356 		DML_LOG_VERBOSE("DML::%s: k=%u req_width_horz_y=%u\n", __func__, k, req_width_horz_y);
357 		DML_LOG_VERBOSE("DML::%s: k=%u req_width_horz_c=%u\n", __func__, k, req_width_horz_c);
358 		DML_LOG_VERBOSE("DML::%s: k=%u Read256BytesBlockWidthY=%u\n", __func__, k, Read256BytesBlockWidthY[k]);
359 		DML_LOG_VERBOSE("DML::%s: k=%u Read256BytesBlockHeightY=%u\n", __func__, k, Read256BytesBlockHeightY[k]);
360 		DML_LOG_VERBOSE("DML::%s: k=%u Read256BytesBlockWidthC=%u\n", __func__, k, Read256BytesBlockWidthC[k]);
361 		DML_LOG_VERBOSE("DML::%s: k=%u Read256BytesBlockHeightC=%u\n", __func__, k, Read256BytesBlockHeightC[k]);
362 		DML_LOG_VERBOSE("DML::%s: k=%u req_width_horz_y=%u\n", __func__, k, req_width_horz_y);
363 		DML_LOG_VERBOSE("DML::%s: k=%u req_width_horz_c=%u\n", __func__, k, req_width_horz_c);
364 		DML_LOG_VERBOSE("DML::%s: k=%u ViewportStationary=%u\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.stationary);
365 		DML_LOG_VERBOSE("DML::%s: k=%u DPPPerSurface=%u\n", __func__, k, DPPPerSurface[k]);
366 
367 		req_per_swath_ub_l[k] = 0;
368 		req_per_swath_ub_c[k] = 0;
369 		if (!dml2_core_utils_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle)) {
370 			MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k];
371 			MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k];
372 			if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) {
373 				swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_width_ub_l,
374 					math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start
375 						+ SwathWidthY[k] + req_width_horz_y - 1, req_width_horz_y)
376 					- math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start, req_width_horz_y)));
377 				swath_width_luma_ub_single_dpp[k] = swath_width_luma_ub[k];
378 			} else {
379 				swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_width_ub_l, math_ceil2((double)SwathWidthY[k] - 1,
380 					req_width_horz_y) + req_width_horz_y));
381 				swath_width_luma_ub_single_dpp[k] = (unsigned int)(math_min2(surface_width_ub_l, math_ceil2((double)SwathWidthSingleDPPY[k] - 1,
382 					req_width_horz_y) + req_width_horz_y));
383 			}
384 			req_per_swath_ub_l[k] = swath_width_luma_ub[k] / req_width_horz_y;
385 
386 			if (BytePerPixC[k] > 0) {
387 				if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) {
388 					swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_width_ub_c,
389 						math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start
390 							+ SwathWidthC[k] + req_width_horz_c - 1, req_width_horz_c)
391 						- math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start, req_width_horz_c)));
392 					swath_width_chroma_ub_single_dpp[k] = swath_width_chroma_ub[k];
393 				} else {
394 					swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_width_ub_c, math_ceil2((double)SwathWidthC[k] - 1,
395 						req_width_horz_c) + req_width_horz_c));
396 					swath_width_chroma_ub_single_dpp[k] = (unsigned int)(math_min2(surface_width_ub_c, math_ceil2((double)SwathWidthSingleDPPC[k] - 1,
397 						req_width_horz_c) + req_width_horz_c));
398 				}
399 				req_per_swath_ub_c[k] = swath_width_chroma_ub[k] / req_width_horz_c;
400 			} else {
401 				swath_width_chroma_ub[k] = 0;
402 			}
403 		} else {
404 			MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k];
405 			MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k];
406 
407 			if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) {
408 				swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_height_ub_l,
409 					math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start
410 						+ SwathWidthY[k] + Read256BytesBlockHeightY[k] - 1, Read256BytesBlockHeightY[k])
411 					- math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start, Read256BytesBlockHeightY[k])));
412 				swath_width_luma_ub_single_dpp[k] = swath_width_luma_ub[k];
413 			} else {
414 				swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_height_ub_l, math_ceil2((double)SwathWidthY[k] - 1,
415 					Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]));
416 				swath_width_luma_ub_single_dpp[k] = (unsigned int)(math_min2(surface_height_ub_l, math_ceil2((double)SwathWidthSingleDPPY[k] - 1,
417 					Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]));
418 			}
419 			req_per_swath_ub_l[k] = swath_width_luma_ub[k] / Read256BytesBlockHeightY[k];
420 			if (BytePerPixC[k] > 0) {
421 				if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) {
422 					swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_height_ub_c,
423 						math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start
424 							+ SwathWidthC[k] + Read256BytesBlockHeightC[k] - 1, Read256BytesBlockHeightC[k])
425 						- math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start, Read256BytesBlockHeightC[k])));
426 					swath_width_chroma_ub_single_dpp[k] = swath_width_chroma_ub[k];
427 				} else {
428 					swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_height_ub_c, math_ceil2((double)SwathWidthC[k] - 1,
429 						Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]));
430 					swath_width_chroma_ub_single_dpp[k] = (unsigned int)(math_min2(surface_height_ub_c, math_ceil2((double)SwathWidthSingleDPPC[k] - 1,
431 						Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]));
432 				}
433 				req_per_swath_ub_c[k] = swath_width_chroma_ub[k] / Read256BytesBlockHeightC[k];
434 			} else {
435 				swath_width_chroma_ub[k] = 0;
436 			}
437 		}
438 
439 		DML_LOG_VERBOSE("DML::%s: k=%u swath_width_luma_ub=%u\n", __func__, k, swath_width_luma_ub[k]);
440 		DML_LOG_VERBOSE("DML::%s: k=%u swath_width_chroma_ub=%u\n", __func__, k, swath_width_chroma_ub[k]);
441 		DML_LOG_VERBOSE("DML::%s: k=%u MaximumSwathHeightY=%u\n", __func__, k, MaximumSwathHeightY[k]);
442 		DML_LOG_VERBOSE("DML::%s: k=%u MaximumSwathHeightC=%u\n", __func__, k, MaximumSwathHeightC[k]);
443 		DML_LOG_VERBOSE("DML::%s: k=%u req_per_swath_ub_l=%u\n", __func__, k, req_per_swath_ub_l[k]);
444 		DML_LOG_VERBOSE("DML::%s: k=%u req_per_swath_ub_c=%u\n", __func__, k, req_per_swath_ub_c[k]);
445 	}
446 }
447 
dcn5_is_unbounded_request(bool unb_req_force_en,bool unb_req_force_val,unsigned int TotalNumberOfActiveDPP,bool NoChromaOrLinear)448 static bool dcn5_is_unbounded_request(bool unb_req_force_en, bool unb_req_force_val, unsigned int TotalNumberOfActiveDPP, bool NoChromaOrLinear)
449 {
450 	bool unb_req_ok = false;
451 	bool unb_req_en = false;
452 
453 	unb_req_ok = (TotalNumberOfActiveDPP == 1 && NoChromaOrLinear);
454 	unb_req_en = unb_req_ok;
455 
456 	if (unb_req_force_en) {
457 		unb_req_en = unb_req_force_val && unb_req_ok;
458 	}
459 	DML_LOG_VERBOSE("DML::%s: unb_req_force_en = %u\n", __func__, unb_req_force_en);
460 	DML_LOG_VERBOSE("DML::%s: unb_req_force_val = %u\n", __func__, unb_req_force_val);
461 	DML_LOG_VERBOSE("DML::%s: unb_req_ok = %u\n", __func__, unb_req_ok);
462 	DML_LOG_VERBOSE("DML::%s: unb_req_en = %u\n", __func__, unb_req_en);
463 	return unb_req_en;
464 }
465 
dcn5_calculate_det_buffer_size(struct dml2_core_shared_CalculateDETBufferSize_locals * l,const struct dml2_display_cfg * display_cfg,bool ForceSingleDPP,unsigned int NumberOfActiveSurfaces,bool UnboundedRequestEnabled,unsigned int nomDETInKByte,unsigned int MaxTotalDETInKByte,unsigned int ConfigReturnBufferSizeInKByte,unsigned int MinCompressedBufferSizeInKByte,unsigned int ConfigReturnBufferSegmentSizeInkByte,unsigned int CompressedBufferSegmentSizeInkByte,double ReadBandwidthLuma[],double ReadBandwidthChroma[],unsigned int full_swath_bytes_l[],unsigned int full_swath_bytes_c[],unsigned int DPPPerSurface[],unsigned int DETBufferSizeInKByte[],unsigned int * CompressedBufferSizeInkByte)466 static void dcn5_calculate_det_buffer_size(
467 		struct dml2_core_shared_CalculateDETBufferSize_locals *l,
468 		const struct dml2_display_cfg *display_cfg,
469 		bool ForceSingleDPP,
470 		unsigned int NumberOfActiveSurfaces,
471 		bool UnboundedRequestEnabled,
472 		unsigned int nomDETInKByte,
473 		unsigned int MaxTotalDETInKByte,
474 		unsigned int ConfigReturnBufferSizeInKByte,
475 		unsigned int MinCompressedBufferSizeInKByte,
476 		unsigned int ConfigReturnBufferSegmentSizeInkByte,
477 		unsigned int CompressedBufferSegmentSizeInkByte,
478 		double ReadBandwidthLuma[],
479 		double ReadBandwidthChroma[],
480 		unsigned int full_swath_bytes_l[],
481 		unsigned int full_swath_bytes_c[],
482 		unsigned int DPPPerSurface[],
483 		// Output
484 		unsigned int DETBufferSizeInKByte[],
485 		unsigned int *CompressedBufferSizeInkByte)
486 {
487 	memset(l, 0, sizeof(struct dml2_core_shared_CalculateDETBufferSize_locals));
488 
489 	bool DETPieceAssignedToThisSurfaceAlready[DML2_MAX_PLANES];
490 	bool NextPotentialSurfaceToAssignDETPieceFound;
491 	bool MinimizeReallocationSuccess = false;
492 
493 	DML_LOG_VERBOSE("DML::%s: ForceSingleDPP = %u\n", __func__, ForceSingleDPP);
494 	DML_LOG_VERBOSE("DML::%s: nomDETInKByte = %u\n", __func__, nomDETInKByte);
495 	DML_LOG_VERBOSE("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
496 	DML_LOG_VERBOSE("DML::%s: UnboundedRequestEnabled = %u\n", __func__, UnboundedRequestEnabled);
497 	DML_LOG_VERBOSE("DML::%s: MaxTotalDETInKByte = %u\n", __func__, MaxTotalDETInKByte);
498 	DML_LOG_VERBOSE("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, ConfigReturnBufferSizeInKByte);
499 	DML_LOG_VERBOSE("DML::%s: MinCompressedBufferSizeInKByte = %u\n", __func__, MinCompressedBufferSizeInKByte);
500 	DML_LOG_VERBOSE("DML::%s: CompressedBufferSegmentSizeInkByte = %u\n", __func__, CompressedBufferSegmentSizeInkByte);
501 	DML_LOG_VERBOSE("DML::%s: ConfigReturnBufferSegmentSizeInkByte = %u\n", __func__, ConfigReturnBufferSegmentSizeInkByte);
502 
503 	// Note: Will use default det size if that fits 2 swaths
504 	if (UnboundedRequestEnabled) {
505 		if (display_cfg->plane_descriptors[0].overrides.det_size_override_kb > 0) {
506 			DETBufferSizeInKByte[0] = display_cfg->plane_descriptors[0].overrides.det_size_override_kb;
507 		} else {
508 			DETBufferSizeInKByte[0] = (unsigned int)math_max2(128.0, math_ceil2(2.0 * ((double)full_swath_bytes_l[0] + (double)full_swath_bytes_c[0]) / 1024.0, ConfigReturnBufferSegmentSizeInkByte));
509 		}
510 		*CompressedBufferSizeInkByte = ConfigReturnBufferSizeInKByte - DETBufferSizeInKByte[0];
511 	} else {
512 		l->DETBufferSizePoolInKByte = MaxTotalDETInKByte;
513 		for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
514 			DETBufferSizeInKByte[k] = 0;
515 			if (dml2_core_utils_is_420(display_cfg->plane_descriptors[k].pixel_format) || dml2_core_utils_is_422_planar(display_cfg->plane_descriptors[k].pixel_format)) {
516 				l->max_minDET = nomDETInKByte - ConfigReturnBufferSegmentSizeInkByte;
517 			} else {
518 				l->max_minDET = nomDETInKByte;
519 			}
520 			l->minDET = 128;
521 			l->minDET_pipe = 0;
522 
523 			// add DET resource until can hold 2 full swaths
524 			while (l->minDET <= l->max_minDET && l->minDET_pipe == 0) {
525 				if (2.0 * ((double)full_swath_bytes_l[k] + (double)full_swath_bytes_c[k]) / 1024.0 <= l->minDET)
526 					l->minDET_pipe = l->minDET;
527 				l->minDET = l->minDET + ConfigReturnBufferSegmentSizeInkByte;
528 			}
529 
530 			DML_LOG_VERBOSE("DML::%s: k=%u minDET = %u\n", __func__, k, l->minDET);
531 			DML_LOG_VERBOSE("DML::%s: k=%u max_minDET = %u\n", __func__, k, l->max_minDET);
532 			DML_LOG_VERBOSE("DML::%s: k=%u minDET_pipe = %u\n", __func__, k, l->minDET_pipe);
533 			DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_l = %u\n", __func__, k, full_swath_bytes_l[k]);
534 			DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_c = %u\n", __func__, k, full_swath_bytes_c[k]);
535 			if (l->minDET_pipe == 0) {
536 				l->minDET_pipe = (unsigned int)(math_max2(128, math_ceil2(((double)full_swath_bytes_l[k] + (double)full_swath_bytes_c[k]) / 1024.0, ConfigReturnBufferSegmentSizeInkByte)));
537 				DML_LOG_VERBOSE("DML::%s: k=%u minDET_pipe = %u (assume each plane take half DET)\n", __func__, k, l->minDET_pipe);
538 			}
539 
540 			if (display_cfg->plane_descriptors[k].overrides.det_size_override_kb > 0) {
541 				DETBufferSizeInKByte[k] = display_cfg->plane_descriptors[k].overrides.det_size_override_kb;
542 				l->DETBufferSizePoolInKByte = l->DETBufferSizePoolInKByte - (ForceSingleDPP ? 1 : DPPPerSurface[k]) * display_cfg->plane_descriptors[k].overrides.det_size_override_kb;
543 			} else if ((ForceSingleDPP ? 1 : DPPPerSurface[k]) * l->minDET_pipe <= l->DETBufferSizePoolInKByte) {
544 				DETBufferSizeInKByte[k] = l->minDET_pipe;
545 				l->DETBufferSizePoolInKByte = l->DETBufferSizePoolInKByte - (ForceSingleDPP ? 1 : DPPPerSurface[k]) * l->minDET_pipe;
546 			}
547 
548 			DML_LOG_VERBOSE("DML::%s: k=%u DPPPerSurface = %u\n", __func__, k, DPPPerSurface[k]);
549 			DML_LOG_VERBOSE("DML::%s: k=%u DETSizeOverride = %u\n", __func__, k, display_cfg->plane_descriptors[k].overrides.det_size_override_kb);
550 			DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, DETBufferSizeInKByte[k]);
551 			DML_LOG_VERBOSE("DML::%s: DETBufferSizePoolInKByte = %u\n", __func__, l->DETBufferSizePoolInKByte);
552 		}
553 
554 		if (display_cfg->minimize_det_reallocation) {
555 			MinimizeReallocationSuccess = true;
556 			// To minimize det reallocation, we don't distribute based on each surfaces bandwidth proportional to the global
557 			// but rather distribute DET across streams proportionally based on pixel rate, and only distribute based on
558 			// bandwidth between the planes on the same stream.  This ensures that large scale re-distribution only on a
559 			// stream count and/or pixel rate change, which is must less likely then general bandwidth changes per plane.
560 
561 			// Calculate total pixel rate
562 			for (unsigned int k = 0; k < display_cfg->num_streams; ++k) {
563 				l->TotalPixelRate += display_cfg->stream_descriptors[k].timing.pixel_clock_khz;
564 			}
565 
566 			// Calculate per stream DET budget
567 			for (unsigned int k = 0; k < display_cfg->num_streams; ++k) {
568 				l->DETBudgetPerStream[k] = (unsigned int)((double) display_cfg->stream_descriptors[k].timing.pixel_clock_khz * MaxTotalDETInKByte / l->TotalPixelRate);
569 				l->RemainingDETBudgetPerStream[k] = l->DETBudgetPerStream[k];
570 			}
571 
572 			// Calculate the per stream total bandwidth
573 			for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
574 				l->TotalBandwidthPerStream[display_cfg->plane_descriptors[k].stream_index] += (unsigned int)(ReadBandwidthLuma[k] + ReadBandwidthChroma[k]);
575 
576 				// Check the minimum can be satisfied by budget
577 				if (l->RemainingDETBudgetPerStream[display_cfg->plane_descriptors[k].stream_index] >= DETBufferSizeInKByte[k] * (ForceSingleDPP ? 1 : DPPPerSurface[k])) {
578 					l->RemainingDETBudgetPerStream[display_cfg->plane_descriptors[k].stream_index] -= DETBufferSizeInKByte[k] * (ForceSingleDPP ? 1 : DPPPerSurface[k]);
579 				} else {
580 					MinimizeReallocationSuccess = false;
581 					break;
582 				}
583 			}
584 
585 			if (MinimizeReallocationSuccess) {
586 				// Since a fixed budget per stream is sufficient to satisfy the minimums, just re-distribute each streams
587 				// budget proportionally across its planes
588 				l->ResidualDETAfterRounding = MaxTotalDETInKByte;
589 
590 				for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
591 					l->IdealDETBudget = (unsigned int)(((ReadBandwidthLuma[k] + ReadBandwidthChroma[k]) / l->TotalBandwidthPerStream[display_cfg->plane_descriptors[k].stream_index])
592 							* l->DETBudgetPerStream[display_cfg->plane_descriptors[k].stream_index]);
593 
594 					if (l->IdealDETBudget > DETBufferSizeInKByte[k]) {
595 						l->DeltaDETBudget = l->IdealDETBudget - DETBufferSizeInKByte[k];
596 						if (l->DeltaDETBudget > l->RemainingDETBudgetPerStream[display_cfg->plane_descriptors[k].stream_index])
597 							l->DeltaDETBudget = l->RemainingDETBudgetPerStream[display_cfg->plane_descriptors[k].stream_index];
598 
599 						/* split the additional budgeted DET among the pipes per plane */
600 						DETBufferSizeInKByte[k] += (unsigned int)((double)l->DeltaDETBudget / (ForceSingleDPP ? 1 : DPPPerSurface[k]));
601 						l->RemainingDETBudgetPerStream[display_cfg->plane_descriptors[k].stream_index] -= l->DeltaDETBudget;
602 					}
603 
604 					// Round down to segment size
605 					DETBufferSizeInKByte[k] = (DETBufferSizeInKByte[k] / ConfigReturnBufferSegmentSizeInkByte) * ConfigReturnBufferSegmentSizeInkByte;
606 
607 					l->ResidualDETAfterRounding -= DETBufferSizeInKByte[k] * (ForceSingleDPP ? 1 : DPPPerSurface[k]);
608 				}
609 			}
610 		}
611 
612 		if (!MinimizeReallocationSuccess) {
613 			l->TotalBandwidth = 0;
614 			for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
615 				l->TotalBandwidth = l->TotalBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
616 			}
617 			DML_LOG_VERBOSE("DML::%s: --- Before bandwidth adjustment ---\n", __func__);
618 			for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
619 				DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, DETBufferSizeInKByte[k]);
620 			}
621 			DML_LOG_VERBOSE("DML::%s: --- DET allocation with bandwidth ---\n", __func__);
622 			DML_LOG_VERBOSE("DML::%s: TotalBandwidth = %f\n", __func__, l->TotalBandwidth);
623 			l->BandwidthOfSurfacesNotAssignedDETPiece = l->TotalBandwidth;
624 			for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
625 				if (display_cfg->plane_descriptors[k].overrides.det_size_override_kb > 0 || (((double)(ForceSingleDPP ? 1 : DPPPerSurface[k]) * (double)DETBufferSizeInKByte[k] / (double)MaxTotalDETInKByte) >= ((ReadBandwidthLuma[k] + ReadBandwidthChroma[k]) / l->TotalBandwidth))) {
626 					DETPieceAssignedToThisSurfaceAlready[k] = true;
627 					l->BandwidthOfSurfacesNotAssignedDETPiece = l->BandwidthOfSurfacesNotAssignedDETPiece - ReadBandwidthLuma[k] - ReadBandwidthChroma[k];
628 				} else {
629 					DETPieceAssignedToThisSurfaceAlready[k] = false;
630 				}
631 				DML_LOG_VERBOSE("DML::%s: k=%u DETPieceAssignedToThisSurfaceAlready = %u\n", __func__, k, DETPieceAssignedToThisSurfaceAlready[k]);
632 				DML_LOG_VERBOSE("DML::%s: k=%u BandwidthOfSurfacesNotAssignedDETPiece = %f\n", __func__, k, l->BandwidthOfSurfacesNotAssignedDETPiece);
633 			}
634 
635 			for (unsigned int j = 0; j < NumberOfActiveSurfaces; ++j) {
636 				NextPotentialSurfaceToAssignDETPieceFound = false;
637 				l->NextSurfaceToAssignDETPiece = 0;
638 
639 				for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
640 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, ReadBandwidthLuma[k] = %f\n", __func__, j, k, ReadBandwidthLuma[k]);
641 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, ReadBandwidthChroma[k] = %f\n", __func__, j, k, ReadBandwidthChroma[k]);
642 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, ReadBandwidthLuma[Next] = %f\n", __func__, j, k, ReadBandwidthLuma[l->NextSurfaceToAssignDETPiece]);
643 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, ReadBandwidthChroma[Next] = %f\n", __func__, j, k, ReadBandwidthChroma[l->NextSurfaceToAssignDETPiece]);
644 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, NextSurfaceToAssignDETPiece = %u\n", __func__, j, k, l->NextSurfaceToAssignDETPiece);
645 					if (!DETPieceAssignedToThisSurfaceAlready[k] && (!NextPotentialSurfaceToAssignDETPieceFound ||
646 							ReadBandwidthLuma[k] + ReadBandwidthChroma[k] < ReadBandwidthLuma[l->NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[l->NextSurfaceToAssignDETPiece])) {
647 						l->NextSurfaceToAssignDETPiece = k;
648 						NextPotentialSurfaceToAssignDETPieceFound = true;
649 					}
650 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, DETPieceAssignedToThisSurfaceAlready = %u\n", __func__, j, k, DETPieceAssignedToThisSurfaceAlready[k]);
651 					DML_LOG_VERBOSE("DML::%s: j=%u k=%u, NextPotentialSurfaceToAssignDETPieceFound = %u\n", __func__, j, k, NextPotentialSurfaceToAssignDETPieceFound);
652 				}
653 
654 				if (NextPotentialSurfaceToAssignDETPieceFound) {
655 					l->NextDETBufferPieceInKByte = (unsigned int)(math_min2(
656 							math_round((double)l->DETBufferSizePoolInKByte * (ReadBandwidthLuma[l->NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[l->NextSurfaceToAssignDETPiece]) / l->BandwidthOfSurfacesNotAssignedDETPiece /
657 									((ForceSingleDPP ? 1 : DPPPerSurface[l->NextSurfaceToAssignDETPiece]) * ConfigReturnBufferSegmentSizeInkByte))
658 									* (ForceSingleDPP ? 1 : DPPPerSurface[l->NextSurfaceToAssignDETPiece]) * ConfigReturnBufferSegmentSizeInkByte,
659 									math_floor2((double)l->DETBufferSizePoolInKByte, (ForceSingleDPP ? 1 : DPPPerSurface[l->NextSurfaceToAssignDETPiece]) * ConfigReturnBufferSegmentSizeInkByte)));
660 
661 					DML_LOG_VERBOSE("DML::%s: j=%u, DETBufferSizePoolInKByte = %u\n", __func__, j, l->DETBufferSizePoolInKByte);
662 					DML_LOG_VERBOSE("DML::%s: j=%u, NextSurfaceToAssignDETPiece = %u\n", __func__, j, l->NextSurfaceToAssignDETPiece);
663 					DML_LOG_VERBOSE("DML::%s: j=%u, ReadBandwidthLuma[%u] = %f\n", __func__, j, l->NextSurfaceToAssignDETPiece, ReadBandwidthLuma[l->NextSurfaceToAssignDETPiece]);
664 					DML_LOG_VERBOSE("DML::%s: j=%u, ReadBandwidthChroma[%u] = %f\n", __func__, j, l->NextSurfaceToAssignDETPiece, ReadBandwidthChroma[l->NextSurfaceToAssignDETPiece]);
665 					DML_LOG_VERBOSE("DML::%s: j=%u, BandwidthOfSurfacesNotAssignedDETPiece = %f\n", __func__, j, l->BandwidthOfSurfacesNotAssignedDETPiece);
666 					DML_LOG_VERBOSE("DML::%s: j=%u, NextDETBufferPieceInKByte = %u\n", __func__, j, l->NextDETBufferPieceInKByte);
667 					DML_LOG_VERBOSE("DML::%s: j=%u, DETBufferSizeInKByte[%u] increases from %u ", __func__, j, l->NextSurfaceToAssignDETPiece, DETBufferSizeInKByte[l->NextSurfaceToAssignDETPiece]);
668 
669 					DETBufferSizeInKByte[l->NextSurfaceToAssignDETPiece] = DETBufferSizeInKByte[l->NextSurfaceToAssignDETPiece] + l->NextDETBufferPieceInKByte / (ForceSingleDPP ? 1 : DPPPerSurface[l->NextSurfaceToAssignDETPiece]);
670 					DML_LOG_VERBOSE("to %u\n", DETBufferSizeInKByte[l->NextSurfaceToAssignDETPiece]);
671 
672 					l->DETBufferSizePoolInKByte = l->DETBufferSizePoolInKByte - l->NextDETBufferPieceInKByte;
673 					DETPieceAssignedToThisSurfaceAlready[l->NextSurfaceToAssignDETPiece] = true;
674 					l->BandwidthOfSurfacesNotAssignedDETPiece = l->BandwidthOfSurfacesNotAssignedDETPiece - (ReadBandwidthLuma[l->NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[l->NextSurfaceToAssignDETPiece]);
675 				}
676 			}
677 		}
678 		*CompressedBufferSizeInkByte = MinCompressedBufferSizeInKByte;
679 	}
680 	*CompressedBufferSizeInkByte = *CompressedBufferSizeInkByte * CompressedBufferSegmentSizeInkByte / ConfigReturnBufferSegmentSizeInkByte;
681 
682 	DML_LOG_VERBOSE("DML::%s: --- After bandwidth adjustment ---\n", __func__);
683 	DML_LOG_VERBOSE("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, *CompressedBufferSizeInkByte);
684 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
685 		DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeInKByte = %u (TotalReadBandWidth=%f)\n", __func__, k, DETBufferSizeInKByte[k], ReadBandwidthLuma[k] + ReadBandwidthChroma[k]);
686 	}
687 }
688 
dcn5_calculate_swath_and_det_configuration(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params * p)689 void dcn5_calculate_swath_and_det_configuration(struct dml2_core_internal_scratch *scratch,
690 		struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *p)
691 {
692 	unsigned int MaximumSwathHeightY[DML2_MAX_PLANES] = { 0 };
693 	unsigned int MaximumSwathHeightC[DML2_MAX_PLANES] = { 0 };
694 	unsigned int RoundedUpSwathSizeBytesY[DML2_MAX_PLANES] = { 0 };
695 	unsigned int RoundedUpSwathSizeBytesC[DML2_MAX_PLANES] = { 0 };
696 
697 	unsigned int TotalActiveDPP = 0;
698 	bool NoChromaOrLinear = true;
699 	unsigned int SurfaceDoingUnboundedRequest = 0;
700 	unsigned int DETBufferSizeInKByteForSwathCalculation;
701 
702 	const long TTUFIFODEPTH = 8;
703 	const long MAXIMUMCOMPRESSION = 4;
704 
705 	DML_LOG_VERBOSE("DML::%s: ForceSingleDPP = %u\n", __func__, p->ForceSingleDPP);
706 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
707 		DML_LOG_VERBOSE("DML::%s: DPPPerSurface[%u] = %u\n", __func__, k, p->DPPPerSurface[k]);
708 	}
709 	dcn5_calculate_swath_width(
710 			p->display_cfg,
711 			p->ForceSingleDPP,
712 			p->NumberOfActiveSurfaces,
713 			p->ODMMode,
714 			p->BytePerPixY,
715 			p->BytePerPixC,
716 			p->Read256BytesBlockHeightY,
717 			p->Read256BytesBlockHeightC,
718 			p->Read256BytesBlockWidthY,
719 			p->Read256BytesBlockWidthC,
720 			p->surf_linear128_l,
721 			p->surf_linear128_c,
722 			p->DPPPerSurface,
723 
724 			// Output
725 			p->req_per_swath_ub_l,
726 			p->req_per_swath_ub_c,
727 			p->dummy[0],
728 			p->dummy[1],
729 			p->SwathWidth,
730 			p->SwathWidthChroma,
731 			MaximumSwathHeightY,
732 			MaximumSwathHeightC,
733 			p->swath_width_luma_ub,
734 			p->swath_width_chroma_ub,
735 			p->swath_width_luma_ub_single_dpp,
736 			p->swath_width_chroma_ub_single_dpp);
737 
738 
739 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
740 		p->full_swath_bytes_single_dpp_l[k] = (unsigned int)(p->swath_width_luma_ub_single_dpp[k] * p->BytePerPixDETY[k] * MaximumSwathHeightY[k]);
741 		p->full_swath_bytes_single_dpp_c[k] = (unsigned int)(p->swath_width_chroma_ub_single_dpp[k] * p->BytePerPixDETC[k] * MaximumSwathHeightC[k]);
742 		p->full_swath_bytes_l[k] = (unsigned int)(p->swath_width_luma_ub[k] * p->BytePerPixDETY[k] * MaximumSwathHeightY[k]);
743 		p->full_swath_bytes_c[k] = (unsigned int)(p->swath_width_chroma_ub[k] * p->BytePerPixDETC[k] * MaximumSwathHeightC[k]);
744 		DML_LOG_VERBOSE("DML::%s: k=%u DPPPerSurface = %u\n", __func__, k, p->DPPPerSurface[k]);
745 		DML_LOG_VERBOSE("DML::%s: k=%u swath_width_luma_ub = %u\n", __func__, k, p->swath_width_luma_ub[k]);
746 		DML_LOG_VERBOSE("DML::%s: k=%u BytePerPixDETY = %f\n", __func__, k, p->BytePerPixDETY[k]);
747 		DML_LOG_VERBOSE("DML::%s: k=%u MaximumSwathHeightY = %u\n", __func__, k, MaximumSwathHeightY[k]);
748 		DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_l = %u\n", __func__, k, p->full_swath_bytes_l[k]);
749 		DML_LOG_VERBOSE("DML::%s: k=%u swath_width_chroma_ub = %u\n", __func__, k, p->swath_width_chroma_ub[k]);
750 		DML_LOG_VERBOSE("DML::%s: k=%u BytePerPixDETC = %f\n", __func__, k, p->BytePerPixDETC[k]);
751 		DML_LOG_VERBOSE("DML::%s: k=%u MaximumSwathHeightC = %u\n", __func__, k, MaximumSwathHeightC[k]);
752 		DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_c = %u\n", __func__, k, p->full_swath_bytes_c[k]);
753 		if (p->display_cfg->plane_descriptors[k].pixel_format == dml2_420_10
754 			|| p->display_cfg->plane_descriptors[k].pixel_format == dml2_422_planar_10
755 			|| p->display_cfg->plane_descriptors[k].pixel_format == dml2_422_packed_10) {
756 			p->full_swath_bytes_l[k] = (unsigned int)(math_ceil2((double)p->full_swath_bytes_l[k], 256));
757 			p->full_swath_bytes_c[k] = (unsigned int)(math_ceil2((double)p->full_swath_bytes_c[k], 256));
758 			p->full_swath_bytes_single_dpp_l[k] = (unsigned int)(math_ceil2((double)p->full_swath_bytes_single_dpp_l[k], 256));
759 			p->full_swath_bytes_single_dpp_c[k] = (unsigned int)(math_ceil2((double)p->full_swath_bytes_single_dpp_c[k], 256));
760 		}
761 	}
762 
763 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
764 		TotalActiveDPP = TotalActiveDPP + (p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]);
765 		if (p->DPPPerSurface[k] > 0)
766 			SurfaceDoingUnboundedRequest = k;
767 		if (dml2_core_utils_is_420(p->display_cfg->plane_descriptors[k].pixel_format)
768 				|| dml2_core_utils_is_422_planar(p->display_cfg->plane_descriptors[k].pixel_format)
769 				|| p->display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha
770 				|| dml2_core_utils_is_linear(p->display_cfg->plane_descriptors[k].surface.tiling)) {
771 			NoChromaOrLinear = false;
772 		}
773 	}
774 
775 	*p->UnboundedRequestEnabled = dcn5_is_unbounded_request(p->display_cfg->overrides.hw.force_unbounded_requesting.enable, p->display_cfg->overrides.hw.force_unbounded_requesting.value, TotalActiveDPP, NoChromaOrLinear);
776 
777 	dcn5_calculate_det_buffer_size(
778 			&scratch->CalculateDETBufferSize_locals,
779 			p->display_cfg,
780 			p->ForceSingleDPP,
781 			p->NumberOfActiveSurfaces,
782 			*p->UnboundedRequestEnabled,
783 			p->nomDETInKByte,
784 			p->MaxTotalDETInKByte,
785 			p->ConfigReturnBufferSizeInKByte,
786 			p->MinCompressedBufferSizeInKByte,
787 			p->ConfigReturnBufferSegmentSizeInkByte,
788 			p->CompressedBufferSegmentSizeInkByte,
789 			p->ReadBandwidthLuma,
790 			p->ReadBandwidthChroma,
791 			p->full_swath_bytes_l,
792 			p->full_swath_bytes_c,
793 			p->DPPPerSurface,
794 
795 			// Output
796 			p->DETBufferSizeInKByte, // per hubp pipe
797 			p->CompressedBufferSizeInkByte);
798 
799 	DML_LOG_VERBOSE("DML::%s: TotalActiveDPP = %u\n", __func__, TotalActiveDPP);
800 	DML_LOG_VERBOSE("DML::%s: nomDETInKByte = %u\n", __func__, p->nomDETInKByte);
801 	DML_LOG_VERBOSE("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, p->ConfigReturnBufferSizeInKByte);
802 	DML_LOG_VERBOSE("DML::%s: UnboundedRequestEnabled = %u\n", __func__, *p->UnboundedRequestEnabled);
803 	DML_LOG_VERBOSE("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, *p->CompressedBufferSizeInkByte);
804 
805 	*p->ViewportSizeSupport = true;
806 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
807 
808 		DETBufferSizeInKByteForSwathCalculation = p->DETBufferSizeInKByte[k];
809 		DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeInKByteForSwathCalculation = %u\n", __func__, k, DETBufferSizeInKByteForSwathCalculation);
810 		if (dml2_core_utils_is_linear(p->display_cfg->plane_descriptors[k].surface.tiling)) {
811 			p->SwathHeightY[k] = MaximumSwathHeightY[k];
812 			p->SwathHeightC[k] = MaximumSwathHeightC[k];
813 			RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k];
814 			RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k];
815 
816 			if (p->surf_linear128_l[k])
817 				p->request_size_bytes_luma[k] = 128;
818 			else
819 				p->request_size_bytes_luma[k] = 256;
820 
821 			if (p->surf_linear128_c[k])
822 				p->request_size_bytes_chroma[k] = 128;
823 			else
824 				p->request_size_bytes_chroma[k] = 256;
825 
826 		} else if (p->full_swath_bytes_l[k] + p->full_swath_bytes_c[k] <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
827 			p->SwathHeightY[k] = MaximumSwathHeightY[k];
828 			p->SwathHeightC[k] = MaximumSwathHeightC[k];
829 			RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k];
830 			RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k];
831 			p->request_size_bytes_luma[k] = 256;
832 			p->request_size_bytes_chroma[k] = 256;
833 
834 		} else if (p->full_swath_bytes_l[k] >= 1.5 * p->full_swath_bytes_c[k] && p->full_swath_bytes_l[k] / 2 + p->full_swath_bytes_c[k] <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
835 			p->SwathHeightY[k] = MaximumSwathHeightY[k] / 2;
836 			p->SwathHeightC[k] = MaximumSwathHeightC[k];
837 			RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k] / 2;
838 			RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k];
839 			p->request_size_bytes_luma[k] = dml2_core_utils_get_segment_horizontal_contiguous(p->BytePerPixY[k], p->display_cfg->plane_descriptors[k].surface.tiling)
840 				== dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) ? 64 : 128;
841 			p->request_size_bytes_chroma[k] = 256;
842 
843 		} else if (p->full_swath_bytes_l[k] < 1.5 * p->full_swath_bytes_c[k] && p->full_swath_bytes_l[k] + p->full_swath_bytes_c[k] / 2 <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
844 			p->SwathHeightY[k] = MaximumSwathHeightY[k];
845 			p->SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
846 			RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k];
847 			RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k] / 2;
848 			p->request_size_bytes_luma[k] = 256;
849 			p->request_size_bytes_chroma[k] = dml2_core_utils_get_segment_horizontal_contiguous(p->BytePerPixC[k], p->display_cfg->plane_descriptors[k].surface.tiling)
850 				== dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) ? 64 : 128;
851 
852 		} else {
853 			p->SwathHeightY[k] = MaximumSwathHeightY[k] / 2;
854 			p->SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
855 			RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k] / 2;
856 			RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k] / 2;
857 			p->request_size_bytes_luma[k] = dml2_core_utils_get_segment_horizontal_contiguous(p->BytePerPixY[k], p->display_cfg->plane_descriptors[k].surface.tiling)
858 				== dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) ? 64 : 128;
859 			p->request_size_bytes_chroma[k] = dml2_core_utils_get_segment_horizontal_contiguous(p->BytePerPixC[k], p->display_cfg->plane_descriptors[k].surface.tiling)
860 				== dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) ? 64 : 128;
861 		}
862 
863 		if (p->SwathHeightC[k] == 0)
864 			p->request_size_bytes_chroma[k] = 0;
865 
866 		if ((p->full_swath_bytes_l[k] / 2 + p->full_swath_bytes_c[k] / 2 > DETBufferSizeInKByteForSwathCalculation * 1024 / 2) ||
867 				p->SwathWidth[k] > p->MaximumSwathWidthLuma[k] || (p->SwathHeightC[k] > 0 && p->SwathWidthChroma[k] > p->MaximumSwathWidthChroma[k])) {
868 			*p->ViewportSizeSupport = false;
869 			DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_l=%u\n", __func__, k, p->full_swath_bytes_l[k]);
870 			DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_c=%u\n", __func__, k, p->full_swath_bytes_c[k]);
871 			DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeInKByteForSwathCalculation=%u\n", __func__, k, DETBufferSizeInKByteForSwathCalculation);
872 			DML_LOG_VERBOSE("DML::%s: k=%u SwathWidth=%u\n", __func__, k, p->SwathWidth[k]);
873 			DML_LOG_VERBOSE("DML::%s: k=%u MaximumSwathWidthLuma=%f\n", __func__, k, p->MaximumSwathWidthLuma[k]);
874 			DML_LOG_VERBOSE("DML::%s: k=%u SwathWidthChroma=%d\n", __func__, k, p->SwathWidthChroma[k]);
875 			DML_LOG_VERBOSE("DML::%s: k=%u MaximumSwathWidthChroma=%f\n", __func__, k, p->MaximumSwathWidthChroma[k]);
876 			p->ViewportSizeSupportPerSurface[k] = false;
877 		} else {
878 			p->ViewportSizeSupportPerSurface[k] = true;
879 		}
880 
881 		if (p->SwathHeightC[k] == 0) {
882 			DML_LOG_VERBOSE("DML::%s: k=%u, All DET will be used for plane0\n", __func__, k);
883 			p->DETBufferSizeY[k] = p->DETBufferSizeInKByte[k] * 1024;
884 			p->DETBufferSizeC[k] = 0;
885 		} else if (RoundedUpSwathSizeBytesY[k] <= 1.5 * RoundedUpSwathSizeBytesC[k]) {
886 			DML_LOG_VERBOSE("DML::%s: k=%u, Half DET will be used for plane0, and half for plane1\n", __func__, k);
887 			p->DETBufferSizeY[k] = p->DETBufferSizeInKByte[k] * 1024 / 2;
888 			p->DETBufferSizeC[k] = p->DETBufferSizeInKByte[k] * 1024 / 2;
889 		} else {
890 			DML_LOG_VERBOSE("DML::%s: k=%u, 2/3 DET will be used for plane0, and 1/3 for plane1\n", __func__, k);
891 			p->DETBufferSizeY[k] = (unsigned int)(math_floor2(p->DETBufferSizeInKByte[k] * 1024 * 2 / 3, 1024));
892 			p->DETBufferSizeC[k] = p->DETBufferSizeInKByte[k] * 1024 - p->DETBufferSizeY[k];
893 		}
894 
895 		DML_LOG_VERBOSE("DML::%s: k=%u SwathHeightY = %u\n", __func__, k, p->SwathHeightY[k]);
896 		DML_LOG_VERBOSE("DML::%s: k=%u SwathHeightC = %u\n", __func__, k, p->SwathHeightC[k]);
897 		DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_l = %u\n", __func__, k, p->full_swath_bytes_l[k]);
898 		DML_LOG_VERBOSE("DML::%s: k=%u full_swath_bytes_c = %u\n", __func__, k, p->full_swath_bytes_c[k]);
899 		DML_LOG_VERBOSE("DML::%s: k=%u RoundedUpSwathSizeBytesY = %u\n", __func__, k, RoundedUpSwathSizeBytesY[k]);
900 		DML_LOG_VERBOSE("DML::%s: k=%u RoundedUpSwathSizeBytesC = %u\n", __func__, k, RoundedUpSwathSizeBytesC[k]);
901 		DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, p->DETBufferSizeInKByte[k]);
902 		DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]);
903 		DML_LOG_VERBOSE("DML::%s: k=%u DETBufferSizeC = %u\n", __func__, k, p->DETBufferSizeC[k]);
904 		DML_LOG_VERBOSE("DML::%s: k=%u ViewportSizeSupportPerSurface = %u\n", __func__, k, p->ViewportSizeSupportPerSurface[k]);
905 
906 	}
907 
908 	*p->compbuf_reserved_space_64b = 2 * p->pixel_chunk_size_kbytes * 1024 / 64;
909 	if (*p->UnboundedRequestEnabled) {
910 		*p->compbuf_reserved_space_64b = (unsigned int)math_ceil2(math_max2(*p->compbuf_reserved_space_64b,
911 				(double)(p->rob_buffer_size_kbytes * 1024 / 64) - (double)(RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / (p->mrq_present ? MAXIMUMCOMPRESSION : 1) / 64)), 1.0);
912 		DML_LOG_VERBOSE("DML::%s: RoundedUpSwathSizeBytesY[%d] = %u\n", __func__, SurfaceDoingUnboundedRequest, RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest]);
913 		DML_LOG_VERBOSE("DML::%s: rob_buffer_size_kbytes = %u\n", __func__, p->rob_buffer_size_kbytes);
914 	}
915 	DML_LOG_VERBOSE("DML::%s: compbuf_reserved_space_64b = %u\n", __func__, *p->compbuf_reserved_space_64b);
916 
917 	*p->hw_debug5 = false;
918 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
919 		if (!(p->mrq_present) && (!p->UnboundedRequestEnabled) && (TotalActiveDPP == 1)
920 				&& p->display_cfg->plane_descriptors[k].surface.dcc.enable
921 				&& ((p->rob_buffer_size_kbytes * 1024 * (p->mrq_present ? MAXIMUMCOMPRESSION : 1)
922 						+ *p->CompressedBufferSizeInkByte * MAXIMUMCOMPRESSION * 1024) > TTUFIFODEPTH * (RoundedUpSwathSizeBytesY[k] + RoundedUpSwathSizeBytesC[k])))
923 			*p->hw_debug5 = true;
924 		DML_LOG_VERBOSE("DML::%s: k=%u UnboundedRequestEnabled = %u\n", __func__, k, *p->UnboundedRequestEnabled);
925 		DML_LOG_VERBOSE("DML::%s: k=%u MAXIMUMCOMPRESSION = %lu\n", __func__, k, MAXIMUMCOMPRESSION);
926 		DML_LOG_VERBOSE("DML::%s: k=%u TTUFIFODEPTH = %lu\n", __func__, k, TTUFIFODEPTH);
927 		DML_LOG_VERBOSE("DML::%s: k=%u CompressedBufferSizeInkByte = %u\n", __func__, k, *p->CompressedBufferSizeInkByte);
928 		DML_LOG_VERBOSE("DML::%s: k=%u RoundedUpSwathSizeBytesC = %u\n", __func__, k, RoundedUpSwathSizeBytesC[k]);
929 		DML_LOG_VERBOSE("DML::%s: k=%u hw_debug5 = %u\n", __func__, k, *p->hw_debug5);
930 	}
931 }
932 
dcn5_calculate_host_vm_dynamic_levels(bool GPUVMEnable,bool HostVMEnable,unsigned int HostVMMinPageSize,unsigned int HostVMMaxNonCachedPageTableLevels)933 static unsigned int dcn5_calculate_host_vm_dynamic_levels(
934 		bool GPUVMEnable,
935 		bool HostVMEnable,
936 		unsigned int HostVMMinPageSize,
937 		unsigned int HostVMMaxNonCachedPageTableLevels)
938 {
939 	unsigned int HostVMDynamicLevels = 0;
940 
941 	if (GPUVMEnable && HostVMEnable) {
942 		if (HostVMMinPageSize < 2048)
943 			HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
944 		else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576)
945 			HostVMDynamicLevels = (unsigned int)math_max2(0, (double)HostVMMaxNonCachedPageTableLevels - 1);
946 		else
947 			HostVMDynamicLevels = (unsigned int)math_max2(0, (double)HostVMMaxNonCachedPageTableLevels - 2);
948 	} else {
949 		HostVMDynamicLevels = 0;
950 	}
951 	return HostVMDynamicLevels;
952 }
953 
dcn5_calculate_prefetch_source_lines(double VRatio,unsigned int VTaps,bool UPSPEnabled,unsigned int UPSPVTaps,enum dml2_sample_positioning UPSPSamplePositioning,bool PixelFormatIs420,bool Interlace,bool ProgressiveToInterlaceUnitInOPP,unsigned int SwathHeight,enum dml2_rotation_angle RotationAngle,bool mirrored,bool ViewportStationary,unsigned int SwathWidth,unsigned int ViewportHeight,unsigned int ViewportXStart,unsigned int ViewportYStart,unsigned int * VInitPreFill,unsigned int * MaxNumSwath)954 static unsigned int dcn5_calculate_prefetch_source_lines(
955 		double VRatio,
956 		unsigned int VTaps,
957 		bool UPSPEnabled,
958 		unsigned int UPSPVTaps,
959 		enum dml2_sample_positioning UPSPSamplePositioning,
960 		bool PixelFormatIs420,
961 		bool Interlace,
962 		bool ProgressiveToInterlaceUnitInOPP,
963 		unsigned int SwathHeight,
964 		enum dml2_rotation_angle RotationAngle,
965 		bool mirrored,
966 		bool ViewportStationary,
967 		unsigned int SwathWidth,
968 		unsigned int ViewportHeight,
969 		unsigned int ViewportXStart,
970 		unsigned int ViewportYStart,
971 
972 		// Output
973 		unsigned int *VInitPreFill,
974 		unsigned int *MaxNumSwath)
975 {
976 
977 	unsigned int vp_start_rot = 0;
978 	unsigned int sw0_tmp = 0;
979 	unsigned int MaxPartialSwath = 0;
980 	unsigned int VInitPreFillUPSP = 0;
981 	unsigned int VInitPreFillDSCL = 0;
982 	const float UPSPVratio = 0.5;
983 	double numLines = 0;
984 
985 	DML_LOG_VERBOSE("DML::%s: VRatio = %f\n", __func__, VRatio);
986 	DML_LOG_VERBOSE("DML::%s: VTaps = %u\n", __func__, VTaps);
987 	DML_LOG_VERBOSE("DML::%s: ViewportXStart = %u\n", __func__, ViewportXStart);
988 	DML_LOG_VERBOSE("DML::%s: ViewportYStart = %u\n", __func__, ViewportYStart);
989 	DML_LOG_VERBOSE("DML::%s: ViewportStationary = %u\n", __func__, ViewportStationary);
990 	DML_LOG_VERBOSE("DML::%s: SwathHeight = %u\n", __func__, SwathHeight);
991 
992 	if (UPSPEnabled && PixelFormatIs420) {
993 		//VRatio = (DSCL Vratio)/2
994 		VInitPreFillUPSP = (unsigned int)(math_floor2((UPSPVTaps + UPSPVratio + 1) / 2.0 + ((UPSPSamplePositioning == dml2_cosited) ? 0.25 : 0), 1));
995 		VInitPreFillDSCL = (unsigned int)(math_floor2((2 * VRatio + (double)VTaps + 1) / 2.0, 1)); // DSCL vratio is 2 * Vratio, so the total Vratio does not change
996 		*VInitPreFill 	 = (unsigned int)(math_floor2(VInitPreFillUPSP + (VInitPreFillDSCL - 1) * UPSPVratio, 1));
997 	} else if (ProgressiveToInterlaceUnitInOPP) {
998 		*VInitPreFill = (unsigned int)(math_floor2((VRatio + (double)VTaps + 1) / 2.0, 1));
999 	} else {
1000 		*VInitPreFill = (unsigned int)(math_floor2((VRatio + (double)VTaps + 1 + (Interlace ? 1 : 0) * 0.5 * VRatio) / 2.0, 1));
1001 	}
1002 
1003 	if (ViewportStationary) {
1004 		if (RotationAngle == dml2_rotation_180) {
1005 			vp_start_rot = SwathHeight - (((unsigned int)(ViewportYStart + ViewportHeight - 1) % SwathHeight) + 1);
1006 		} else if ((RotationAngle == dml2_rotation_270 && !mirrored) || (RotationAngle == dml2_rotation_90 && mirrored)) {
1007 			vp_start_rot = ViewportXStart;
1008 		} else if ((RotationAngle == dml2_rotation_90 && !mirrored) || (RotationAngle == dml2_rotation_270 && mirrored)) {
1009 			vp_start_rot = SwathHeight - (((unsigned int)(ViewportYStart + SwathWidth - 1) % SwathHeight) + 1);
1010 		} else {
1011 			vp_start_rot = ViewportYStart;
1012 		}
1013 		sw0_tmp = SwathHeight - (vp_start_rot % SwathHeight);
1014 		if (sw0_tmp < *VInitPreFill) {
1015 			*MaxNumSwath = (unsigned int)(math_ceil2((*VInitPreFill - sw0_tmp) / (double)SwathHeight, 1) + 1);
1016 		} else {
1017 			*MaxNumSwath = 1;
1018 		}
1019 		MaxPartialSwath = (unsigned int)(math_max2(1, (unsigned int)(vp_start_rot + *VInitPreFill - 1) % SwathHeight));
1020 	} else {
1021 		*MaxNumSwath = (unsigned int)(math_ceil2((*VInitPreFill - 1.0) / (double)SwathHeight, 1) + 1);
1022 		if (*VInitPreFill > 1) {
1023 			MaxPartialSwath = (unsigned int)(math_max2(1, (unsigned int)(*VInitPreFill - 2) % SwathHeight));
1024 		} else {
1025 			MaxPartialSwath = (unsigned int)(math_max2(1, (unsigned int)(*VInitPreFill + SwathHeight - 2) % SwathHeight));
1026 		}
1027 	}
1028 	numLines = *MaxNumSwath * SwathHeight + MaxPartialSwath;
1029 
1030 	DML_LOG_VERBOSE("DML::%s: vp_start_rot = %u\n", __func__, vp_start_rot);
1031 	DML_LOG_VERBOSE("DML::%s: VInitPreFill = %u\n", __func__, *VInitPreFill);
1032 	DML_LOG_VERBOSE("DML::%s: MaxPartialSwath = %u\n", __func__, MaxPartialSwath);
1033 	DML_LOG_VERBOSE("DML::%s: MaxNumSwath = %u\n", __func__, *MaxNumSwath);
1034 	DML_LOG_VERBOSE("DML::%s: Prefetch source lines = %3.2f\n", __func__, numLines);
1035 	return (unsigned int)(numLines);
1036 
1037 }
1038 
dcn5_calculate_row_bandwidth(bool GPUVMEnable,bool use_one_row_for_frame,enum dml2_source_format_class SourcePixelFormat,double VRatio,double VRatioChroma,bool DCCEnable,double LineTime,unsigned int PixelPTEBytesPerRowLuma,unsigned int PixelPTEBytesPerRowChroma,unsigned int dpte_row_height_luma,unsigned int dpte_row_height_chroma,bool mrq_present,unsigned int meta_row_bytes_per_row_ub_l,unsigned int meta_row_bytes_per_row_ub_c,unsigned int meta_row_height_luma,unsigned int meta_row_height_chroma,double * dpte_row_bw,double * meta_row_bw)1039 static void dcn5_calculate_row_bandwidth(
1040 		bool GPUVMEnable,
1041 		bool use_one_row_for_frame,
1042 		enum dml2_source_format_class SourcePixelFormat,
1043 		double VRatio,
1044 		double VRatioChroma,
1045 		bool DCCEnable,
1046 		double LineTime,
1047 		unsigned int PixelPTEBytesPerRowLuma,
1048 		unsigned int PixelPTEBytesPerRowChroma,
1049 		unsigned int dpte_row_height_luma,
1050 		unsigned int dpte_row_height_chroma,
1051 
1052 		bool mrq_present,
1053 		unsigned int meta_row_bytes_per_row_ub_l,
1054 		unsigned int meta_row_bytes_per_row_ub_c,
1055 		unsigned int meta_row_height_luma,
1056 		unsigned int meta_row_height_chroma,
1057 
1058 		// Output
1059 		double *dpte_row_bw,
1060 		double *meta_row_bw)
1061 {
1062 	if (!DCCEnable || !mrq_present) {
1063 		*meta_row_bw = 0;
1064 	} else if (dml2_core_utils_is_420(SourcePixelFormat) || dml2_core_utils_is_422_planar(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha) {
1065 		*meta_row_bw = VRatio * meta_row_bytes_per_row_ub_l / (meta_row_height_luma * LineTime)
1066 								+ VRatioChroma * meta_row_bytes_per_row_ub_c / (meta_row_height_chroma * LineTime);
1067 	} else {
1068 		*meta_row_bw = VRatio * meta_row_bytes_per_row_ub_l / (meta_row_height_luma * LineTime);
1069 	}
1070 
1071 	if (GPUVMEnable != true || use_one_row_for_frame) {
1072 		*dpte_row_bw = 0;
1073 	} else if (dml2_core_utils_is_420(SourcePixelFormat) || dml2_core_utils_is_422_planar(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha) {
1074 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
1075 							+ VRatioChroma * PixelPTEBytesPerRowChroma / (dpte_row_height_chroma * LineTime);
1076 	} else {
1077 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
1078 	}
1079 }
1080 
dcn5_calculate_vm_and_row_bytes(struct dml2_core_shared_calculate_vm_and_row_bytes_params * p)1081 unsigned int dcn5_calculate_vm_and_row_bytes(struct dml2_core_shared_calculate_vm_and_row_bytes_params *p)
1082 {
1083 	unsigned int extra_dpde_bytes;
1084 	unsigned int extra_mpde_bytes;
1085 	unsigned int MacroTileSizeBytes;
1086 	unsigned int vp_height_dpte_ub;
1087 
1088 	unsigned int meta_surface_bytes;
1089 	unsigned int vm_bytes;
1090 	unsigned int vp_height_meta_ub;
1091 	unsigned int PixelPTEReqWidth_linear = 0; // VBA_DELTA. VBA doesn't calculate this
1092 
1093 	*p->MetaRequestHeight = 8 * p->BlockHeight256Bytes;
1094 	*p->MetaRequestWidth = 8 * p->BlockWidth256Bytes;
1095 	if (dml2_core_utils_is_linear(p->SurfaceTiling)) {
1096 		*p->meta_row_height = 32;
1097 		*p->meta_row_width = (unsigned int)(math_floor2(p->ViewportXStart + p->SwathWidth + *p->MetaRequestWidth - 1, *p->MetaRequestWidth) - math_floor2(p->ViewportXStart, *p->MetaRequestWidth));
1098 		*p->meta_row_bytes = (unsigned int)(*p->meta_row_width * *p->MetaRequestHeight * p->BytePerPixel / 256.0); // FIXME_DCN4SW missing in old code but no dcc for linear anyways?
1099 	} else if (!dml2_core_utils_is_vertical_rotation(p->RotationAngle)) {
1100 		*p->meta_row_height = *p->MetaRequestHeight;
1101 		if (p->ViewportStationary && p->NumberOfDPPs == 1) {
1102 			*p->meta_row_width = (unsigned int)(math_floor2(p->ViewportXStart + p->SwathWidth + *p->MetaRequestWidth - 1, *p->MetaRequestWidth) - math_floor2(p->ViewportXStart, *p->MetaRequestWidth));
1103 		} else {
1104 			*p->meta_row_width = (unsigned int)(math_ceil2(p->SwathWidth - 1, *p->MetaRequestWidth) + *p->MetaRequestWidth);
1105 		}
1106 		*p->meta_row_bytes = (unsigned int)(*p->meta_row_width * *p->MetaRequestHeight * p->BytePerPixel / 256.0);
1107 	} else {
1108 		*p->meta_row_height = *p->MetaRequestWidth;
1109 		if (p->ViewportStationary && p->NumberOfDPPs == 1) {
1110 			*p->meta_row_width = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + *p->MetaRequestHeight - 1, *p->MetaRequestHeight) - math_floor2(p->ViewportYStart, *p->MetaRequestHeight));
1111 		} else {
1112 			*p->meta_row_width = (unsigned int)(math_ceil2(p->SwathWidth - 1, *p->MetaRequestHeight) + *p->MetaRequestHeight);
1113 		}
1114 		*p->meta_row_bytes = (unsigned int)(*p->meta_row_width * *p->MetaRequestWidth * p->BytePerPixel / 256.0);
1115 	}
1116 
1117 	if (p->ViewportStationary && p->is_phantom && (p->NumberOfDPPs == 1 || !dml2_core_utils_is_vertical_rotation(p->RotationAngle))) {
1118 		vp_height_meta_ub = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + 64 * p->BlockHeight256Bytes - 1, 64 * p->BlockHeight256Bytes) - math_floor2(p->ViewportYStart, 64 * p->BlockHeight256Bytes));
1119 	} else if (!dml2_core_utils_is_vertical_rotation(p->RotationAngle)) {
1120 		vp_height_meta_ub = (unsigned int)(math_ceil2(p->ViewportHeight - 1, 64 * p->BlockHeight256Bytes) + 64 * p->BlockHeight256Bytes);
1121 	} else {
1122 		vp_height_meta_ub = (unsigned int)(math_ceil2(p->SwathWidth - 1, 64 * p->BlockHeight256Bytes) + 64 * p->BlockHeight256Bytes);
1123 	}
1124 
1125 	meta_surface_bytes = (unsigned int)(p->DCCMetaPitch * vp_height_meta_ub * p->BytePerPixel / 256.0);
1126 	DML_LOG_VERBOSE("DML::%s: DCCMetaPitch = %u\n", __func__, p->DCCMetaPitch);
1127 	DML_LOG_VERBOSE("DML::%s: meta_surface_bytes = %u\n", __func__, meta_surface_bytes);
1128 	if (p->GPUVMEnable == true) {
1129 		double meta_vmpg_bytes = 4.0 * 1024.0;
1130 		*p->meta_pte_bytes_per_frame_ub = (unsigned int)((math_ceil2((double) (meta_surface_bytes - meta_vmpg_bytes) / (8 * meta_vmpg_bytes), 1) + 1) * 64);
1131 		extra_mpde_bytes = 128 * (p->GPUVMMaxPageTableLevels - 1);
1132 	} else {
1133 		*p->meta_pte_bytes_per_frame_ub = 0;
1134 		extra_mpde_bytes = 0;
1135 	}
1136 
1137 	if (!p->DCCEnable || !p->mrq_present) {
1138 		*p->meta_pte_bytes_per_frame_ub = 0;
1139 		extra_mpde_bytes = 0;
1140 		*p->meta_row_bytes = 0;
1141 	}
1142 
1143 	if (!p->GPUVMEnable) {
1144 		*p->PixelPTEBytesPerRow = 0;
1145 		*p->PixelPTEBytesPerRowStorage = 0;
1146 		*p->dpte_row_width_ub = 0;
1147 		*p->dpte_row_height = 0;
1148 		*p->dpte_row_height_linear = 0;
1149 		*p->PixelPTEBytesPerRow_one_row_per_frame = 0;
1150 		*p->dpte_row_width_ub_one_row_per_frame = 0;
1151 		*p->dpte_row_height_one_row_per_frame = 0;
1152 		*p->vmpg_width = 0;
1153 		*p->vmpg_height = 0;
1154 		*p->PixelPTEReqWidth = 0;
1155 		*p->PixelPTEReqHeight = 0;
1156 		*p->PTERequestSize = 0;
1157 		*p->dpde0_bytes_per_frame_ub = 0;
1158 		return 0;
1159 	}
1160 
1161 	MacroTileSizeBytes = p->MacroTileWidth * p->BytePerPixel * p->MacroTileHeight;
1162 
1163 	if (p->ViewportStationary && p->is_phantom && (p->NumberOfDPPs == 1 || !dml2_core_utils_is_vertical_rotation(p->RotationAngle))) {
1164 		vp_height_dpte_ub = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + p->MacroTileHeight - 1, p->MacroTileHeight) - math_floor2(p->ViewportYStart, p->MacroTileHeight));
1165 	} else if (!dml2_core_utils_is_vertical_rotation(p->RotationAngle)) {
1166 		vp_height_dpte_ub = (unsigned int)(math_ceil2((double)p->ViewportHeight - 1, p->MacroTileHeight) + p->MacroTileHeight);
1167 	} else {
1168 		vp_height_dpte_ub = (unsigned int)(math_ceil2((double)p->SwathWidth - 1, p->MacroTileHeight) + p->MacroTileHeight);
1169 	}
1170 
1171 	unsigned int pixel_per_element = dml2_core_utils_is_422_packed(p->SourcePixelFormat) ? 2 : 1;
1172 	if (p->GPUVMEnable == true && p->GPUVMMaxPageTableLevels > 1) {
1173 		*p->dpde0_bytes_per_frame_ub = (unsigned int)(64 * (math_ceil2((double)(p->Pitch * pixel_per_element * vp_height_dpte_ub * p->BytePerPixel - MacroTileSizeBytes) / (double)(8 * 2097152), 1) + 1));
1174 		extra_dpde_bytes = 128 * (p->GPUVMMaxPageTableLevels - 2);
1175 	} else {
1176 		*p->dpde0_bytes_per_frame_ub = 0;
1177 		extra_dpde_bytes = 0;
1178 	}
1179 
1180 	vm_bytes = *p->meta_pte_bytes_per_frame_ub + extra_mpde_bytes + *p->dpde0_bytes_per_frame_ub + extra_dpde_bytes;
1181 
1182 	DML_LOG_VERBOSE("DML::%s: DCCEnable = %u\n", __func__, p->DCCEnable);
1183 	DML_LOG_VERBOSE("DML::%s: GPUVMEnable = %u\n", __func__, p->GPUVMEnable);
1184 	DML_LOG_VERBOSE("DML::%s: SwModeLinear = %u\n", __func__, p->SurfaceTiling == dml2_sw_linear);
1185 	DML_LOG_VERBOSE("DML::%s: BytePerPixel = %u\n", __func__, p->BytePerPixel);
1186 	DML_LOG_VERBOSE("DML::%s: GPUVMMaxPageTableLevels = %u\n", __func__, p->GPUVMMaxPageTableLevels);
1187 	DML_LOG_VERBOSE("DML::%s: BlockHeight256Bytes = %u\n", __func__, p->BlockHeight256Bytes);
1188 	DML_LOG_VERBOSE("DML::%s: BlockWidth256Bytes = %u\n", __func__, p->BlockWidth256Bytes);
1189 	DML_LOG_VERBOSE("DML::%s: MacroTileHeight = %u\n", __func__, p->MacroTileHeight);
1190 	DML_LOG_VERBOSE("DML::%s: MacroTileWidth = %u\n", __func__, p->MacroTileWidth);
1191 	DML_LOG_VERBOSE("DML::%s: meta_pte_bytes_per_frame_ub = %u\n", __func__, *p->meta_pte_bytes_per_frame_ub);
1192 	DML_LOG_VERBOSE("DML::%s: dpde0_bytes_per_frame_ub = %u\n", __func__, *p->dpde0_bytes_per_frame_ub);
1193 	DML_LOG_VERBOSE("DML::%s: extra_mpde_bytes = %u\n", __func__, extra_mpde_bytes);
1194 	DML_LOG_VERBOSE("DML::%s: extra_dpde_bytes = %u\n", __func__, extra_dpde_bytes);
1195 	DML_LOG_VERBOSE("DML::%s: vm_bytes = %u\n", __func__, vm_bytes);
1196 	DML_LOG_VERBOSE("DML::%s: ViewportHeight = %u\n", __func__, p->ViewportHeight);
1197 	DML_LOG_VERBOSE("DML::%s: SwathWidth = %u\n", __func__, p->SwathWidth);
1198 	DML_LOG_VERBOSE("DML::%s: vp_height_dpte_ub = %u\n", __func__, vp_height_dpte_ub);
1199 
1200 	if (dml2_core_utils_is_linear(p->SurfaceTiling)) {
1201 		*p->PixelPTEReqHeight = 1;
1202 		*p->PixelPTEReqWidth = p->GPUVMMinPageSizeKBytes * 1024 * 8 / p->BytePerPixel;
1203 		PixelPTEReqWidth_linear = p->GPUVMMinPageSizeKBytes * 1024 * 8 / p->BytePerPixel;
1204 		*p->PTERequestSize = 64;
1205 
1206 		*p->vmpg_height = 1;
1207 		*p->vmpg_width = p->GPUVMMinPageSizeKBytes * 1024 / p->BytePerPixel;
1208 	} else if (p->GPUVMMinPageSizeKBytes * 1024 >= dml2_core_utils_get_tile_block_size_bytes(p->SurfaceTiling, p->BytePerPixel)) { // 1 64B 8x1 PTE
1209 		*p->PixelPTEReqHeight = p->MacroTileHeight;
1210 		*p->PixelPTEReqWidth = 8 * 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel);
1211 		*p->PTERequestSize = 64;
1212 
1213 		*p->vmpg_height = p->MacroTileHeight;
1214 		*p->vmpg_width = 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel);
1215 
1216 	} else if (p->GPUVMMinPageSizeKBytes == 4 && dml2_core_utils_get_tile_block_size_bytes(p->SurfaceTiling, p->BytePerPixel) == 65536) { // 2 64B PTE requests to get 16 PTEs to cover the 64K tile
1217 		// one 64KB tile, is 16x16x256B req
1218 		*p->PixelPTEReqHeight = 16 * p->BlockHeight256Bytes;
1219 		*p->PixelPTEReqWidth = 16 * p->BlockWidth256Bytes;
1220 		*p->PTERequestSize = 128;
1221 
1222 		*p->vmpg_height = *p->PixelPTEReqHeight;
1223 		*p->vmpg_width = *p->PixelPTEReqWidth;
1224 	} else {
1225 		// default for rest of calculation to go through, when vm is disable, the calulated pte related values shouldnt be used anyways
1226 		*p->PixelPTEReqHeight = p->MacroTileHeight;
1227 		*p->PixelPTEReqWidth = 8 * 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel);
1228 		*p->PTERequestSize = 64;
1229 
1230 		*p->vmpg_height = p->MacroTileHeight;
1231 		*p->vmpg_width = 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel);
1232 
1233 		if (p->GPUVMEnable == true) {
1234 			DML_LOG_VERBOSE("DML::%s: GPUVMMinPageSizeKBytes=%u and sw_mode=%u (tile_size=%d) not supported!\n",
1235 					__func__, p->GPUVMMinPageSizeKBytes, p->SurfaceTiling, dml2_core_utils_get_tile_block_size_bytes(p->SurfaceTiling, p->BytePerPixel));
1236 			DML_ASSERT(0);
1237 		}
1238 	}
1239 
1240 	DML_LOG_VERBOSE("DML::%s: GPUVMMinPageSizeKBytes = %u\n", __func__, p->GPUVMMinPageSizeKBytes);
1241 	DML_LOG_VERBOSE("DML::%s: PixelPTEReqHeight = %u\n", __func__, *p->PixelPTEReqHeight);
1242 	DML_LOG_VERBOSE("DML::%s: PixelPTEReqWidth = %u\n", __func__, *p->PixelPTEReqWidth);
1243 	DML_LOG_VERBOSE("DML::%s: PixelPTEReqWidth_linear = %u\n", __func__, PixelPTEReqWidth_linear);
1244 	DML_LOG_VERBOSE("DML::%s: PTERequestSize = %u\n", __func__, *p->PTERequestSize);
1245 	DML_LOG_VERBOSE("DML::%s: Pitch = %u\n", __func__, p->Pitch);
1246 	DML_LOG_VERBOSE("DML::%s: vmpg_width = %u\n", __func__, *p->vmpg_width);
1247 	DML_LOG_VERBOSE("DML::%s: vmpg_height = %u\n", __func__, *p->vmpg_height);
1248 
1249 	*p->dpte_row_height_one_row_per_frame = vp_height_dpte_ub;
1250 	*p->dpte_row_width_ub_one_row_per_frame = (unsigned int)((math_ceil2(((double)p->Pitch * pixel_per_element * (double)*p->dpte_row_height_one_row_per_frame / (double)*p->PixelPTEReqHeight - 1) / (double)*p->PixelPTEReqWidth, 1) + 1) * (double)*p->PixelPTEReqWidth);
1251 	*p->PixelPTEBytesPerRow_one_row_per_frame = (unsigned int)((double)*p->dpte_row_width_ub_one_row_per_frame / (double)*p->PixelPTEReqWidth * *p->PTERequestSize);
1252 	*p->dpte_row_height_linear = 0;
1253 
1254 	if (dml2_core_utils_is_linear(p->SurfaceTiling)) {
1255 		*p->dpte_row_height = (unsigned int)(math_min2(128, (double)(1ULL << (unsigned int)math_floor2(math_log((float)(p->PTEBufferSizeInRequests * *p->PixelPTEReqWidth / pixel_per_element / p->Pitch), 2.0), 1))));
1256 		*p->dpte_row_width_ub = (unsigned int)(math_ceil2(((double)p->Pitch * pixel_per_element * (double)*p->dpte_row_height - 1), (double)*p->PixelPTEReqWidth) + *p->PixelPTEReqWidth);
1257 		*p->PixelPTEBytesPerRow = (unsigned int)((double)*p->dpte_row_width_ub / (double)*p->PixelPTEReqWidth * *p->PTERequestSize);
1258 
1259 		// VBA_DELTA, VBA doesn't have programming value for pte row height linear.
1260 		*p->dpte_row_height_linear = (unsigned int)1 << (unsigned int)math_floor2(math_log((float)(p->PTEBufferSizeInRequests * PixelPTEReqWidth_linear / pixel_per_element / p->Pitch), 2.0), 1);
1261 		if (*p->dpte_row_height_linear > 128)
1262 			*p->dpte_row_height_linear = 128;
1263 
1264 		DML_LOG_VERBOSE("DML::%s: dpte_row_width_ub = %u (linear)\n", __func__, *p->dpte_row_width_ub);
1265 
1266 	} else if (!dml2_core_utils_is_vertical_rotation(p->RotationAngle)) {
1267 		*p->dpte_row_height = *p->PixelPTEReqHeight;
1268 
1269 		if (p->GPUVMMinPageSizeKBytes > 64) {
1270 			*p->dpte_row_width_ub = (unsigned int)((math_ceil2(((double)p->Pitch * pixel_per_element * (double)*p->dpte_row_height / (double)*p->PixelPTEReqHeight - 1) / (double)*p->PixelPTEReqWidth, 1) + 1) * *p->PixelPTEReqWidth);
1271 		} else if (p->ViewportStationary && (p->NumberOfDPPs == 1)) {
1272 			*p->dpte_row_width_ub = (unsigned int)(math_floor2(p->ViewportXStart + p->SwathWidth + *p->PixelPTEReqWidth - 1, *p->PixelPTEReqWidth) - math_floor2(p->ViewportXStart, *p->PixelPTEReqWidth));
1273 		} else {
1274 			*p->dpte_row_width_ub = (unsigned int)((math_ceil2((double)(p->SwathWidth - 1) / (double)*p->PixelPTEReqWidth, 1) + 1.0) * *p->PixelPTEReqWidth);
1275 		}
1276 		DML_LOG_VERBOSE("DML::%s: dpte_row_width_ub = %u (tiled horz)\n", __func__, *p->dpte_row_width_ub);
1277 		*p->PixelPTEBytesPerRow = *p->dpte_row_width_ub / *p->PixelPTEReqWidth * *p->PTERequestSize;
1278 	} else {
1279 		*p->dpte_row_height = (unsigned int)(math_min2(*p->PixelPTEReqWidth, p->MacroTileWidth));
1280 
1281 		if (p->ViewportStationary && (p->NumberOfDPPs == 1)) {
1282 			*p->dpte_row_width_ub = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + *p->PixelPTEReqHeight - 1, *p->PixelPTEReqHeight) - math_floor2(p->ViewportYStart, *p->PixelPTEReqHeight));
1283 		} else {
1284 			*p->dpte_row_width_ub = (unsigned int)((math_ceil2((double)(p->SwathWidth - 1) / (double)*p->PixelPTEReqHeight, 1) + 1) * *p->PixelPTEReqHeight);
1285 		}
1286 
1287 		*p->PixelPTEBytesPerRow = (unsigned int)((double)*p->dpte_row_width_ub / (double)*p->PixelPTEReqHeight * *p->PTERequestSize);
1288 		DML_LOG_VERBOSE("DML::%s: dpte_row_width_ub = %u (tiled vert)\n", __func__, *p->dpte_row_width_ub);
1289 	}
1290 
1291 	if (p->GPUVMEnable != true) {
1292 		*p->PixelPTEBytesPerRow = 0;
1293 		*p->PixelPTEBytesPerRow_one_row_per_frame = 0;
1294 	}
1295 
1296 	*p->PixelPTEBytesPerRowStorage = *p->PixelPTEBytesPerRow;
1297 
1298 	DML_LOG_VERBOSE("DML::%s: GPUVMMinPageSizeKBytes = %u\n", __func__, p->GPUVMMinPageSizeKBytes);
1299 	DML_LOG_VERBOSE("DML::%s: GPUVMEnable = %u\n", __func__, p->GPUVMEnable);
1300 	DML_LOG_VERBOSE("DML::%s: meta_row_height = %u\n", __func__, *p->meta_row_height);
1301 	DML_LOG_VERBOSE("DML::%s: dpte_row_height = %u\n", __func__, *p->dpte_row_height);
1302 	DML_LOG_VERBOSE("DML::%s: dpte_row_height_linear = %u\n", __func__, *p->dpte_row_height_linear);
1303 	DML_LOG_VERBOSE("DML::%s: dpte_row_width_ub = %u\n", __func__, *p->dpte_row_width_ub);
1304 	DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, *p->PixelPTEBytesPerRow);
1305 	DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRowStorage = %u\n", __func__, *p->PixelPTEBytesPerRowStorage);
1306 	DML_LOG_VERBOSE("DML::%s: PTEBufferSizeInRequests = %u\n", __func__, p->PTEBufferSizeInRequests);
1307 	DML_LOG_VERBOSE("DML::%s: dpte_row_height_one_row_per_frame = %u\n", __func__, *p->dpte_row_height_one_row_per_frame);
1308 	DML_LOG_VERBOSE("DML::%s: dpte_row_width_ub_one_row_per_frame = %u\n", __func__, *p->dpte_row_width_ub_one_row_per_frame);
1309 	DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRow_one_row_per_frame = %u\n", __func__, *p->PixelPTEBytesPerRow_one_row_per_frame);
1310 
1311 	return vm_bytes;
1312 }
1313 
dcn5_calculate_vm_row_and_swath(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_CalculateVMRowAndSwath_params * p)1314 void dcn5_calculate_vm_row_and_swath(struct dml2_core_internal_scratch *scratch,
1315 		struct dml2_core_calcs_CalculateVMRowAndSwath_params *p)
1316 {
1317 	struct dml2_core_calcs_CalculateVMRowAndSwath_locals *s = &scratch->CalculateVMRowAndSwath_locals;
1318 
1319 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
1320 		s->HostVMDynamicLevels = dcn5_calculate_host_vm_dynamic_levels(p->display_cfg->gpuvm_enable, p->display_cfg->hostvm_enable, p->display_cfg->plane_descriptors[k].overrides.hostvm_min_page_size_kbytes,
1321 			p->display_cfg->hostvm_max_non_cached_page_table_levels);
1322 
1323 		if (p->display_cfg->gpuvm_enable == true) {
1324 			p->vm_group_bytes[k] = 512;
1325 			p->dpte_group_bytes[k] = 512;
1326 		} else {
1327 			p->vm_group_bytes[k] = 0;
1328 			p->dpte_group_bytes[k] = 0;
1329 		}
1330 
1331 		if (dml2_core_utils_is_420(p->myPipe[k].SourcePixelFormat) || dml2_core_utils_is_422_planar(p->myPipe[k].SourcePixelFormat) || p->myPipe[k].SourcePixelFormat == dml2_rgbe_alpha) {
1332 			if ((p->myPipe[k].SourcePixelFormat == dml2_420_10 || p->myPipe[k].SourcePixelFormat == dml2_420_12
1333 				|| p->myPipe[k].SourcePixelFormat == dml2_422_planar_10 || p->myPipe[k].SourcePixelFormat == dml2_422_planar_12)
1334 				&& !dml2_core_utils_is_vertical_rotation(p->myPipe[k].RotationAngle)) {
1335 				s->PTEBufferSizeInRequestsForLuma[k] = (p->PTEBufferSizeInRequestsLuma + p->PTEBufferSizeInRequestsChroma) / 2;
1336 				s->PTEBufferSizeInRequestsForChroma[k] = s->PTEBufferSizeInRequestsForLuma[k];
1337 			} else {
1338 				s->PTEBufferSizeInRequestsForLuma[k] = p->PTEBufferSizeInRequestsLuma;
1339 				s->PTEBufferSizeInRequestsForChroma[k] = p->PTEBufferSizeInRequestsChroma;
1340 			}
1341 
1342 			scratch->calculate_vm_and_row_bytes_params.ViewportStationary = p->myPipe[k].ViewportStationary;
1343 			scratch->calculate_vm_and_row_bytes_params.DCCEnable = p->myPipe[k].DCCEnable;
1344 			scratch->calculate_vm_and_row_bytes_params.NumberOfDPPs = p->myPipe[k].DPPPerSurface;
1345 			scratch->calculate_vm_and_row_bytes_params.BlockHeight256Bytes = p->myPipe[k].BlockHeight256BytesC;
1346 			scratch->calculate_vm_and_row_bytes_params.BlockWidth256Bytes = p->myPipe[k].BlockWidth256BytesC;
1347 			scratch->calculate_vm_and_row_bytes_params.SourcePixelFormat = p->myPipe[k].SourcePixelFormat;
1348 			scratch->calculate_vm_and_row_bytes_params.SurfaceTiling = p->myPipe[k].SurfaceTiling;
1349 			scratch->calculate_vm_and_row_bytes_params.BytePerPixel = p->myPipe[k].BytePerPixelC;
1350 			scratch->calculate_vm_and_row_bytes_params.RotationAngle = p->myPipe[k].RotationAngle;
1351 			scratch->calculate_vm_and_row_bytes_params.SwathWidth = p->SwathWidthC[k];
1352 			scratch->calculate_vm_and_row_bytes_params.ViewportHeight = p->myPipe[k].ViewportHeightC;
1353 			scratch->calculate_vm_and_row_bytes_params.ViewportXStart = p->myPipe[k].ViewportXStartC;
1354 			scratch->calculate_vm_and_row_bytes_params.ViewportYStart = p->myPipe[k].ViewportYStartC;
1355 			scratch->calculate_vm_and_row_bytes_params.GPUVMEnable = p->display_cfg->gpuvm_enable;
1356 			scratch->calculate_vm_and_row_bytes_params.GPUVMMaxPageTableLevels = p->display_cfg->gpuvm_max_page_table_levels;
1357 			scratch->calculate_vm_and_row_bytes_params.GPUVMMinPageSizeKBytes = p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes;
1358 			scratch->calculate_vm_and_row_bytes_params.PTEBufferSizeInRequests = s->PTEBufferSizeInRequestsForChroma[k];
1359 			scratch->calculate_vm_and_row_bytes_params.Pitch = p->myPipe[k].PitchC;
1360 			scratch->calculate_vm_and_row_bytes_params.MacroTileWidth = p->myPipe[k].BlockWidthC;
1361 			scratch->calculate_vm_and_row_bytes_params.MacroTileHeight = p->myPipe[k].BlockHeightC;
1362 			scratch->calculate_vm_and_row_bytes_params.DCCMetaPitch = p->myPipe[k].DCCMetaPitchC;
1363 			scratch->calculate_vm_and_row_bytes_params.mrq_present = p->mrq_present;
1364 
1365 			scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow = &s->PixelPTEBytesPerRowC[k];
1366 			scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRowStorage = &s->PixelPTEBytesPerRowStorageC[k];
1367 			scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub = &p->dpte_row_width_chroma_ub[k];
1368 			scratch->calculate_vm_and_row_bytes_params.dpte_row_height = &p->dpte_row_height_chroma[k];
1369 			scratch->calculate_vm_and_row_bytes_params.dpte_row_height_linear = &p->dpte_row_height_linear_chroma[k];
1370 			scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow_one_row_per_frame = &s->PixelPTEBytesPerRowC_one_row_per_frame[k];
1371 			scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub_one_row_per_frame = &s->dpte_row_width_chroma_ub_one_row_per_frame[k];
1372 			scratch->calculate_vm_and_row_bytes_params.dpte_row_height_one_row_per_frame = &s->dpte_row_height_chroma_one_row_per_frame[k];
1373 			scratch->calculate_vm_and_row_bytes_params.vmpg_width = &p->vmpg_width_c[k];
1374 			scratch->calculate_vm_and_row_bytes_params.vmpg_height = &p->vmpg_height_c[k];
1375 			scratch->calculate_vm_and_row_bytes_params.PixelPTEReqWidth = &p->PixelPTEReqWidthC[k];
1376 			scratch->calculate_vm_and_row_bytes_params.PixelPTEReqHeight = &p->PixelPTEReqHeightC[k];
1377 			scratch->calculate_vm_and_row_bytes_params.PTERequestSize = &p->PTERequestSizeC[k];
1378 			scratch->calculate_vm_and_row_bytes_params.dpde0_bytes_per_frame_ub = &p->dpde0_bytes_per_frame_ub_c[k];
1379 
1380 			scratch->calculate_vm_and_row_bytes_params.meta_row_bytes = &s->meta_row_bytes_per_row_ub_c[k];
1381 			scratch->calculate_vm_and_row_bytes_params.MetaRequestWidth = &p->meta_req_width_chroma[k];
1382 			scratch->calculate_vm_and_row_bytes_params.MetaRequestHeight = &p->meta_req_height_chroma[k];
1383 			scratch->calculate_vm_and_row_bytes_params.meta_row_width = &p->meta_row_width_chroma[k];
1384 			scratch->calculate_vm_and_row_bytes_params.meta_row_height = &p->meta_row_height_chroma[k];
1385 			scratch->calculate_vm_and_row_bytes_params.meta_pte_bytes_per_frame_ub = &p->meta_pte_bytes_per_frame_ub_c[k];
1386 
1387 			s->vm_bytes_c = dcn5_calculate_vm_and_row_bytes(&scratch->calculate_vm_and_row_bytes_params);
1388 
1389 			p->PrefetchSourceLinesC[k] = dcn5_calculate_prefetch_source_lines(
1390 					p->myPipe[k].VRatioChroma,
1391 					p->myPipe[k].VTapsChroma,
1392 					p->myPipe[k].UPSPEnabled,
1393 					p->myPipe[k].UPSPVTaps,
1394 					p->myPipe[k].UPSPSamplePositioning,
1395 					dml2_core_utils_is_420(p->myPipe[k].SourcePixelFormat),
1396 					p->myPipe[k].InterlaceEnable,
1397 					p->myPipe[k].ProgressiveToInterlaceUnitInOPP,
1398 					p->myPipe[k].SwathHeightC,
1399 					p->myPipe[k].RotationAngle,
1400 					p->myPipe[k].mirrored,
1401 					p->myPipe[k].ViewportStationary,
1402 					p->SwathWidthC[k],
1403 					p->myPipe[k].ViewportHeightC,
1404 					p->myPipe[k].ViewportXStartC,
1405 					p->myPipe[k].ViewportYStartC,
1406 
1407 					// Output
1408 					&p->VInitPreFillC[k],
1409 					&p->MaxNumSwathC[k]);
1410 		} else {
1411 			s->PTEBufferSizeInRequestsForLuma[k] = p->PTEBufferSizeInRequestsLuma + p->PTEBufferSizeInRequestsChroma;
1412 			s->PTEBufferSizeInRequestsForChroma[k] = 0;
1413 			s->PixelPTEBytesPerRowC[k] = 0;
1414 			s->PixelPTEBytesPerRowStorageC[k] = 0;
1415 			s->vm_bytes_c = 0;
1416 			p->MaxNumSwathC[k] = 0;
1417 			p->PrefetchSourceLinesC[k] = 0;
1418 			s->dpte_row_height_chroma_one_row_per_frame[k] = 0;
1419 			s->dpte_row_width_chroma_ub_one_row_per_frame[k] = 0;
1420 			s->PixelPTEBytesPerRowC_one_row_per_frame[k] = 0;
1421 		}
1422 
1423 		scratch->calculate_vm_and_row_bytes_params.ViewportStationary = p->myPipe[k].ViewportStationary;
1424 		scratch->calculate_vm_and_row_bytes_params.DCCEnable = p->myPipe[k].DCCEnable;
1425 		scratch->calculate_vm_and_row_bytes_params.NumberOfDPPs = p->myPipe[k].DPPPerSurface;
1426 		scratch->calculate_vm_and_row_bytes_params.BlockHeight256Bytes = p->myPipe[k].BlockHeight256BytesY;
1427 		scratch->calculate_vm_and_row_bytes_params.BlockWidth256Bytes = p->myPipe[k].BlockWidth256BytesY;
1428 		scratch->calculate_vm_and_row_bytes_params.SourcePixelFormat = p->myPipe[k].SourcePixelFormat;
1429 		scratch->calculate_vm_and_row_bytes_params.SurfaceTiling = p->myPipe[k].SurfaceTiling;
1430 		scratch->calculate_vm_and_row_bytes_params.BytePerPixel = p->myPipe[k].BytePerPixelY;
1431 		scratch->calculate_vm_and_row_bytes_params.RotationAngle = p->myPipe[k].RotationAngle;
1432 		scratch->calculate_vm_and_row_bytes_params.SwathWidth = p->SwathWidthY[k];
1433 		scratch->calculate_vm_and_row_bytes_params.ViewportHeight = p->myPipe[k].ViewportHeight;
1434 		scratch->calculate_vm_and_row_bytes_params.ViewportXStart = p->myPipe[k].ViewportXStart;
1435 		scratch->calculate_vm_and_row_bytes_params.ViewportYStart = p->myPipe[k].ViewportYStart;
1436 		scratch->calculate_vm_and_row_bytes_params.GPUVMEnable = p->display_cfg->gpuvm_enable;
1437 		scratch->calculate_vm_and_row_bytes_params.GPUVMMaxPageTableLevels = p->display_cfg->gpuvm_max_page_table_levels;
1438 		scratch->calculate_vm_and_row_bytes_params.GPUVMMinPageSizeKBytes = p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes;
1439 		scratch->calculate_vm_and_row_bytes_params.PTEBufferSizeInRequests = s->PTEBufferSizeInRequestsForLuma[k];
1440 		scratch->calculate_vm_and_row_bytes_params.Pitch = p->myPipe[k].PitchY;
1441 		scratch->calculate_vm_and_row_bytes_params.MacroTileWidth = p->myPipe[k].BlockWidthY;
1442 		scratch->calculate_vm_and_row_bytes_params.MacroTileHeight = p->myPipe[k].BlockHeightY;
1443 		scratch->calculate_vm_and_row_bytes_params.DCCMetaPitch = p->myPipe[k].DCCMetaPitchY;
1444 		scratch->calculate_vm_and_row_bytes_params.mrq_present = p->mrq_present;
1445 
1446 		scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow = &s->PixelPTEBytesPerRowY[k];
1447 		scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRowStorage = &s->PixelPTEBytesPerRowStorageY[k];
1448 		scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub = &p->dpte_row_width_luma_ub[k];
1449 		scratch->calculate_vm_and_row_bytes_params.dpte_row_height = &p->dpte_row_height_luma[k];
1450 		scratch->calculate_vm_and_row_bytes_params.dpte_row_height_linear = &p->dpte_row_height_linear_luma[k];
1451 		scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow_one_row_per_frame = &s->PixelPTEBytesPerRowY_one_row_per_frame[k];
1452 		scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub_one_row_per_frame = &s->dpte_row_width_luma_ub_one_row_per_frame[k];
1453 		scratch->calculate_vm_and_row_bytes_params.dpte_row_height_one_row_per_frame = &s->dpte_row_height_luma_one_row_per_frame[k];
1454 		scratch->calculate_vm_and_row_bytes_params.vmpg_width = &p->vmpg_width_y[k];
1455 		scratch->calculate_vm_and_row_bytes_params.vmpg_height = &p->vmpg_height_y[k];
1456 		scratch->calculate_vm_and_row_bytes_params.PixelPTEReqWidth = &p->PixelPTEReqWidthY[k];
1457 		scratch->calculate_vm_and_row_bytes_params.PixelPTEReqHeight = &p->PixelPTEReqHeightY[k];
1458 		scratch->calculate_vm_and_row_bytes_params.PTERequestSize = &p->PTERequestSizeY[k];
1459 		scratch->calculate_vm_and_row_bytes_params.dpde0_bytes_per_frame_ub = &p->dpde0_bytes_per_frame_ub_l[k];
1460 
1461 		scratch->calculate_vm_and_row_bytes_params.meta_row_bytes = &s->meta_row_bytes_per_row_ub_l[k];
1462 		scratch->calculate_vm_and_row_bytes_params.MetaRequestWidth = &p->meta_req_width_luma[k];
1463 		scratch->calculate_vm_and_row_bytes_params.MetaRequestHeight = &p->meta_req_height_luma[k];
1464 		scratch->calculate_vm_and_row_bytes_params.meta_row_width = &p->meta_row_width_luma[k];
1465 		scratch->calculate_vm_and_row_bytes_params.meta_row_height = &p->meta_row_height_luma[k];
1466 		scratch->calculate_vm_and_row_bytes_params.meta_pte_bytes_per_frame_ub = &p->meta_pte_bytes_per_frame_ub_l[k];
1467 
1468 		s->vm_bytes_l = dcn5_calculate_vm_and_row_bytes(&scratch->calculate_vm_and_row_bytes_params);
1469 
1470 		p->PrefetchSourceLinesY[k] = dcn5_calculate_prefetch_source_lines(
1471 				p->myPipe[k].VRatio,
1472 				p->myPipe[k].VTaps,
1473 				0, //No upsampler in Luma
1474 				p->myPipe[k].UPSPVTaps,
1475 				p->myPipe[k].UPSPSamplePositioning,
1476 				dml2_core_utils_is_420(p->myPipe[k].SourcePixelFormat),
1477 				p->myPipe[k].InterlaceEnable,
1478 				p->myPipe[k].ProgressiveToInterlaceUnitInOPP,
1479 				p->myPipe[k].SwathHeightY,
1480 				p->myPipe[k].RotationAngle,
1481 				p->myPipe[k].mirrored,
1482 				p->myPipe[k].ViewportStationary,
1483 				p->SwathWidthY[k],
1484 				p->myPipe[k].ViewportHeight,
1485 				p->myPipe[k].ViewportXStart,
1486 				p->myPipe[k].ViewportYStart,
1487 
1488 				// Output
1489 				&p->VInitPreFillY[k],
1490 				&p->MaxNumSwathY[k]);
1491 
1492 		DML_LOG_VERBOSE("DML::%s: k=%u, vm_bytes_l = %u (before hvm level)\n", __func__, k, s->vm_bytes_l);
1493 		DML_LOG_VERBOSE("DML::%s: k=%u, vm_bytes_c = %u (before hvm level)\n", __func__, k, s->vm_bytes_c);
1494 		DML_LOG_VERBOSE("DML::%s: k=%u, meta_row_bytes_per_row_ub_l = %u\n", __func__, k, s->meta_row_bytes_per_row_ub_l[k]);
1495 		DML_LOG_VERBOSE("DML::%s: k=%u, meta_row_bytes_per_row_ub_c = %u\n", __func__, k, s->meta_row_bytes_per_row_ub_c[k]);
1496 		p->vm_bytes[k] = (s->vm_bytes_l + s->vm_bytes_c) * (1 + 8 * s->HostVMDynamicLevels);
1497 		p->meta_row_bytes[k] = s->meta_row_bytes_per_row_ub_l[k] + s->meta_row_bytes_per_row_ub_c[k];
1498 		p->meta_row_bytes_per_row_ub_l[k] = s->meta_row_bytes_per_row_ub_l[k];
1499 		p->meta_row_bytes_per_row_ub_c[k] = s->meta_row_bytes_per_row_ub_c[k];
1500 
1501 		DML_LOG_VERBOSE("DML::%s: k=%u, meta_row_bytes = %u\n", __func__, k, p->meta_row_bytes[k]);
1502 		DML_LOG_VERBOSE("DML::%s: k=%u, vm_bytes = %u (after hvm level)\n", __func__, k, p->vm_bytes[k]);
1503 		if (s->PixelPTEBytesPerRowStorageY[k] <= 64 * s->PTEBufferSizeInRequestsForLuma[k] && s->PixelPTEBytesPerRowStorageC[k] <= 64 * s->PTEBufferSizeInRequestsForChroma[k]) {
1504 			p->PTEBufferSizeNotExceeded[k] = true;
1505 		} else {
1506 			p->PTEBufferSizeNotExceeded[k] = false;
1507 		}
1508 
1509 		s->one_row_per_frame_fits_in_buffer[k] = (s->PixelPTEBytesPerRowY_one_row_per_frame[k] <= 64 * 2 * s->PTEBufferSizeInRequestsForLuma[k] &&
1510 				s->PixelPTEBytesPerRowC_one_row_per_frame[k] <= 64 * 2 * s->PTEBufferSizeInRequestsForChroma[k]);
1511 		if (p->PTEBufferSizeNotExceeded[k] == 0 || s->one_row_per_frame_fits_in_buffer[k] == 0) {
1512 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowY = %u (before hvm level)\n", __func__, k, s->PixelPTEBytesPerRowY[k]);
1513 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowC = %u (before hvm level)\n", __func__, k, s->PixelPTEBytesPerRowC[k]);
1514 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowStorageY = %u\n", __func__, k, s->PixelPTEBytesPerRowStorageY[k]);
1515 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowStorageC = %u\n", __func__, k, s->PixelPTEBytesPerRowStorageC[k]);
1516 			DML_LOG_VERBOSE("DML::%s: k=%u, PTEBufferSizeInRequestsForLuma = %u\n", __func__, k, s->PTEBufferSizeInRequestsForLuma[k]);
1517 			DML_LOG_VERBOSE("DML::%s: k=%u, PTEBufferSizeInRequestsForChroma = %u\n", __func__, k, s->PTEBufferSizeInRequestsForChroma[k]);
1518 			DML_LOG_VERBOSE("DML::%s: k=%u, PTEBufferSizeNotExceeded (not one_row_per_frame) = %u\n", __func__, k, p->PTEBufferSizeNotExceeded[k]);
1519 
1520 			DML_LOG_VERBOSE("DML::%s: k=%u, HostVMDynamicLevels = %u\n", __func__, k, s->HostVMDynamicLevels);
1521 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowY_one_row_per_frame = %u\n", __func__, k, s->PixelPTEBytesPerRowY_one_row_per_frame[k]);
1522 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowC_one_row_per_frame = %u\n", __func__, k, s->PixelPTEBytesPerRowC_one_row_per_frame[k]);
1523 			DML_LOG_VERBOSE("DML::%s: k=%u, one_row_per_frame_fits_in_buffer = %u\n", __func__, k, s->one_row_per_frame_fits_in_buffer[k]);
1524 		}
1525 	}
1526 
1527 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
1528 		if (p->display_cfg->gpuvm_enable) {
1529 			DML_LOG_VERBOSE("DML::%s: k=%u, force_pte_buffer_mode.enable = %u\n", __func__, k, p->display_cfg->plane_descriptors[k].overrides.hw.force_pte_buffer_mode.enable);
1530 			DML_LOG_VERBOSE("DML::%s: k=%u, force_pte_buffer_mode.value = %u\n", __func__, k, p->display_cfg->plane_descriptors[k].overrides.hw.force_pte_buffer_mode.value);
1531 			DML_LOG_VERBOSE("DML::%s: k=%u, gpuvm_min_page_size_kbytes = %u\n", __func__, k, p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes);
1532 			DML_LOG_VERBOSE("DML::%s: k=%u, uclk_pstate_switch_modes = %u\n", __func__, k, p->uclk_pstate_switch_modes[k]);
1533 			DML_LOG_VERBOSE("DML::%s: k=%u, FORCE_ONE_ROW_FOR_FRAME = %u\n", __func__, k, p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME);
1534 
1535 			if (p->display_cfg->plane_descriptors[k].overrides.hw.force_pte_buffer_mode.enable == 1) {
1536 				p->PTE_BUFFER_MODE[k] = p->display_cfg->plane_descriptors[k].overrides.hw.force_pte_buffer_mode.value;
1537 			} else {
1538 				p->PTE_BUFFER_MODE[k] = p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME
1539 					|| (p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes > 64)
1540 					|| (p->uclk_pstate_switch_modes[k] == dml2_pstate_method_alternate);
1541 				p->BIGK_FRAGMENT_SIZE[k] = (unsigned int)(math_log((float)p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes * 1024, 2) - 12);
1542 			}
1543 		} else {
1544 			p->PTE_BUFFER_MODE[k] = 0;
1545 			p->BIGK_FRAGMENT_SIZE[k] = 0;
1546 		}
1547 		DML_LOG_VERBOSE("DML::%s: k=%u, PTE_BUFFER_MODE = %u\n", __func__, k, p->PTE_BUFFER_MODE[k]);
1548 		DML_LOG_VERBOSE("DML::%s: k=%u, BIGK_FRAGMENT_SIZE = %u\n", __func__, k, p->BIGK_FRAGMENT_SIZE[k]);
1549 	}
1550 
1551 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
1552 		s->HostVMDynamicLevels = dcn5_calculate_host_vm_dynamic_levels(p->display_cfg->gpuvm_enable, p->display_cfg->hostvm_enable, p->display_cfg->plane_descriptors[k].overrides.hostvm_min_page_size_kbytes,
1553 			p->display_cfg->hostvm_max_non_cached_page_table_levels);
1554 
1555 		p->DCCMetaBufferSizeNotExceeded[k] = true;
1556 		if (p->display_cfg->gpuvm_enable) {
1557 		    p->use_one_row_for_frame[k] = p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME
1558 					|| (p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes > 64 && dml2_core_utils_is_vertical_rotation(p->myPipe[k].RotationAngle))
1559 					|| (p->uclk_pstate_switch_modes[k] == dml2_pstate_method_alternate);
1560 		}
1561 
1562 		p->use_one_row_for_frame_flip[k] = p->use_one_row_for_frame[k];
1563 
1564 		if (p->use_one_row_for_frame[k]) {
1565 			p->dpte_row_height_luma[k] = s->dpte_row_height_luma_one_row_per_frame[k];
1566 			p->dpte_row_width_luma_ub[k] = s->dpte_row_width_luma_ub_one_row_per_frame[k];
1567 			s->PixelPTEBytesPerRowY[k] = s->PixelPTEBytesPerRowY_one_row_per_frame[k];
1568 			p->dpte_row_height_chroma[k] = s->dpte_row_height_chroma_one_row_per_frame[k];
1569 			p->dpte_row_width_chroma_ub[k] = s->dpte_row_width_chroma_ub_one_row_per_frame[k];
1570 			s->PixelPTEBytesPerRowC[k] = s->PixelPTEBytesPerRowC_one_row_per_frame[k];
1571 			p->PTEBufferSizeNotExceeded[k] = s->one_row_per_frame_fits_in_buffer[k];
1572 		}
1573 
1574 		if (p->meta_row_bytes[k] <= p->DCCMetaBufferSizeBytes) {
1575 			p->DCCMetaBufferSizeNotExceeded[k] = true;
1576 		} else {
1577 			p->DCCMetaBufferSizeNotExceeded[k] = false;
1578 			DML_LOG_VERBOSE("DML::%s: k=%d, meta_row_bytes = %d\n",  __func__, k, p->meta_row_bytes[k]);
1579 			DML_LOG_VERBOSE("DML::%s: k=%d, DCCMetaBufferSizeBytes = %d\n",  __func__, k, p->DCCMetaBufferSizeBytes);
1580 			DML_LOG_VERBOSE("DML::%s: k=%d, DCCMetaBufferSizeNotExceeded = %d\n",  __func__, k, p->DCCMetaBufferSizeNotExceeded[k]);
1581 		}
1582 
1583 		s->PixelPTEBytesPerRowY[k] = s->PixelPTEBytesPerRowY[k] * (1 + 8 * s->HostVMDynamicLevels);
1584 		s->PixelPTEBytesPerRowC[k] = s->PixelPTEBytesPerRowC[k] * (1 + 8 * s->HostVMDynamicLevels);
1585 		p->PixelPTEBytesPerRow[k] = s->PixelPTEBytesPerRowY[k] + s->PixelPTEBytesPerRowC[k];
1586 		p->dpte_row_bytes_per_row_l[k] = s->PixelPTEBytesPerRowY[k];
1587 		p->dpte_row_bytes_per_row_c[k] = s->PixelPTEBytesPerRowC[k];
1588 
1589 		// if one row of dPTEs is meant to span the entire frame, then for these calculations, we will pretend like that one big row is fetched in two halfs
1590 		if (p->use_one_row_for_frame[k])
1591 			p->PixelPTEBytesPerRow[k] = p->PixelPTEBytesPerRow[k] / 2;
1592 
1593 		dcn5_calculate_row_bandwidth(
1594 				p->display_cfg->gpuvm_enable,
1595 				p->use_one_row_for_frame[k],
1596 				p->myPipe[k].SourcePixelFormat,
1597 				p->myPipe[k].VRatio,
1598 				p->myPipe[k].VRatioChroma,
1599 				p->myPipe[k].DCCEnable,
1600 				p->myPipe[k].HTotal / p->myPipe[k].PixelClock,
1601 				s->PixelPTEBytesPerRowY[k],
1602 				s->PixelPTEBytesPerRowC[k],
1603 				p->dpte_row_height_luma[k],
1604 				p->dpte_row_height_chroma[k],
1605 
1606 				p->mrq_present,
1607 				p->meta_row_bytes_per_row_ub_l[k],
1608 				p->meta_row_bytes_per_row_ub_c[k],
1609 				p->meta_row_height_luma[k],
1610 				p->meta_row_height_chroma[k],
1611 
1612 				// Output
1613 				&p->dpte_row_bw[k],
1614 				&p->meta_row_bw[k]);
1615 		DML_LOG_VERBOSE("DML::%s: k=%u, use_one_row_for_frame = %u\n", __func__, k, p->use_one_row_for_frame[k]);
1616 		DML_LOG_VERBOSE("DML::%s: k=%u, use_one_row_for_frame_flip = %u\n", __func__, k, p->use_one_row_for_frame_flip[k]);
1617 		DML_LOG_VERBOSE("DML::%s: k=%u, dpte_row_height_luma = %u\n", __func__, k, p->dpte_row_height_luma[k]);
1618 		DML_LOG_VERBOSE("DML::%s: k=%u, dpte_row_width_luma_ub = %u\n", __func__, k, p->dpte_row_width_luma_ub[k]);
1619 		DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowY = %u (after hvm level)\n", __func__, k, s->PixelPTEBytesPerRowY[k]);
1620 		DML_LOG_VERBOSE("DML::%s: k=%u, dpte_row_height_chroma = %u\n", __func__, k, p->dpte_row_height_chroma[k]);
1621 		DML_LOG_VERBOSE("DML::%s: k=%u, dpte_row_width_chroma_ub = %u\n", __func__, k, p->dpte_row_width_chroma_ub[k]);
1622 		DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRowC = %u (after hvm level)\n", __func__, k, s->PixelPTEBytesPerRowC[k]);
1623 		DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEBytesPerRow = %u\n", __func__, k, p->PixelPTEBytesPerRow[k]);
1624 		DML_LOG_VERBOSE("DML::%s: k=%u, PTEBufferSizeNotExceeded = %u\n", __func__, k, p->PTEBufferSizeNotExceeded[k]);
1625 		DML_LOG_VERBOSE("DML::%s: k=%u, gpuvm_enable = %u\n", __func__, k, p->display_cfg->gpuvm_enable);
1626 	}
1627 }
1628 
dcn5_calculate_bytes_to_fetch_required_to_hide_latency(struct dml2_core_calcs_calculate_bytes_to_fetch_required_to_hide_latency_params * p)1629 void dcn5_calculate_bytes_to_fetch_required_to_hide_latency(
1630 		struct dml2_core_calcs_calculate_bytes_to_fetch_required_to_hide_latency_params *p)
1631 {
1632 	unsigned int dst_lines_to_hide;
1633 	unsigned int src_lines_to_hide_l;
1634 	unsigned int src_lines_to_hide_c;
1635 	unsigned int plane_index;
1636 	unsigned int stream_index;
1637 
1638 	for (plane_index = 0; plane_index < p->num_active_planes; plane_index++) {
1639 		stream_index = p->display_cfg->plane_descriptors[plane_index].stream_index;
1640 
1641 		dst_lines_to_hide = (unsigned int)math_ceil(p->latency_to_hide_us[plane_index] /
1642 				((double)p->display_cfg->stream_descriptors[stream_index].timing.h_total /
1643 						(double)p->display_cfg->stream_descriptors[stream_index].timing.pixel_clock_khz * 1000.0));
1644 
1645 		src_lines_to_hide_l = (unsigned int)math_ceil2(p->display_cfg->plane_descriptors[plane_index].composition.scaler_info.plane0.v_ratio * dst_lines_to_hide,
1646 				p->swath_height_l[plane_index]);
1647 		p->bytes_required_l[plane_index] = src_lines_to_hide_l * p->num_of_dpp[plane_index] * p->swath_width_l[plane_index] * p->byte_per_pix_l[plane_index];
1648 
1649 		src_lines_to_hide_c = (unsigned int)math_ceil2(p->display_cfg->plane_descriptors[plane_index].composition.scaler_info.plane1.v_ratio * dst_lines_to_hide,
1650 				p->swath_height_c[plane_index]);
1651 		p->bytes_required_c[plane_index] = src_lines_to_hide_c * p->num_of_dpp[plane_index] * p->swath_width_c[plane_index] * p->byte_per_pix_c[plane_index];
1652 
1653 		if (p->display_cfg->plane_descriptors[plane_index].surface.dcc.enable && p->mrq_present) {
1654 			p->bytes_required_l[plane_index] += (unsigned int)math_ceil((double)src_lines_to_hide_l / p->meta_row_height_l[plane_index]) * p->meta_row_bytes_per_row_ub_l[plane_index];
1655 			if (p->meta_row_height_c[plane_index]) {
1656 				p->bytes_required_c[plane_index] += (unsigned int)math_ceil((double)src_lines_to_hide_c / p->meta_row_height_c[plane_index]) * p->meta_row_bytes_per_row_ub_c[plane_index];
1657 			}
1658 		}
1659 
1660 		if (p->display_cfg->gpuvm_enable == true) {
1661 			p->bytes_required_l[plane_index] += (unsigned int)math_ceil((double)src_lines_to_hide_l / p->dpte_row_height_l[plane_index]) * p->dpte_bytes_per_row_l[plane_index];
1662 			if (p->dpte_row_height_c[plane_index]) {
1663 				p->bytes_required_c[plane_index] += (unsigned int)math_ceil((double)src_lines_to_hide_c / p->dpte_row_height_c[plane_index]) * p->dpte_bytes_per_row_c[plane_index];
1664 			}
1665 		}
1666 	}
1667 }
1668 
dcn5_calculate_excess_vactive_bandwidth_required(const struct dml2_display_cfg * display_cfg,unsigned int num_active_planes,unsigned int bytes_required_l[],unsigned int bytes_required_c[],double excess_vactive_fill_bw_l[],double excess_vactive_fill_bw_c[])1669 void dcn5_calculate_excess_vactive_bandwidth_required(
1670 		const struct dml2_display_cfg *display_cfg,
1671 		unsigned int num_active_planes,
1672 		unsigned int bytes_required_l[],
1673 		unsigned int bytes_required_c[],
1674 		/* outputs */
1675 		double excess_vactive_fill_bw_l[],
1676 		double excess_vactive_fill_bw_c[])
1677 {
1678 	unsigned int plane_index;
1679 
1680 	for (plane_index = 0; plane_index < num_active_planes; plane_index++) {
1681 		excess_vactive_fill_bw_l[plane_index] = 0.0;
1682 		excess_vactive_fill_bw_c[plane_index] = 0.0;
1683 
1684 		if (display_cfg->plane_descriptors[plane_index].overrides.max_vactive_det_fill_delay_us[dml2_pstate_type_uclk] > 0) {
1685 			excess_vactive_fill_bw_l[plane_index] = (double)bytes_required_l[plane_index] / (double)display_cfg->plane_descriptors[plane_index].overrides.max_vactive_det_fill_delay_us[dml2_pstate_type_uclk];
1686 			excess_vactive_fill_bw_c[plane_index] = (double)bytes_required_c[plane_index] / (double)display_cfg->plane_descriptors[plane_index].overrides.max_vactive_det_fill_delay_us[dml2_pstate_type_uclk];
1687 		}
1688 	}
1689 }
1690 
dcn5_calculate_cursor_req_attributes(unsigned int cursor_width,unsigned int cursor_bpp,unsigned int * cursor_lines_per_chunk,unsigned int * cursor_bytes_per_line,unsigned int * cursor_bytes_per_chunk,unsigned int * cursor_bytes)1691 void dcn5_calculate_cursor_req_attributes(
1692 		unsigned int cursor_width,
1693 		unsigned int cursor_bpp,
1694 
1695 		// output
1696 		unsigned int *cursor_lines_per_chunk,
1697 		unsigned int *cursor_bytes_per_line,
1698 		unsigned int *cursor_bytes_per_chunk,
1699 		unsigned int *cursor_bytes)
1700 {
1701 	unsigned int cursor_bytes_per_req = 0;
1702 	unsigned int cursor_width_bytes = 0;
1703 
1704 	//SW determines the cursor pitch to support the maximum cursor_width that will be used but the following restrictions apply.
1705 	//- For 2bpp, cursor_pitch = 256 pixels due to min cursor request size of 64B
1706 	//- For 32 or 64 bpp, cursor_pitch = 64, 128 or 256 pixels depending on the cursor width
1707 
1708 	//The cursor requestor uses a cursor request size of 64B, 128B, or 256B depending on the cursor_width and cursor_bpp as follows.
1709 
1710 	cursor_width_bytes = (unsigned int)math_ceil2((double)cursor_width * cursor_bpp / 8, 1);
1711 	if (cursor_width_bytes <= 64)
1712 		cursor_bytes_per_req = 64;
1713 	else if (cursor_width_bytes <= 128)
1714 		cursor_bytes_per_req = 128;
1715 	else
1716 		cursor_bytes_per_req = 256;
1717 
1718 	//If cursor_width_bytes is greater than 256B, then multiple 256B requests are issued to fetch the entire cursor line.
1719 	*cursor_bytes_per_line = (unsigned int)math_ceil2((double)cursor_width_bytes, cursor_bytes_per_req);
1720 
1721 	//Nominally, the cursor chunk is 1KB or 2KB but it is restricted to a power of 2 number of lines with a maximum of 16 lines.
1722 	if (cursor_bpp == 2) {
1723 		*cursor_lines_per_chunk = 16;
1724 	} else if (cursor_bpp == 32) {
1725 		if (cursor_width <= 32)
1726 			*cursor_lines_per_chunk = 16;
1727 		else if (cursor_width <= 64)
1728 			*cursor_lines_per_chunk = 8;
1729 		else if (cursor_width <= 128)
1730 			*cursor_lines_per_chunk = 4;
1731 		else
1732 			*cursor_lines_per_chunk = 2;
1733 	} else if (cursor_bpp == 64) {
1734 		if (cursor_width <= 16)
1735 			*cursor_lines_per_chunk = 16;
1736 		else if (cursor_width <= 32)
1737 			*cursor_lines_per_chunk = 8;
1738 		else if (cursor_width <= 64)
1739 			*cursor_lines_per_chunk = 4;
1740 		else if (cursor_width <= 128)
1741 			*cursor_lines_per_chunk = 2;
1742 		else
1743 			*cursor_lines_per_chunk = 1;
1744 	} else {
1745 		if (cursor_width > 0) {
1746 			DML_LOG_VERBOSE("DML::%s: Invalid cursor_bpp = %d\n", __func__, cursor_bpp);
1747 			DML_ASSERT(0);
1748 		}
1749 	}
1750 
1751 	*cursor_bytes_per_chunk = *cursor_bytes_per_line * *cursor_lines_per_chunk;
1752 
1753 	// For the cursor implementation, all requested data is stored in the return buffer. Given this fact, the cursor_bytes can be directly compared with the CursorBufferSize.
1754 	// Only cursor_width is provided for worst case sizing so assume that the cursor is square
1755 	*cursor_bytes = *cursor_bytes_per_line * cursor_width;
1756 	DML_LOG_VERBOSE("DML::%s: cursor_bpp = %d\n", __func__, cursor_bpp);
1757 	DML_LOG_VERBOSE("DML::%s: cursor_width = %d\n", __func__, cursor_width);
1758 	DML_LOG_VERBOSE("DML::%s: cursor_width_bytes = %d\n", __func__, cursor_width_bytes);
1759 	DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_req = %d\n", __func__, cursor_bytes_per_req);
1760 	DML_LOG_VERBOSE("DML::%s: cursor_lines_per_chunk = %d\n", __func__, *cursor_lines_per_chunk);
1761 	DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_line = %d\n", __func__, *cursor_bytes_per_line);
1762 	DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_chunk = %d\n", __func__, *cursor_bytes_per_chunk);
1763 	DML_LOG_VERBOSE("DML::%s: cursor_bytes = %d\n", __func__, *cursor_bytes);
1764 	DML_LOG_VERBOSE("DML::%s: cursor_pitch = %d\n", __func__, cursor_bpp == 2 ? 256 : (unsigned int)1 << (unsigned int)math_ceil2(math_log((float)cursor_width, 2), 1));
1765 }
1766 
dcn5_calculate_cursor_urgent_burst_factor(unsigned int CursorBufferSize,unsigned int CursorWidth,unsigned int cursor_bytes_per_chunk,unsigned int cursor_lines_per_chunk,double LineTime,double UrgentLatency,double * UrgentBurstFactorCursor,bool * NotEnoughUrgentLatencyHiding)1767 void dcn5_calculate_cursor_urgent_burst_factor(
1768 		unsigned int CursorBufferSize,
1769 		unsigned int CursorWidth,
1770 		unsigned int cursor_bytes_per_chunk,
1771 		unsigned int cursor_lines_per_chunk,
1772 		double LineTime,
1773 		double UrgentLatency,
1774 
1775 		double *UrgentBurstFactorCursor,
1776 		bool *NotEnoughUrgentLatencyHiding)
1777 {
1778 	unsigned int LinesInCursorBuffer = 0;
1779 	double CursorBufferSizeInTime = 0;
1780 
1781 	if (CursorWidth > 0) {
1782 		LinesInCursorBuffer = (unsigned int)math_floor2(CursorBufferSize * 1024.0 / (double)cursor_bytes_per_chunk, 1) * cursor_lines_per_chunk;
1783 
1784 		CursorBufferSizeInTime = LinesInCursorBuffer * LineTime;
1785 		if (CursorBufferSizeInTime - UrgentLatency <= 0) {
1786 			*NotEnoughUrgentLatencyHiding = 1;
1787 			*UrgentBurstFactorCursor = 1;
1788 		} else {
1789 			*NotEnoughUrgentLatencyHiding = 0;
1790 			*UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency);
1791 		}
1792 		DML_LOG_VERBOSE("DML::%s: LinesInCursorBuffer = %u\n", __func__, LinesInCursorBuffer);
1793 		DML_LOG_VERBOSE("DML::%s: CursorBufferSizeInTime = %f\n", __func__, CursorBufferSizeInTime);
1794 		DML_LOG_VERBOSE("DML::%s: CursorBufferSize = %u (kbytes)\n", __func__, CursorBufferSize);
1795 		DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_chunk = %u\n", __func__, cursor_bytes_per_chunk);
1796 		DML_LOG_VERBOSE("DML::%s: cursor_lines_per_chunk = %u\n", __func__, cursor_lines_per_chunk);
1797 		DML_LOG_VERBOSE("DML::%s: UrgentBurstFactorCursor = %f\n", __func__, *UrgentBurstFactorCursor);
1798 		DML_LOG_VERBOSE("DML::%s: NotEnoughUrgentLatencyHiding = %d\n", __func__, *NotEnoughUrgentLatencyHiding);
1799 	}
1800 }
1801 
dcn5_calculate_urgent_burst_factor(const struct dml2_plane_parameters * plane_cfg,unsigned int swath_width_luma_ub,unsigned int swath_width_chroma_ub,unsigned int SwathHeightY,unsigned int SwathHeightC,double LineTime,double UrgentLatency,double VRatio,double VRatioC,double BytePerPixelInDETY,double BytePerPixelInDETC,unsigned int DETBufferSizeY,unsigned int DETBufferSizeC,double * UrgentBurstFactorLuma,double * UrgentBurstFactorChroma,bool * NotEnoughUrgentLatencyHiding)1802 void dcn5_calculate_urgent_burst_factor(
1803 		const struct dml2_plane_parameters *plane_cfg,
1804 		unsigned int swath_width_luma_ub,
1805 		unsigned int swath_width_chroma_ub,
1806 		unsigned int SwathHeightY,
1807 		unsigned int SwathHeightC,
1808 		double LineTime,
1809 		double UrgentLatency,
1810 		double VRatio,
1811 		double VRatioC,
1812 		double BytePerPixelInDETY,
1813 		double BytePerPixelInDETC,
1814 		unsigned int DETBufferSizeY,
1815 		unsigned int DETBufferSizeC,
1816 		// Output
1817 		double *UrgentBurstFactorLuma,
1818 		double *UrgentBurstFactorChroma,
1819 		bool *NotEnoughUrgentLatencyHiding)
1820 {
1821 	(void)plane_cfg;
1822 	double LinesInDETLuma;
1823 	double LinesInDETChroma;
1824 	double DETBufferSizeInTimeLuma;
1825 	double DETBufferSizeInTimeChroma;
1826 
1827 	*NotEnoughUrgentLatencyHiding = 0;
1828 	*UrgentBurstFactorLuma = 0;
1829 	*UrgentBurstFactorChroma = 0;
1830 
1831 	DML_LOG_VERBOSE("DML::%s: VRatio = %f\n", __func__, VRatio);
1832 	DML_LOG_VERBOSE("DML::%s: VRatioC = %f\n", __func__, VRatioC);
1833 	DML_LOG_VERBOSE("DML::%s: DETBufferSizeY = %d\n", __func__, DETBufferSizeY);
1834 	DML_LOG_VERBOSE("DML::%s: DETBufferSizeC = %d\n", __func__, DETBufferSizeC);
1835 	DML_LOG_VERBOSE("DML::%s: BytePerPixelInDETY = %f\n", __func__, BytePerPixelInDETY);
1836 	DML_LOG_VERBOSE("DML::%s: swath_width_luma_ub = %d\n", __func__, swath_width_luma_ub);
1837 	DML_LOG_VERBOSE("DML::%s: LineTime = %f\n", __func__, LineTime);
1838 	DML_ASSERT(VRatio > 0);
1839 
1840 	LinesInDETLuma = DETBufferSizeY / BytePerPixelInDETY / swath_width_luma_ub;
1841 
1842 	DETBufferSizeInTimeLuma = math_floor2(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
1843 	if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
1844 		*NotEnoughUrgentLatencyHiding = 1;
1845 		*UrgentBurstFactorLuma = 1;
1846 	} else {
1847 		*UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency);
1848 	}
1849 
1850 	if (BytePerPixelInDETC > 0) {
1851 		LinesInDETChroma = DETBufferSizeC / BytePerPixelInDETC / swath_width_chroma_ub;
1852 
1853 		DETBufferSizeInTimeChroma = math_floor2(LinesInDETChroma, SwathHeightC) * LineTime / VRatioC;
1854 		if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
1855 			*NotEnoughUrgentLatencyHiding = 1;
1856 			*UrgentBurstFactorChroma = 1;
1857 		} else {
1858 			*UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency);
1859 		}
1860 	}
1861 
1862 	DML_LOG_VERBOSE("DML::%s: LinesInDETLuma = %f\n", __func__, LinesInDETLuma);
1863 	DML_LOG_VERBOSE("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency);
1864 	DML_LOG_VERBOSE("DML::%s: DETBufferSizeInTimeLuma = %f\n", __func__, DETBufferSizeInTimeLuma);
1865 	DML_LOG_VERBOSE("DML::%s: UrgentBurstFactorLuma = %f\n", __func__, *UrgentBurstFactorLuma);
1866 	DML_LOG_VERBOSE("DML::%s: UrgentBurstFactorChroma = %f\n", __func__, *UrgentBurstFactorChroma);
1867 	DML_LOG_VERBOSE("DML::%s: NotEnoughUrgentLatencyHiding = %d\n", __func__, *NotEnoughUrgentLatencyHiding);
1868 }
1869 
dcn5_calculate_dcfclk_deep_sleep(const struct dml2_display_cfg * display_cfg,unsigned int NumberOfActiveSurfaces,unsigned int BytePerPixelY[],unsigned int BytePerPixelC[],unsigned int SwathWidthY[],unsigned int SwathWidthC[],unsigned int DPPPerSurface[],double PSCL_THROUGHPUT[],double PSCL_THROUGHPUT_CHROMA[],double Dppclk[],double ReadBandwidthLuma[],double ReadBandwidthChroma[],unsigned int ReturnBusWidth,double * DCFClkDeepSleep)1870 void dcn5_calculate_dcfclk_deep_sleep(
1871 		const struct dml2_display_cfg *display_cfg,
1872 		unsigned int NumberOfActiveSurfaces,
1873 		unsigned int BytePerPixelY[],
1874 		unsigned int BytePerPixelC[],
1875 		unsigned int SwathWidthY[],
1876 		unsigned int SwathWidthC[],
1877 		unsigned int DPPPerSurface[],
1878 		double PSCL_THROUGHPUT[],
1879 		double PSCL_THROUGHPUT_CHROMA[],
1880 		double Dppclk[],
1881 		double ReadBandwidthLuma[],
1882 		double ReadBandwidthChroma[],
1883 		unsigned int ReturnBusWidth,
1884 
1885 		// Output
1886 		double *DCFClkDeepSleep)
1887 {
1888 	double DisplayPipeLineDeliveryTimeLuma;
1889 	double DisplayPipeLineDeliveryTimeChroma;
1890 	double DCFClkDeepSleepPerSurface[DML2_MAX_PLANES];
1891 	double ReadBandwidth = 0.0;
1892 
1893 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
1894 		double pixel_rate_mhz = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
1895 
1896 		if (display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio <= 1) {
1897 			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerSurface[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio / pixel_rate_mhz;
1898 		} else {
1899 			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k] / Dppclk[k];
1900 		}
1901 		if (BytePerPixelC[k] == 0) {
1902 			DisplayPipeLineDeliveryTimeChroma = 0;
1903 		} else {
1904 			if (display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio <= 1) {
1905 				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerSurface[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio / pixel_rate_mhz;
1906 			} else {
1907 				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k];
1908 			}
1909 		}
1910 
1911 		if (BytePerPixelC[k] > 0) {
1912 			DCFClkDeepSleepPerSurface[k] = math_max2(__DML2_CALCS_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 32.0 / DisplayPipeLineDeliveryTimeLuma,
1913 					__DML2_CALCS_DCFCLK_FACTOR__ * SwathWidthC[k] * BytePerPixelC[k] / 32.0 / DisplayPipeLineDeliveryTimeChroma);
1914 		} else {
1915 			DCFClkDeepSleepPerSurface[k] = __DML2_CALCS_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma;
1916 		}
1917 		DCFClkDeepSleepPerSurface[k] = math_max2(DCFClkDeepSleepPerSurface[k], pixel_rate_mhz / 16);
1918 
1919 		DML_LOG_VERBOSE("DML::%s: k=%u, PixelClock = %f\n", __func__, k, pixel_rate_mhz);
1920 		DML_LOG_VERBOSE("DML::%s: k=%u, DCFClkDeepSleepPerSurface = %f\n", __func__, k, DCFClkDeepSleepPerSurface[k]);
1921 	}
1922 
1923 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
1924 		ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
1925 	}
1926 
1927 	*DCFClkDeepSleep = math_max2(8.0, __DML2_CALCS_DCFCLK_FACTOR__ * ReadBandwidth / (double)ReturnBusWidth);
1928 
1929 	DML_LOG_VERBOSE("DML::%s: __DML2_CALCS_DCFCLK_FACTOR__ = %f\n", __func__, __DML2_CALCS_DCFCLK_FACTOR__);
1930 	DML_LOG_VERBOSE("DML::%s: ReadBandwidth = %f\n", __func__, ReadBandwidth);
1931 	DML_LOG_VERBOSE("DML::%s: ReturnBusWidth = %u\n", __func__, ReturnBusWidth);
1932 	DML_LOG_VERBOSE("DML::%s: DCFClkDeepSleep = %f\n", __func__, *DCFClkDeepSleep);
1933 
1934 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
1935 		*DCFClkDeepSleep = math_max2(*DCFClkDeepSleep, DCFClkDeepSleepPerSurface[k]);
1936 	}
1937 	DML_LOG_VERBOSE("DML::%s: DCFClkDeepSleep = %f (final)\n", __func__, *DCFClkDeepSleep);
1938 }
1939 
dcn5_calculate_max_vstartup(bool ptoi_supported,unsigned int vblank_nom_default_us,const struct dml2_timing_cfg * timing,double write_back_delay_us)1940 unsigned int dcn5_calculate_max_vstartup(
1941 		bool ptoi_supported,
1942 		unsigned int vblank_nom_default_us,
1943 		const struct dml2_timing_cfg *timing,
1944 		double write_back_delay_us)
1945 {
1946 	unsigned int vblank_size = 0;
1947 	unsigned int max_vstartup_lines = 0;
1948 
1949 	double line_time_us = (double)timing->h_total / ((double)timing->pixel_clock_khz / 1000);
1950 	unsigned int vblank_actual = timing->v_total - timing->v_active;
1951 	unsigned int vblank_nom_default_in_line = (unsigned int)math_floor2((double)vblank_nom_default_us / line_time_us, 1.0);
1952 	unsigned int vblank_avail = (timing->vblank_nom == 0) ? vblank_nom_default_in_line : (unsigned int)timing->vblank_nom;
1953 
1954 	vblank_size = (unsigned int)math_min2(vblank_actual, vblank_avail);
1955 
1956 	if (timing->interlaced && !ptoi_supported)
1957 		max_vstartup_lines = (unsigned int)(math_floor2((vblank_size - 1) / 2.0, 1.0));
1958 	else
1959 		max_vstartup_lines = vblank_size - (unsigned int)math_max2(1.0, math_ceil2(write_back_delay_us / line_time_us, 1.0));
1960 	max_vstartup_lines = (unsigned int)math_min2(max_vstartup_lines, __DML2_CALCS_MAX_VSTARTUP__);
1961 
1962 	DML_LOG_VERBOSE("DML::%s: VBlankNom = %lu\n", __func__, timing->vblank_nom);
1963 	DML_LOG_VERBOSE("DML::%s: vblank_nom_default_us = %u\n", __func__, vblank_nom_default_us);
1964 	DML_LOG_VERBOSE("DML::%s: line_time_us = %f\n", __func__, line_time_us);
1965 	DML_LOG_VERBOSE("DML::%s: vblank_actual = %u\n", __func__, vblank_actual);
1966 	DML_LOG_VERBOSE("DML::%s: vblank_avail = %u\n", __func__, vblank_avail);
1967 	DML_LOG_VERBOSE("DML::%s: max_vstartup_lines = %u\n", __func__, max_vstartup_lines);
1968 	return max_vstartup_lines;
1969 }
1970 
dcn5_calculate_mcache_row_bytes(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_calculate_mcache_row_bytes_params * p)1971 static void dcn5_calculate_mcache_row_bytes(
1972 		struct dml2_core_internal_scratch *scratch,
1973 		struct dml2_core_calcs_calculate_mcache_row_bytes_params *p)
1974 {
1975 	(void)scratch;
1976 	unsigned int vmpg_bytes = 0;
1977 	unsigned int blk_bytes = 0;
1978 	float meta_per_mvmpg_per_channel = 0;
1979 	unsigned int est_blk_per_vmpg = 2;
1980 	unsigned int mvmpg_per_row_ub = 0;
1981 	unsigned int full_vp_width_mvmpg_aligned = 0;
1982 	unsigned int full_vp_height_mvmpg_aligned = 0;
1983 	unsigned int meta_per_mvmpg_per_channel_ub = 0;
1984 	unsigned int mvmpg_per_mcache;
1985 
1986 	DML_LOG_VERBOSE("DML::%s: num_chans = %u\n", __func__, p->num_chans);
1987 	DML_LOG_VERBOSE("DML::%s: mem_word_bytes = %u\n", __func__, p->mem_word_bytes);
1988 	DML_LOG_VERBOSE("DML::%s: mcache_line_size_bytes = %u\n", __func__, p->mcache_line_size_bytes);
1989 	DML_LOG_VERBOSE("DML::%s: mcache_size_bytes = %u\n", __func__, p->mcache_size_bytes);
1990 	DML_LOG_VERBOSE("DML::%s: gpuvm_enable = %u\n", __func__, p->gpuvm_enable);
1991 	DML_LOG_VERBOSE("DML::%s: gpuvm_page_size_kbytes = %u\n", __func__, p->gpuvm_page_size_kbytes);
1992 	DML_LOG_VERBOSE("DML::%s: vp_stationary = %u\n", __func__, p->vp_stationary);
1993 	DML_LOG_VERBOSE("DML::%s: tiling_mode = %u\n", __func__, p->tiling_mode);
1994 	DML_LOG_VERBOSE("DML::%s: vp_start_x = %u\n", __func__, p->vp_start_x);
1995 	DML_LOG_VERBOSE("DML::%s: vp_start_y = %u\n", __func__, p->vp_start_y);
1996 	DML_LOG_VERBOSE("DML::%s: full_vp_width = %u\n", __func__, p->full_vp_width);
1997 	DML_LOG_VERBOSE("DML::%s: full_vp_height = %u\n", __func__, p->full_vp_height);
1998 	DML_LOG_VERBOSE("DML::%s: blk_width = %u\n", __func__, p->blk_width);
1999 	DML_LOG_VERBOSE("DML::%s: blk_height = %u\n", __func__, p->blk_height);
2000 	DML_LOG_VERBOSE("DML::%s: vmpg_width = %u\n", __func__, p->vmpg_width);
2001 	DML_LOG_VERBOSE("DML::%s: vmpg_height = %u\n", __func__, p->vmpg_height);
2002 	DML_LOG_VERBOSE("DML::%s: full_swath_bytes = %u\n", __func__, p->full_swath_bytes);
2003 	DML_ASSERT(p->mcache_line_size_bytes != 0);
2004 	DML_ASSERT(p->mcache_size_bytes != 0);
2005 
2006 	*p->mvmpg_width = 0;
2007 	*p->mvmpg_height = 0;
2008 
2009 	if (p->full_vp_height == 0 && p->full_vp_width == 0) {
2010 		*p->num_mcaches = 0;
2011 		*p->mcache_row_bytes = 0;
2012 		*p->mcache_row_bytes_per_channel = 0;
2013 	} else {
2014 		blk_bytes = dml2_core_utils_get_tile_block_size_bytes(p->tiling_mode, p->bytes_per_pixel);
2015 
2016 		// if gpuvm is not enable, the alignment boundary should be in terms of tiling block size
2017 		vmpg_bytes = p->gpuvm_page_size_kbytes * 1024;
2018 
2019 		//With vmpg_bytes >= tile blk_bytes, the meta_row_width alignment equations are relative to the vmpg_width/height.
2020 		// But for 4KB page with 64KB tile block, we need the meta for all pages in the tile block.
2021 		// Therefore, the alignment is relative to the blk_width/height. The factor of 16 vmpg per 64KB tile block is applied at the end.
2022 		*p->mvmpg_width = p->blk_width;
2023 		*p->mvmpg_height = p->blk_height;
2024 		if (p->gpuvm_enable) {
2025 			if (vmpg_bytes >= blk_bytes) {
2026 				*p->mvmpg_width = p->vmpg_width;
2027 				*p->mvmpg_height = p->vmpg_height;
2028 			} else if (!((blk_bytes == 65536) && (vmpg_bytes == 4096))) {
2029 				DML_LOG_VERBOSE("ERROR: DML::%s: Tiling size and vm page size combination not supported\n", __func__);
2030 				DML_ASSERT(0);
2031 			}
2032 		}
2033 
2034 		//For plane0 & 1, first calculate full_vp_width/height_l/c aligned to vmpg_width/height_l/c
2035 		full_vp_width_mvmpg_aligned = (unsigned int)(math_floor2((p->vp_start_x + p->full_vp_width) + *p->mvmpg_width - 1, *p->mvmpg_width) - math_floor2(p->vp_start_x, *p->mvmpg_width));
2036 		full_vp_height_mvmpg_aligned = (unsigned int)(math_floor2((p->vp_start_y + p->full_vp_height) + *p->mvmpg_height - 1, *p->mvmpg_height) - math_floor2(p->vp_start_y, *p->mvmpg_height));
2037 
2038 		*p->full_vp_access_width_mvmpg_aligned = p->surf_vert ? full_vp_height_mvmpg_aligned : full_vp_width_mvmpg_aligned;
2039 
2040 		//Use the equation for the exact alignment when possible. Note that the exact alignment cannot be used for horizontal access if vmpg_bytes > blk_bytes.
2041 		if (!p->surf_vert) { //horizontal access
2042 			if (p->vp_stationary == 1 && vmpg_bytes <= blk_bytes)
2043 				*p->meta_row_width_ub = full_vp_width_mvmpg_aligned;
2044 			else
2045 				*p->meta_row_width_ub = (unsigned int)math_ceil2((double)p->full_vp_width - 1, *p->mvmpg_width) + *p->mvmpg_width;
2046 			mvmpg_per_row_ub = *p->meta_row_width_ub / *p->mvmpg_width;
2047 		} else { //vertical access
2048 			if (p->vp_stationary == 1)
2049 				*p->meta_row_width_ub = full_vp_height_mvmpg_aligned;
2050 			else
2051 				*p->meta_row_width_ub = (unsigned int)math_ceil2((double)p->full_vp_height - 1, *p->mvmpg_height) + *p->mvmpg_height;
2052 			mvmpg_per_row_ub = *p->meta_row_width_ub / *p->mvmpg_height;
2053 		}
2054 
2055 		if (p->gpuvm_enable) {
2056 			meta_per_mvmpg_per_channel = (float)vmpg_bytes / (float)256 / p->num_chans;
2057 
2058 			//but using the est_blk_per_vmpg between 2 and 4, to be not as pessimestic
2059 			if (p->surf_vert && vmpg_bytes > blk_bytes) {
2060 				meta_per_mvmpg_per_channel = (float)est_blk_per_vmpg * blk_bytes / (float)256 / p->num_chans;
2061 			}
2062 
2063 			*p->dcc_dram_bw_nom_overhead_factor = 1 + math_max2(1.0 / 256.0, math_ceil2(meta_per_mvmpg_per_channel, p->mem_word_bytes) / (256 * meta_per_mvmpg_per_channel)); // dcc_dr_oh_nom
2064 		} else {
2065 			meta_per_mvmpg_per_channel = (float) blk_bytes / (float)256 / p->num_chans;
2066 
2067 			if (!p->surf_vert)
2068 				*p->dcc_dram_bw_nom_overhead_factor = 1 + 1.0 / 256.0;
2069 			else
2070 				*p->dcc_dram_bw_nom_overhead_factor = 1 + math_max2(1.0 / 256.0, math_ceil2(meta_per_mvmpg_per_channel, p->mem_word_bytes) / (256 * meta_per_mvmpg_per_channel));
2071 		}
2072 
2073 		meta_per_mvmpg_per_channel_ub = (unsigned int)math_ceil2((double)meta_per_mvmpg_per_channel, p->mcache_line_size_bytes);
2074 
2075 		//but for 4KB vmpg with 64KB tile blk
2076 		if (p->gpuvm_enable && (blk_bytes == 65536) && (vmpg_bytes == 4096))
2077 			meta_per_mvmpg_per_channel_ub = 16 * meta_per_mvmpg_per_channel_ub;
2078 
2079 		// If this mcache_row_bytes for the full viewport of the surface is less than or equal to mcache_bytes,
2080 		// then one mcache can be used for this request stream. If not, it is useful to know the width of the viewport that can be supported in the mcache_bytes.
2081 		if (p->gpuvm_enable || p->surf_vert) {
2082 			*p->mcache_row_bytes_per_channel = mvmpg_per_row_ub * meta_per_mvmpg_per_channel_ub;
2083 			*p->mcache_row_bytes = *p->mcache_row_bytes_per_channel * p->num_chans;
2084 		} else { // horizontal and gpuvm disable
2085 			*p->mcache_row_bytes = *p->meta_row_width_ub * p->blk_height * p->bytes_per_pixel / 256;
2086 			*p->mcache_row_bytes_per_channel = (unsigned int)math_ceil2((double)*p->mcache_row_bytes / p->num_chans, p->mcache_line_size_bytes);
2087 		}
2088 
2089 		*p->dcc_dram_bw_pref_overhead_factor = 1 + math_max2(1.0 / 256.0, (double)*p->mcache_row_bytes / (double)p->full_swath_bytes); // dcc_dr_oh_pref
2090 		*p->num_mcaches = (unsigned int)math_ceil2((double)*p->mcache_row_bytes_per_channel / p->mcache_size_bytes, 1);
2091 
2092 		mvmpg_per_mcache = p->mcache_size_bytes / meta_per_mvmpg_per_channel_ub;
2093 		*p->mvmpg_per_mcache_lb = (unsigned int)math_floor2(mvmpg_per_mcache, 1);
2094 
2095 		DML_LOG_VERBOSE("DML::%s: gpuvm_enable = %u\n", __func__, p->gpuvm_enable);
2096 		DML_LOG_VERBOSE("DML::%s: vmpg_bytes = %u\n", __func__, vmpg_bytes);
2097 		DML_LOG_VERBOSE("DML::%s: blk_bytes = %u\n", __func__, blk_bytes);
2098 		DML_LOG_VERBOSE("DML::%s: meta_per_mvmpg_per_channel = %f\n", __func__, meta_per_mvmpg_per_channel);
2099 		DML_LOG_VERBOSE("DML::%s: mvmpg_per_row_ub = %u\n", __func__, mvmpg_per_row_ub);
2100 		DML_LOG_VERBOSE("DML::%s: meta_row_width_ub = %u\n", __func__, *p->meta_row_width_ub);
2101 		DML_LOG_VERBOSE("DML::%s: mvmpg_width = %u\n", __func__, *p->mvmpg_width);
2102 		DML_LOG_VERBOSE("DML::%s: mvmpg_height = %u\n", __func__, *p->mvmpg_height);
2103 		DML_LOG_VERBOSE("DML::%s: dcc_dram_bw_nom_overhead_factor = %f\n", __func__, *p->dcc_dram_bw_nom_overhead_factor);
2104 		DML_LOG_VERBOSE("DML::%s: dcc_dram_bw_pref_overhead_factor = %f\n", __func__, *p->dcc_dram_bw_pref_overhead_factor);
2105 	}
2106 
2107 	DML_LOG_VERBOSE("DML::%s: mcache_row_bytes = %u\n", __func__, *p->mcache_row_bytes);
2108 	DML_LOG_VERBOSE("DML::%s: mcache_row_bytes_per_channel = %u\n", __func__, *p->mcache_row_bytes_per_channel);
2109 	DML_LOG_VERBOSE("DML::%s: num_mcaches = %u\n", __func__, *p->num_mcaches);
2110 	DML_ASSERT(*p->num_mcaches > 0);
2111 }
2112 
dcn5_calculate_mcache_setting(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_calculate_mcache_setting_params * p)2113 void dcn5_calculate_mcache_setting(
2114 		struct dml2_core_internal_scratch *scratch,
2115 		struct dml2_core_calcs_calculate_mcache_setting_params *p)
2116 {
2117 	unsigned int n;
2118 
2119 	struct dml2_core_shared_calculate_mcache_setting_locals *l = &scratch->calculate_mcache_setting_locals;
2120 	memset(l, 0, sizeof(struct dml2_core_shared_calculate_mcache_setting_locals));
2121 
2122 	*p->num_mcaches_l = 0;
2123 	*p->mcache_row_bytes_l = 0;
2124 	*p->mcache_row_bytes_per_channel_l = 0;
2125 	*p->dcc_dram_bw_nom_overhead_factor_l = 1.0;
2126 	*p->dcc_dram_bw_pref_overhead_factor_l = 1.0;
2127 
2128 	*p->num_mcaches_c = 0;
2129 	*p->mcache_row_bytes_c = 0;
2130 	*p->mcache_row_bytes_per_channel_c = 0;
2131 	*p->dcc_dram_bw_nom_overhead_factor_c = 1.0;
2132 	*p->dcc_dram_bw_pref_overhead_factor_c = 1.0;
2133 
2134 	*p->mall_comb_mcache_l = 0;
2135 	*p->mall_comb_mcache_c = 0;
2136 	*p->lc_comb_mcache = 0;
2137 
2138 	if (!p->dcc_enable)
2139 		return;
2140 
2141 	l->is_dual_plane =  dml2_core_utils_is_420(p->source_format) || dml2_core_utils_is_422_planar(p->source_format) || p->source_format == dml2_rgbe_alpha;
2142 
2143 	l->l_p.num_chans = p->num_chans;
2144 	l->l_p.mem_word_bytes = p->mem_word_bytes;
2145 	l->l_p.mcache_size_bytes = p->mcache_size_bytes;
2146 	l->l_p.mcache_line_size_bytes = p->mcache_line_size_bytes;
2147 	l->l_p.gpuvm_enable = p->gpuvm_enable;
2148 	l->l_p.gpuvm_page_size_kbytes = p->gpuvm_page_size_kbytes;
2149 	l->l_p.surf_vert = p->surf_vert;
2150 	l->l_p.vp_stationary = p->vp_stationary;
2151 	l->l_p.tiling_mode = p->tiling_mode;
2152 	l->l_p.vp_start_x = p->vp_start_x_l;
2153 	l->l_p.vp_start_y = p->vp_start_y_l;
2154 	l->l_p.full_vp_width = p->full_vp_width_l;
2155 	l->l_p.full_vp_height = p->full_vp_height_l;
2156 	l->l_p.blk_width = p->blk_width_l;
2157 	l->l_p.blk_height = p->blk_height_l;
2158 	l->l_p.vmpg_width = p->vmpg_width_l;
2159 	l->l_p.vmpg_height = p->vmpg_height_l;
2160 	l->l_p.full_swath_bytes = p->full_swath_bytes_l;
2161 	l->l_p.bytes_per_pixel = p->bytes_per_pixel_l;
2162 
2163 	// output
2164 	l->l_p.num_mcaches = p->num_mcaches_l;
2165 	l->l_p.mcache_row_bytes = p->mcache_row_bytes_l;
2166 	l->l_p.mcache_row_bytes_per_channel = p->mcache_row_bytes_per_channel_l;
2167 	l->l_p.dcc_dram_bw_nom_overhead_factor = p->dcc_dram_bw_nom_overhead_factor_l;
2168 	l->l_p.dcc_dram_bw_pref_overhead_factor = p->dcc_dram_bw_pref_overhead_factor_l;
2169 	l->l_p.mvmpg_width = &l->mvmpg_width_l;
2170 	l->l_p.mvmpg_height = &l->mvmpg_height_l;
2171 	l->l_p.full_vp_access_width_mvmpg_aligned = &l->full_vp_access_width_mvmpg_aligned_l;
2172 	l->l_p.meta_row_width_ub = &l->meta_row_width_l;
2173 	l->l_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_l;
2174 
2175 	dcn5_calculate_mcache_row_bytes(scratch, &l->l_p);
2176 	DML_ASSERT(*p->num_mcaches_l > 0);
2177 
2178 	if (l->is_dual_plane) {
2179 		l->c_p.num_chans = p->num_chans;
2180 		l->c_p.mem_word_bytes = p->mem_word_bytes;
2181 		l->c_p.mcache_size_bytes = p->mcache_size_bytes;
2182 		l->c_p.mcache_line_size_bytes = p->mcache_line_size_bytes;
2183 		l->c_p.gpuvm_enable = p->gpuvm_enable;
2184 		l->c_p.gpuvm_page_size_kbytes = p->gpuvm_page_size_kbytes;
2185 		l->c_p.surf_vert = p->surf_vert;
2186 		l->c_p.vp_stationary = p->vp_stationary;
2187 		l->c_p.tiling_mode = p->tiling_mode;
2188 		l->c_p.vp_start_x = p->vp_start_x_c;
2189 		l->c_p.vp_start_y = p->vp_start_y_c;
2190 		l->c_p.full_vp_width = p->full_vp_width_c;
2191 		l->c_p.full_vp_height = p->full_vp_height_c;
2192 		l->c_p.blk_width = p->blk_width_c;
2193 		l->c_p.blk_height = p->blk_height_c;
2194 		l->c_p.vmpg_width = p->vmpg_width_c;
2195 		l->c_p.vmpg_height = p->vmpg_height_c;
2196 		l->c_p.full_swath_bytes = p->full_swath_bytes_c;
2197 		l->c_p.bytes_per_pixel = p->bytes_per_pixel_c;
2198 
2199 		// output
2200 		l->c_p.num_mcaches = p->num_mcaches_c;
2201 		l->c_p.mcache_row_bytes = p->mcache_row_bytes_c;
2202 		l->c_p.mcache_row_bytes_per_channel = p->mcache_row_bytes_per_channel_c;
2203 		l->c_p.dcc_dram_bw_nom_overhead_factor = p->dcc_dram_bw_nom_overhead_factor_c;
2204 		l->c_p.dcc_dram_bw_pref_overhead_factor = p->dcc_dram_bw_pref_overhead_factor_c;
2205 		l->c_p.mvmpg_width = &l->mvmpg_width_c;
2206 		l->c_p.mvmpg_height = &l->mvmpg_height_c;
2207 		l->c_p.full_vp_access_width_mvmpg_aligned = &l->full_vp_access_width_mvmpg_aligned_c;
2208 		l->c_p.meta_row_width_ub = &l->meta_row_width_c;
2209 		l->c_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_c;
2210 
2211 		dcn5_calculate_mcache_row_bytes(scratch, &l->c_p);
2212 		DML_ASSERT(*p->num_mcaches_c > 0);
2213 	}
2214 
2215 	// Sharing for iMALL access
2216 	l->mcache_remainder_l = *p->mcache_row_bytes_per_channel_l % p->mcache_size_bytes;
2217 	l->mcache_remainder_c = *p->mcache_row_bytes_per_channel_c % p->mcache_size_bytes;
2218 	l->mvmpg_access_width_l = p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l;
2219 	l->mvmpg_access_width_c = p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c;
2220 
2221 	if (p->imall_enable) {
2222 		*p->mall_comb_mcache_l = (2 * l->mcache_remainder_l <= p->mcache_size_bytes);
2223 
2224 		if (l->is_dual_plane)
2225 			*p->mall_comb_mcache_c = (2 * l->mcache_remainder_c <= p->mcache_size_bytes);
2226 	}
2227 
2228 	if (!p->surf_vert) // horizonatal access
2229 		l->luma_time_factor = (double)l->mvmpg_height_c / l->mvmpg_height_l * 2;
2230 	else // vertical access
2231 		l->luma_time_factor = (double)l->mvmpg_width_c / l->mvmpg_width_l * 2;
2232 
2233 	// The algorithm starts with computing a non-integer, avg_mcache_element_size_l/c:
2234 	l->avg_mcache_element_size_l = l->meta_row_width_l / *p->num_mcaches_l;
2235 	if (l->is_dual_plane) {
2236 		l->avg_mcache_element_size_c = l->meta_row_width_c / *p->num_mcaches_c;
2237 
2238 		/* if either remainder is 0, then mcache sharing is not needed or not possible due to full utilization */
2239 		if (l->mcache_remainder_l && l->mcache_remainder_c) {
2240 			if (!p->imall_enable || (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c)) {
2241 				l->lc_comb_last_mcache_size = (unsigned int)((l->mcache_remainder_l * (*p->mall_comb_mcache_l ? 2 : 1) * l->luma_time_factor) +
2242 					(l->mcache_remainder_c * (*p->mall_comb_mcache_c ? 2 : 1)));
2243 			}
2244 			*p->lc_comb_mcache = (l->lc_comb_last_mcache_size <= p->mcache_size_bytes) && (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c);
2245 		}
2246 	}
2247 
2248 	DML_LOG_VERBOSE("DML::%s: imall_enable = %u\n", __func__, p->imall_enable);
2249 	DML_LOG_VERBOSE("DML::%s: is_dual_plane = %u\n", __func__, l->is_dual_plane);
2250 	DML_LOG_VERBOSE("DML::%s: surf_vert = %u\n", __func__, p->surf_vert);
2251 	DML_LOG_VERBOSE("DML::%s: mvmpg_width_l = %u\n", __func__, l->mvmpg_width_l);
2252 	DML_LOG_VERBOSE("DML::%s: mvmpg_height_l = %u\n", __func__, l->mvmpg_height_l);
2253 	DML_LOG_VERBOSE("DML::%s: mcache_remainder_l = %f\n", __func__, l->mcache_remainder_l);
2254 	DML_LOG_VERBOSE("DML::%s: num_mcaches_l = %u\n", __func__, *p->num_mcaches_l);
2255 	DML_LOG_VERBOSE("DML::%s: avg_mcache_element_size_l = %u\n", __func__, l->avg_mcache_element_size_l);
2256 	DML_LOG_VERBOSE("DML::%s: mvmpg_access_width_l = %u\n", __func__, l->mvmpg_access_width_l);
2257 	DML_LOG_VERBOSE("DML::%s: mall_comb_mcache_l = %u\n", __func__, *p->mall_comb_mcache_l);
2258 
2259 	if (l->is_dual_plane) {
2260 		DML_LOG_VERBOSE("DML::%s: mvmpg_width_c = %u\n", __func__, l->mvmpg_width_c);
2261 		DML_LOG_VERBOSE("DML::%s: mvmpg_height_c = %u\n", __func__, l->mvmpg_height_c);
2262 		DML_LOG_VERBOSE("DML::%s: mcache_remainder_c = %f\n", __func__, l->mcache_remainder_c);
2263 		DML_LOG_VERBOSE("DML::%s: luma_time_factor = %f\n", __func__, l->luma_time_factor);
2264 		DML_LOG_VERBOSE("DML::%s: num_mcaches_c = %u\n", __func__, *p->num_mcaches_c);
2265 		DML_LOG_VERBOSE("DML::%s: avg_mcache_element_size_c = %u\n", __func__, l->avg_mcache_element_size_c);
2266 		DML_LOG_VERBOSE("DML::%s: mvmpg_access_width_c = %u\n", __func__, l->mvmpg_access_width_c);
2267 		DML_LOG_VERBOSE("DML::%s: mall_comb_mcache_c = %u\n", __func__, *p->mall_comb_mcache_c);
2268 		DML_LOG_VERBOSE("DML::%s: lc_comb_last_mcache_size = %u\n", __func__, l->lc_comb_last_mcache_size);
2269 		DML_LOG_VERBOSE("DML::%s: lc_comb_mcache = %u\n", __func__, *p->lc_comb_mcache);
2270 	}
2271 	// calculate split_coordinate
2272 	l->full_vp_access_width_l = p->surf_vert ? p->full_vp_height_l : p->full_vp_width_l;
2273 	l->full_vp_access_width_c = p->surf_vert ? p->full_vp_height_c : p->full_vp_width_c;
2274 
2275 	for (n = 0; n < *p->num_mcaches_l - 1; n++) {
2276 		p->mcache_offsets_l[n] = (unsigned int)(math_floor2((n + 1) * l->avg_mcache_element_size_l / l->mvmpg_access_width_l, 1)) * l->mvmpg_access_width_l;
2277 	}
2278 	p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l;
2279 
2280 	if (l->is_dual_plane) {
2281 		for (n = 0; n < *p->num_mcaches_c - 1; n++) {
2282 			p->mcache_offsets_c[n] = (unsigned int)(math_floor2((n + 1) * l->avg_mcache_element_size_c / l->mvmpg_access_width_c, 1)) * l->mvmpg_access_width_c;
2283 		}
2284 		p->mcache_offsets_c[*p->num_mcaches_c - 1] = l->full_vp_access_width_c;
2285 	}
2286 	for (n = 0; n < *p->num_mcaches_l; n++)
2287 		DML_LOG_VERBOSE("DML::%s: mcache_offsets_l[%u] = %u\n", __func__, n, p->mcache_offsets_l[n]);
2288 
2289 	if (l->is_dual_plane) {
2290 		for (n = 0; n < *p->num_mcaches_c; n++)
2291 			DML_LOG_VERBOSE("DML::%s: mcache_offsets_c[%u] = %u\n", __func__, n, p->mcache_offsets_c[n]);
2292 	}
2293 
2294 	// Luma/Chroma combine in the last mcache
2295 	// In the case of Luma/Chroma combine-mCache (with lc_comb_mcache==1), all mCaches except the last segment are filled as much as possible, when stay aligned to mvmpg boundary
2296 	if (*p->lc_comb_mcache && l->is_dual_plane) {
2297 		for (n = 0; n < *p->num_mcaches_l - 1; n++)
2298 			p->mcache_offsets_l[n] = (n + 1) * l->mvmpg_per_mcache_lb_l * l->mvmpg_access_width_l;
2299 		p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l;
2300 
2301 		for (n = 0; n < *p->num_mcaches_c - 1; n++)
2302 			p->mcache_offsets_c[n] = (n + 1) * l->mvmpg_per_mcache_lb_c * l->mvmpg_access_width_c;
2303 		p->mcache_offsets_c[*p->num_mcaches_c - 1] = l->full_vp_access_width_c;
2304 
2305 		for (n = 0; n < *p->num_mcaches_l; n++)
2306 			DML_LOG_VERBOSE("DML::%s: mcache_offsets_l[%u] = %u\n", __func__, n, p->mcache_offsets_l[n]);
2307 
2308 		for (n = 0; n < *p->num_mcaches_c; n++)
2309 			DML_LOG_VERBOSE("DML::%s: mcache_offsets_c[%u] = %u\n", __func__, n, p->mcache_offsets_c[n]);
2310 	}
2311 
2312 	*p->mcache_shift_granularity_l = l->mvmpg_access_width_l;
2313 	*p->mcache_shift_granularity_c = l->mvmpg_access_width_c;
2314 }
2315 
dcn5_calculate_avg_bandwidth_required(double * avg_bandwidth_required,unsigned int num_active_planes,double ReadBandwidthLuma[],double ReadBandwidthChroma[],double cursor_bw[],double dcc_dram_bw_nom_overhead_factor_p0[],double dcc_dram_bw_nom_overhead_factor_p1[])2316 void dcn5_calculate_avg_bandwidth_required(
2317 		double *avg_bandwidth_required,
2318 		// input
2319 		unsigned int num_active_planes,
2320 		double ReadBandwidthLuma[],
2321 		double ReadBandwidthChroma[],
2322 		double cursor_bw[],
2323 		double dcc_dram_bw_nom_overhead_factor_p0[],
2324 		double dcc_dram_bw_nom_overhead_factor_p1[])
2325 {
2326 	unsigned int k;
2327 	*avg_bandwidth_required = 0;
2328 	for (k = 0; k < num_active_planes; ++k) {
2329 		*avg_bandwidth_required += dcc_dram_bw_nom_overhead_factor_p0[k] * ReadBandwidthLuma[k]
2330 			+ dcc_dram_bw_nom_overhead_factor_p1[k] * ReadBandwidthChroma[k]
2331 			+ cursor_bw[k];
2332 	}
2333 }
2334 
dcn5_calculate_hostvm_inefficiency_factor(double * HostVMInefficiencyFactor,double * HostVMInefficiencyFactorPrefetch,bool gpuvm_enable,bool hostvm_enable,unsigned int remote_iommu_outstanding_translations,unsigned int max_outstanding_reqs,double urg_bandwidth_avail_active_pixel_and_vm,double urg_bandwidth_avail_active_vm_only)2335 void dcn5_calculate_hostvm_inefficiency_factor(
2336 		double *HostVMInefficiencyFactor,
2337 		double *HostVMInefficiencyFactorPrefetch,
2338 
2339 		bool gpuvm_enable,
2340 		bool hostvm_enable,
2341 		unsigned int remote_iommu_outstanding_translations,
2342 		unsigned int max_outstanding_reqs,
2343 		double urg_bandwidth_avail_active_pixel_and_vm,
2344 		double urg_bandwidth_avail_active_vm_only)
2345 {
2346 	*HostVMInefficiencyFactor = 1;
2347 	*HostVMInefficiencyFactorPrefetch = 1;
2348 
2349 	if (gpuvm_enable && hostvm_enable) {
2350 		*HostVMInefficiencyFactor = urg_bandwidth_avail_active_pixel_and_vm / urg_bandwidth_avail_active_vm_only;
2351 		*HostVMInefficiencyFactorPrefetch = *HostVMInefficiencyFactor;
2352 
2353 		if ((*HostVMInefficiencyFactorPrefetch < 4) && (remote_iommu_outstanding_translations < max_outstanding_reqs))
2354 			*HostVMInefficiencyFactorPrefetch = 4;
2355 		DML_LOG_VERBOSE("DML::%s: urg_bandwidth_avail_active_pixel_and_vm = %f\n", __func__, urg_bandwidth_avail_active_pixel_and_vm);
2356 		DML_LOG_VERBOSE("DML::%s: urg_bandwidth_avail_active_vm_only = %f\n", __func__, urg_bandwidth_avail_active_vm_only);
2357 		DML_LOG_VERBOSE("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, *HostVMInefficiencyFactor);
2358 		DML_LOG_VERBOSE("DML::%s: HostVMInefficiencyFactorPrefetch = %f\n", __func__, *HostVMInefficiencyFactorPrefetch);
2359 	}
2360 }
2361 
dcn5_calculate_tdlut_setting(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_calculate_tdlut_setting_params * p)2362 void dcn5_calculate_tdlut_setting(
2363 		struct dml2_core_internal_scratch *scratch,
2364 		struct dml2_core_calcs_calculate_tdlut_setting_params *p)
2365 {
2366 	(void)scratch;
2367 	// locals
2368 	unsigned int tdlut_bpe = 8;
2369 	unsigned int tdlut_width;
2370 	unsigned int tdlut_pitch_bytes;
2371 	unsigned int tdlut_footprint_bytes;
2372 	unsigned int vmpg_bytes;
2373 	unsigned int tdlut_vmpg_per_frame;
2374 	unsigned int tdlut_pte_req_per_frame;
2375 	unsigned int tdlut_bytes_per_line;
2376 	double tdlut_drain_rate;
2377 	unsigned int tdlut_mpc_width;
2378 	unsigned int tdlut_bytes_per_group_simple;
2379 
2380 	if (!p->setup_for_tdlut) {
2381 		*p->tdlut_groups_per_2row_ub = 0;
2382 		*p->tdlut_opt_time = 0;
2383 		*p->tdlut_drain_time = 0;
2384 		*p->tdlut_bytes_per_group = 0;
2385 		*p->tdlut_pte_bytes_per_frame = 0;
2386 		*p->tdlut_bytes_per_frame = 0;
2387 		return;
2388 	}
2389 
2390 	if (p->tdlut_mpc_width_flag) {
2391 		tdlut_mpc_width = 33;
2392 		tdlut_bytes_per_group_simple = 39*256;
2393 	} else {
2394 		tdlut_mpc_width = 17;
2395 		tdlut_bytes_per_group_simple = 10*256;
2396 	}
2397 
2398 	vmpg_bytes = p->gpuvm_page_size_kbytes * 1024;
2399 
2400 	if (p->tdlut_addressing_mode == dml2_tdlut_simple_linear) {
2401 		if (p->tdlut_width_mode == dml2_tdlut_width_17_cube)
2402 			tdlut_width = 4916;
2403 		else
2404 			tdlut_width = 35940;
2405 	} else {
2406 		if (p->tdlut_width_mode == dml2_tdlut_width_17_cube)
2407 			tdlut_width = 17;
2408 		else // dml2_tdlut_width_33_cube
2409 			tdlut_width = 33;
2410 	}
2411 
2412 	if (p->is_gfx11)
2413 		tdlut_pitch_bytes = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 256); //256B alignment
2414 	else
2415 		tdlut_pitch_bytes = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 128); //128B alignment
2416 
2417 	if (p->tdlut_addressing_mode == dml2_tdlut_sw_linear)
2418 		tdlut_footprint_bytes = tdlut_pitch_bytes * tdlut_width * tdlut_width;
2419 	else
2420 		tdlut_footprint_bytes = tdlut_pitch_bytes;
2421 
2422 	if (!p->gpuvm_enable) {
2423 		tdlut_vmpg_per_frame = 0;
2424 		tdlut_pte_req_per_frame = 0;
2425 	} else {
2426 		tdlut_vmpg_per_frame = (unsigned int)math_ceil2(tdlut_footprint_bytes - 1, vmpg_bytes) / vmpg_bytes + 1;
2427 		tdlut_pte_req_per_frame = (unsigned int)math_ceil2(tdlut_vmpg_per_frame - 1, 8) / 8 + 1;
2428 	}
2429 	tdlut_bytes_per_line = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 64); //64b request
2430 	*p->tdlut_pte_bytes_per_frame = tdlut_pte_req_per_frame * 64;
2431 
2432 	if (p->tdlut_addressing_mode == dml2_tdlut_sw_linear) {
2433 		//the tdlut_width is either 17 or 33 but the 33x33x33 is subsampled every other line/slice
2434 		*p->tdlut_bytes_per_frame = tdlut_bytes_per_line * tdlut_mpc_width * tdlut_mpc_width;
2435 		*p->tdlut_bytes_per_group = tdlut_bytes_per_line * tdlut_mpc_width;
2436 		//the delivery cycles is DispClk cycles per line * number of lines * number of slices
2437 		tdlut_drain_rate = tdlut_bytes_per_line * p->dispclk_mhz / math_ceil2(tdlut_mpc_width/2.0, 1);
2438 	} else {
2439 		//tdlut_addressing_mode = tdlut_simple_linear, 3dlut width should be 4*1229=4916 elements
2440 		*p->tdlut_bytes_per_frame = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 256);
2441 		*p->tdlut_bytes_per_group = tdlut_bytes_per_group_simple;
2442 		tdlut_drain_rate = 2 * tdlut_bpe * p->dispclk_mhz;
2443 	}
2444 
2445 	//the tdlut is fetched during the 2 row times of prefetch.
2446 	if (p->setup_for_tdlut) {
2447 		*p->tdlut_groups_per_2row_ub = (unsigned int)math_ceil2((double) *p->tdlut_bytes_per_frame / *p->tdlut_bytes_per_group, 1);
2448 		*p->tdlut_opt_time = (int) (*p->tdlut_bytes_per_frame - p->cursor_buffer_size * 1024) / tdlut_drain_rate;
2449 		*p->tdlut_drain_time = p->cursor_buffer_size * 1024 / tdlut_drain_rate;
2450 	}
2451 
2452 	DML_LOG_VERBOSE("DML::%s: cursor_buffer_size = %d\n", __func__, p->cursor_buffer_size);
2453 	DML_LOG_VERBOSE("DML::%s: gpuvm_enable = %d\n", __func__, p->gpuvm_enable);
2454 	DML_LOG_VERBOSE("DML::%s: vmpg_bytes = %d\n", __func__, vmpg_bytes);
2455 	DML_LOG_VERBOSE("DML::%s: tdlut_vmpg_per_frame = %d\n", __func__, tdlut_vmpg_per_frame);
2456 	DML_LOG_VERBOSE("DML::%s: tdlut_pte_req_per_frame = %d\n", __func__, tdlut_pte_req_per_frame);
2457 
2458 	DML_LOG_VERBOSE("DML::%s: dispclk_mhz = %f\n", __func__, p->dispclk_mhz);
2459 	DML_LOG_VERBOSE("DML::%s: tdlut_width = %u\n", __func__, tdlut_width);
2460 	DML_LOG_VERBOSE("DML::%s: tdlut_addressing_mode = %s\n", __func__, (p->tdlut_addressing_mode == dml2_tdlut_sw_linear) ? "sw_linear" : "simple_linear");
2461 	DML_LOG_VERBOSE("DML::%s: tdlut_pitch_bytes = %u\n", __func__, tdlut_pitch_bytes);
2462 	DML_LOG_VERBOSE("DML::%s: tdlut_footprint_bytes = %u\n", __func__, tdlut_footprint_bytes);
2463 	DML_LOG_VERBOSE("DML::%s: tdlut_bytes_per_frame = %u\n", __func__, *p->tdlut_bytes_per_frame);
2464 	DML_LOG_VERBOSE("DML::%s: tdlut_bytes_per_line = %u\n", __func__, tdlut_bytes_per_line);
2465 	DML_LOG_VERBOSE("DML::%s: tdlut_bytes_per_group = %u\n", __func__, *p->tdlut_bytes_per_group);
2466 	DML_LOG_VERBOSE("DML::%s: tdlut_drain_rate = %f\n", __func__, tdlut_drain_rate);
2467 	DML_LOG_VERBOSE("DML::%s: tdlut_delivery_cycles = %u\n", __func__, p->tdlut_addressing_mode == dml2_tdlut_sw_linear ? (unsigned int)math_ceil2(tdlut_mpc_width/2.0, 1) * tdlut_mpc_width * tdlut_mpc_width : (unsigned int)math_ceil2(tdlut_width/2.0, 1));
2468 	DML_LOG_VERBOSE("DML::%s: tdlut_opt_time = %f\n", __func__, *p->tdlut_opt_time);
2469 	DML_LOG_VERBOSE("DML::%s: tdlut_drain_time = %f\n", __func__, *p->tdlut_drain_time);
2470 	DML_LOG_VERBOSE("DML::%s: tdlut_groups_per_2row_ub = %d\n", __func__, *p->tdlut_groups_per_2row_ub);
2471 }
2472 
dcn5_calculate_tarb(const struct dml2_display_cfg * display_cfg,unsigned int PixelChunkSizeInKByte,unsigned int NumberOfActiveSurfaces,unsigned int NumberOfDPP[],unsigned int dpte_group_bytes[],unsigned int tdlut_bytes_per_group[],double HostVMInefficiencyFactor,double HostVMInefficiencyFactorPrefetch,double ReturnBW,unsigned int MetaChunkSize,double * Tarb,double * Tarb_prefetch)2473 static void dcn5_calculate_tarb(
2474 		const struct dml2_display_cfg *display_cfg,
2475 		unsigned int PixelChunkSizeInKByte,
2476 		unsigned int NumberOfActiveSurfaces,
2477 		unsigned int NumberOfDPP[],
2478 		unsigned int dpte_group_bytes[],
2479 		unsigned int tdlut_bytes_per_group[],
2480 		double HostVMInefficiencyFactor,
2481 		double HostVMInefficiencyFactorPrefetch,
2482 		double ReturnBW,
2483 		unsigned int MetaChunkSize,
2484 
2485 		// output
2486 		double *Tarb,
2487 		double *Tarb_prefetch)
2488 {
2489 	double extra_bytes = 0;
2490 	double extra_bytes_prefetch = 0;
2491 	double HostVMDynamicLevels;
2492 
2493 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
2494 		extra_bytes = extra_bytes + (NumberOfDPP[k] * PixelChunkSizeInKByte * 1024);
2495 
2496 		if (display_cfg->plane_descriptors[k].surface.dcc.enable)
2497 			extra_bytes = extra_bytes + (MetaChunkSize * 1024);
2498 
2499 		if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut)
2500 			extra_bytes = extra_bytes + tdlut_bytes_per_group[k];
2501 	}
2502 
2503 	extra_bytes_prefetch = extra_bytes;
2504 
2505 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
2506 		HostVMDynamicLevels = dcn5_calculate_host_vm_dynamic_levels(display_cfg->gpuvm_enable, display_cfg->hostvm_enable, display_cfg->plane_descriptors[k].overrides.hostvm_min_page_size_kbytes, display_cfg->hostvm_max_non_cached_page_table_levels);
2507 
2508 		if (display_cfg->gpuvm_enable == true) {
2509 			extra_bytes = extra_bytes + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor;
2510 			extra_bytes_prefetch = extra_bytes_prefetch + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactorPrefetch;
2511 		}
2512 	}
2513 	*Tarb = extra_bytes / ReturnBW;
2514 	*Tarb_prefetch = extra_bytes_prefetch / ReturnBW;
2515 	DML_LOG_VERBOSE("DML::%s: PixelChunkSizeInKByte = %d\n", __func__, PixelChunkSizeInKByte);
2516 	DML_LOG_VERBOSE("DML::%s: MetaChunkSize = %d\n", __func__, MetaChunkSize);
2517 	DML_LOG_VERBOSE("DML::%s: extra_bytes = %f\n", __func__, extra_bytes);
2518 	DML_LOG_VERBOSE("DML::%s: extra_bytes_prefetch = %f\n", __func__, extra_bytes_prefetch);
2519 }
2520 
dcn5_calculate_extra_latency(const struct dml2_display_cfg * display_cfg,unsigned int ROBBufferSizeInKByte,unsigned int RoundTripPingLatencyCycles,unsigned int ReorderingBytes,double DCFCLK,double FabricClock,unsigned int PixelChunkSizeInKByte,double ReturnBW,unsigned int NumberOfActiveSurfaces,unsigned int NumberOfDPP[],unsigned int dpte_group_bytes[],unsigned int tdlut_bytes_per_group[],double HostVMInefficiencyFactor,double HostVMInefficiencyFactorPrefetch,enum dml2_qos_param_type qos_type,bool max_outstanding_when_urgent_expected,unsigned int max_outstanding_requests,unsigned int request_size_bytes_luma[],unsigned int request_size_bytes_chroma[],unsigned int MetaChunkSize,unsigned int dchub_arb_to_ret_delay,double Ttrip,unsigned int hostvm_mode,double * ExtraLatency,double * ExtraLatency_sr,double * ExtraLatencyPrefetch)2521 void dcn5_calculate_extra_latency(
2522 		const struct dml2_display_cfg *display_cfg,
2523 		unsigned int ROBBufferSizeInKByte,
2524 		unsigned int RoundTripPingLatencyCycles,
2525 		unsigned int ReorderingBytes,
2526 		double DCFCLK,
2527 		double FabricClock,
2528 		unsigned int PixelChunkSizeInKByte,
2529 		double ReturnBW,
2530 		unsigned int NumberOfActiveSurfaces,
2531 		unsigned int NumberOfDPP[],
2532 		unsigned int dpte_group_bytes[],
2533 		unsigned int tdlut_bytes_per_group[],
2534 		double HostVMInefficiencyFactor,
2535 		double HostVMInefficiencyFactorPrefetch,
2536 		enum dml2_qos_param_type qos_type,
2537 		bool max_outstanding_when_urgent_expected,
2538 		unsigned int max_outstanding_requests,
2539 		unsigned int request_size_bytes_luma[],
2540 		unsigned int request_size_bytes_chroma[],
2541 		unsigned int MetaChunkSize,
2542 		unsigned int dchub_arb_to_ret_delay,
2543 		double Ttrip,
2544 		unsigned int hostvm_mode,
2545 
2546 		// output
2547 		double *ExtraLatency, // Tex
2548 		double *ExtraLatency_sr, // Tex_sr
2549 		double *ExtraLatencyPrefetch)
2550 
2551 {
2552 	double Tarb;
2553 	double Tarb_prefetch;
2554 	double Tex_trips;
2555 	unsigned int max_request_size_bytes = 0;
2556 
2557 	dcn5_calculate_tarb(
2558 			display_cfg,
2559 			PixelChunkSizeInKByte,
2560 			NumberOfActiveSurfaces,
2561 			NumberOfDPP,
2562 			dpte_group_bytes,
2563 			tdlut_bytes_per_group,
2564 			HostVMInefficiencyFactor,
2565 			HostVMInefficiencyFactorPrefetch,
2566 			ReturnBW,
2567 			MetaChunkSize,
2568 			// output
2569 			&Tarb,
2570 			&Tarb_prefetch);
2571 
2572 	Tex_trips = (display_cfg->hostvm_enable && hostvm_mode == 1) ? (2.0 * Ttrip) : 0.0;
2573 
2574 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
2575 		if (request_size_bytes_luma[k] > max_request_size_bytes)
2576 			max_request_size_bytes = request_size_bytes_luma[k];
2577 		if (request_size_bytes_chroma[k] > max_request_size_bytes)
2578 			max_request_size_bytes = request_size_bytes_chroma[k];
2579 	}
2580 
2581 	if (qos_type == dml2_qos_param_type_dcn4x) {
2582 		*ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK;
2583 		*ExtraLatency = *ExtraLatency_sr;
2584 		if (max_outstanding_when_urgent_expected)
2585 			*ExtraLatency = *ExtraLatency + (ROBBufferSizeInKByte * 1024 - max_outstanding_requests * max_request_size_bytes) / ReturnBW;
2586 	} else {
2587 		*ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK + RoundTripPingLatencyCycles / FabricClock + ReorderingBytes / ReturnBW;
2588 		*ExtraLatency = *ExtraLatency_sr;
2589 	}
2590 	*ExtraLatency = *ExtraLatency + Tex_trips;
2591 	*ExtraLatencyPrefetch = *ExtraLatency + Tarb_prefetch;
2592 	*ExtraLatency = *ExtraLatency + Tarb;
2593 	*ExtraLatency_sr = *ExtraLatency_sr + Tarb;
2594 
2595 	DML_LOG_VERBOSE("DML::%s: qos_type=%u\n", __func__, qos_type);
2596 	DML_LOG_VERBOSE("DML::%s: hostvm_mode=%u\n", __func__, hostvm_mode);
2597 	DML_LOG_VERBOSE("DML::%s: Tex_trips=%f\n", __func__, Tex_trips);
2598 	DML_LOG_VERBOSE("DML::%s: DCFCLK=%f\n", __func__, DCFCLK);
2599 	DML_LOG_VERBOSE("DML::%s: ReturnBW=%f\n", __func__, ReturnBW);
2600 	if (qos_type == dml2_qos_param_type_dcn4x) {
2601 		DML_LOG_VERBOSE("DML::%s: max_outstanding_when_urgent_expected=%u\n", __func__, max_outstanding_when_urgent_expected);
2602 		DML_LOG_VERBOSE("DML::%s: max_outstanding_requests=%u\n", __func__, max_outstanding_requests);
2603 		DML_LOG_VERBOSE("DML::%s: max_request_size_bytes=%u\n", __func__, max_request_size_bytes);
2604 		DML_LOG_VERBOSE("DML::%s: ROBBufferSizeInKByte=%u\n", __func__, ROBBufferSizeInKByte);
2605 	} else {
2606 		DML_LOG_VERBOSE("DML::%s: FabricClock=%f\n", __func__, FabricClock);
2607 		DML_LOG_VERBOSE("DML::%s: RoundTripPingLatencyCycles=%u\n", __func__, RoundTripPingLatencyCycles);
2608 		DML_LOG_VERBOSE("DML::%s: ReorderingBytes=%u\n", __func__, ReorderingBytes);
2609 	}
2610 	DML_LOG_VERBOSE("DML::%s: Tarb=%f\n", __func__, Tarb);
2611 	DML_LOG_VERBOSE("DML::%s: ExtraLatency=%f\n", __func__, *ExtraLatency);
2612 	DML_LOG_VERBOSE("DML::%s: ExtraLatency_sr=%f\n", __func__, *ExtraLatency_sr);
2613 	DML_LOG_VERBOSE("DML::%s: ExtraLatencyPrefetch=%f\n", __func__, *ExtraLatencyPrefetch);
2614 }
2615 
dcn5_calculate_t_wait(long reserved_vblank_time_ns,double UrgentLatency,double Ttrip,double temp_read_or_ppt_blackout_us,bool drr_enabled)2616 double dcn5_calculate_t_wait(
2617 		long reserved_vblank_time_ns,
2618 		double UrgentLatency,
2619 		double Ttrip,
2620 		double temp_read_or_ppt_blackout_us,
2621 		bool drr_enabled
2622 	)
2623 {
2624 	double TWait;
2625 	double t_urg_trip = math_max2(UrgentLatency, Ttrip);
2626 	TWait = math_max2(reserved_vblank_time_ns / 1000.0, drr_enabled ? temp_read_or_ppt_blackout_us : 0.0) + t_urg_trip;
2627 
2628 	DML_LOG_VERBOSE("DML::%s: reserved_vblank_time_ns = %ld\n", __func__, reserved_vblank_time_ns);
2629 	DML_LOG_VERBOSE("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency);
2630 	DML_LOG_VERBOSE("DML::%s: Ttrip = %f\n", __func__, Ttrip);
2631 	DML_LOG_VERBOSE("DML::%s: TWait = %f\n", __func__, TWait);
2632 	return TWait;
2633 }
2634 
dcn5_calculate_v_update_and_dynamic_metadata_parameters(unsigned int MaxInterDCNTileRepeaters,double Dppclk,double Dispclk,double DCFClkDeepSleep,double PixelClock,unsigned int HTotal,unsigned int VBlank,unsigned int DynamicMetadataTransmittedBytes,unsigned int DynamicMetadataLinesBeforeActiveRequired,unsigned int InterlaceEnable,bool ProgressiveToInterlaceUnitInOPP,double * TSetup,double * Tdmbf,double * Tdmec,double * Tdmsks,unsigned int * VUpdateOffsetPix,unsigned int * VUpdateWidthPix,unsigned int * VReadyOffsetPix)2635 static void dcn5_calculate_v_update_and_dynamic_metadata_parameters(
2636 		unsigned int MaxInterDCNTileRepeaters,
2637 		double Dppclk,
2638 		double Dispclk,
2639 		double DCFClkDeepSleep,
2640 		double PixelClock,
2641 		unsigned int HTotal,
2642 		unsigned int VBlank,
2643 		unsigned int DynamicMetadataTransmittedBytes,
2644 		unsigned int DynamicMetadataLinesBeforeActiveRequired,
2645 		unsigned int InterlaceEnable,
2646 		bool ProgressiveToInterlaceUnitInOPP,
2647 
2648 		// Output
2649 		double *TSetup,
2650 		double *Tdmbf,
2651 		double *Tdmec,
2652 		double *Tdmsks,
2653 		unsigned int *VUpdateOffsetPix,
2654 		unsigned int *VUpdateWidthPix,
2655 		unsigned int *VReadyOffsetPix)
2656 {
2657 	double TotalRepeaterDelayTime;
2658 	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / Dppclk + 3 / Dispclk);
2659 	*VUpdateWidthPix = (unsigned int)(math_ceil2((14.0 / DCFClkDeepSleep + 12.0 / Dppclk + TotalRepeaterDelayTime) * PixelClock, 1.0));
2660 	*VReadyOffsetPix = (unsigned int)(math_ceil2(math_max2(150.0 / Dppclk, TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / Dppclk) * PixelClock, 1.0));
2661 	*VUpdateOffsetPix = (unsigned int)(math_ceil2(HTotal / 4.0, 1.0));
2662 	*TSetup = (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
2663 	*Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / Dispclk;
2664 	*Tdmec = HTotal / PixelClock;
2665 
2666 	if (DynamicMetadataLinesBeforeActiveRequired == 0) {
2667 		*Tdmsks = VBlank * HTotal / PixelClock / 2.0;
2668 	} else {
2669 		*Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock;
2670 	}
2671 	if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) {
2672 		*Tdmsks = *Tdmsks / 2;
2673 	}
2674 	DML_LOG_VERBOSE("DML::%s: DynamicMetadataLinesBeforeActiveRequired = %u\n", __func__, DynamicMetadataLinesBeforeActiveRequired);
2675 	DML_LOG_VERBOSE("DML::%s: VBlank = %u\n", __func__, VBlank);
2676 	DML_LOG_VERBOSE("DML::%s: HTotal = %u\n", __func__, HTotal);
2677 	DML_LOG_VERBOSE("DML::%s: PixelClock = %f\n", __func__, PixelClock);
2678 	DML_LOG_VERBOSE("DML::%s: Dppclk = %f\n", __func__, Dppclk);
2679 	DML_LOG_VERBOSE("DML::%s: DCFClkDeepSleep = %f\n", __func__, DCFClkDeepSleep);
2680 	DML_LOG_VERBOSE("DML::%s: MaxInterDCNTileRepeaters = %u\n", __func__, MaxInterDCNTileRepeaters);
2681 	DML_LOG_VERBOSE("DML::%s: TotalRepeaterDelayTime = %f\n", __func__, TotalRepeaterDelayTime);
2682 	DML_LOG_VERBOSE("DML::%s: VUpdateWidthPix = %u\n", __func__, *VUpdateWidthPix);
2683 	DML_LOG_VERBOSE("DML::%s: VReadyOffsetPix = %u\n", __func__, *VReadyOffsetPix);
2684 	DML_LOG_VERBOSE("DML::%s: VUpdateOffsetPix = %u\n", __func__, *VUpdateOffsetPix);
2685 	DML_LOG_VERBOSE("DML::%s: Tdmsks = %f\n", __func__, *Tdmsks);
2686 }
2687 
dcn5_calculate_prefetch_schedule(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_CalculatePrefetchSchedule_params * p)2688 bool dcn5_calculate_prefetch_schedule(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_CalculatePrefetchSchedule_params *p)
2689 {
2690 	struct dml2_core_calcs_CalculatePrefetchSchedule_locals *s = &scratch->CalculatePrefetchSchedule_locals;
2691 	bool dcc_mrq_enable;
2692 
2693 	unsigned int vm_bytes;
2694 	unsigned int extra_tdpe_bytes;
2695 	unsigned int tdlut_row_bytes;
2696 	unsigned int Lo;
2697 	unsigned int cnvc_delay_subtotal;
2698 
2699 	s->NoTimeToPrefetch = false;
2700 	s->DPPCycles = 0;
2701 	s->DISPCLKCycles = 0;
2702 	s->DSTTotalPixelsAfterScaler = 0.0;
2703 	s->LineTime = 0.0;
2704 	s->dst_y_prefetch_equ = 0.0;
2705 	s->prefetch_bw_oto = 0.0;
2706 	s->Tvm_oto = 0.0;
2707 	s->Tr0_oto = 0.0;
2708 	s->Tvm_oto_lines = 0.0;
2709 	s->Tr0_oto_lines = 0.0;
2710 	s->dst_y_prefetch_oto = 0.0;
2711 	s->TimeForFetchingVM = 0.0;
2712 	s->TimeForFetchingRowInVBlank = 0.0;
2713 	s->LinesToRequestPrefetchPixelData = 0.0;
2714 	s->HostVMDynamicLevelsTrips = 0;
2715 	s->trip_to_mem = 0.0;
2716 	*p->Tvm_trips = 0.0;
2717 	*p->Tr0_trips = 0.0;
2718 	s->Tvm_trips_rounded = 0.0;
2719 	s->Tr0_trips_rounded = 0.0;
2720 	s->max_Tsw = 0.0;
2721 	s->Lsw_oto = 0.0;
2722 	*p->Tpre_rounded = 0.0;
2723 	s->prefetch_bw_equ = 0.0;
2724 	s->Tvm_equ = 0.0;
2725 	s->Tr0_equ = 0.0;
2726 	s->Tdmbf = 0.0;
2727 	s->Tdmec = 0.0;
2728 	s->Tdmsks = 0.0;
2729 	*p->prefetch_sw_bytes = 0.0;
2730 	s->prefetch_bw_pr = 0.0;
2731 	s->bytes_pp = 0.0;
2732 	s->dep_bytes = 0.0;
2733 	s->min_Lsw_oto = 0.0;
2734 	s->min_Lsw_equ = 0.0;
2735 	s->Tsw_est1 = 0.0;
2736 	s->Tsw_est2 = 0.0;
2737 	s->Tsw_est3 = 0.0;
2738 	s->cursor_prefetch_bytes = 0;
2739 	*p->prefetch_cursor_bw = 0;
2740 
2741 	dcc_mrq_enable = (p->dcc_enable && p->mrq_present);
2742 
2743 	s->TWait_p = p->TWait - p->Ttrip; // TWait includes max(Turg, Ttrip) and Ttrip here is already max(Turg, Ttrip)
2744 
2745 	if (p->display_cfg->gpuvm_enable == true && p->display_cfg->hostvm_enable == true) {
2746 		s->HostVMDynamicLevelsTrips = p->display_cfg->hostvm_max_non_cached_page_table_levels;
2747 	} else {
2748 		s->HostVMDynamicLevelsTrips = 0;
2749 	}
2750 	DML_LOG_VERBOSE("DML::%s: dcc_enable = %u\n", __func__, p->dcc_enable);
2751 	DML_LOG_VERBOSE("DML::%s: mrq_present = %u\n", __func__, p->mrq_present);
2752 	DML_LOG_VERBOSE("DML::%s: dcc_mrq_enable = %u\n", __func__, dcc_mrq_enable);
2753 	DML_LOG_VERBOSE("DML::%s: GPUVMEnable = %u\n", __func__, p->display_cfg->gpuvm_enable);
2754 	DML_LOG_VERBOSE("DML::%s: GPUVMPageTableLevels = %u\n", __func__, p->display_cfg->gpuvm_max_page_table_levels);
2755 	DML_LOG_VERBOSE("DML::%s: DCCEnable = %u\n", __func__, p->myPipe->DCCEnable);
2756 	DML_LOG_VERBOSE("DML::%s: VStartup = %u\n", __func__, p->VStartup);
2757 	DML_LOG_VERBOSE("DML::%s: HostVMEnable = %u\n", __func__, p->display_cfg->hostvm_enable);
2758 	DML_LOG_VERBOSE("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
2759 	DML_LOG_VERBOSE("DML::%s: TWait = %f\n", __func__, p->TWait);
2760 	DML_LOG_VERBOSE("DML::%s: TWait_p = %f\n", __func__, s->TWait_p);
2761 	DML_LOG_VERBOSE("DML::%s: Ttrip = %f\n", __func__, p->Ttrip);
2762 	DML_LOG_VERBOSE("DML::%s: myPipe->Dppclk = %f\n", __func__, p->myPipe->Dppclk);
2763 	DML_LOG_VERBOSE("DML::%s: myPipe->Dispclk = %f\n", __func__, p->myPipe->Dispclk);
2764 	dcn5_calculate_v_update_and_dynamic_metadata_parameters(
2765 			p->MaxInterDCNTileRepeaters,
2766 			p->myPipe->Dppclk,
2767 			p->myPipe->Dispclk,
2768 			p->myPipe->DCFClkDeepSleep,
2769 			p->myPipe->PixelClock,
2770 			p->myPipe->HTotal,
2771 			p->myPipe->VBlank,
2772 			p->DynamicMetadataTransmittedBytes,
2773 			p->DynamicMetadataLinesBeforeActiveRequired,
2774 			p->myPipe->InterlaceEnable,
2775 			p->myPipe->ProgressiveToInterlaceUnitInOPP,
2776 			p->TSetup,
2777 
2778 			// Output
2779 			&s->Tdmbf,
2780 			&s->Tdmec,
2781 			&s->Tdmsks,
2782 			p->VUpdateOffsetPix,
2783 			p->VUpdateWidthPix,
2784 			p->VReadyOffsetPix);
2785 
2786 	s->LineTime = p->myPipe->HTotal / p->myPipe->PixelClock;
2787 	s->trip_to_mem = p->Ttrip;
2788 	*p->Tvm_trips = p->ExtraLatencyPrefetch + math_max2(s->trip_to_mem * (p->display_cfg->gpuvm_max_page_table_levels * (s->HostVMDynamicLevelsTrips + 1)), p->Turg);
2789 	if (dcc_mrq_enable)
2790 		*p->Tvm_trips_flip = *p->Tvm_trips;
2791 	else
2792 		*p->Tvm_trips_flip = *p->Tvm_trips - s->trip_to_mem;
2793 
2794 	*p->Tr0_trips_flip = s->trip_to_mem * (s->HostVMDynamicLevelsTrips + 1);
2795 	*p->Tr0_trips = math_max2(*p->Tr0_trips_flip, p->tdlut_opt_time / 2);
2796 
2797 	if (p->DynamicMetadataVMEnabled == true) {
2798 		*p->Tdmdl_vm = s->TWait_p + *p->Tvm_trips;
2799 		*p->Tdmdl = *p->Tdmdl_vm + p->Ttrip;
2800 	} else {
2801 		*p->Tdmdl_vm = 0;
2802 		*p->Tdmdl = s->TWait_p + p->ExtraLatencyPrefetch + p->Ttrip; // Tex
2803 	}
2804 
2805 	if (p->DynamicMetadataEnable == true) {
2806 		if (p->VStartup * s->LineTime < *p->TSetup + *p->Tdmdl + s->Tdmbf + s->Tdmec + s->Tdmsks) {
2807 			*p->NotEnoughTimeForDynamicMetadata = true;
2808 			DML_LOG_VERBOSE("DML::%s: Not Enough Time for Dynamic Meta!\n", __func__);
2809 			DML_LOG_VERBOSE("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, s->Tdmbf);
2810 			DML_LOG_VERBOSE("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, s->Tdmec);
2811 			DML_LOG_VERBOSE("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, s->Tdmsks);
2812 			DML_LOG_VERBOSE("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *p->Tdmdl);
2813 		} else {
2814 			*p->NotEnoughTimeForDynamicMetadata = false;
2815 		}
2816 	} else {
2817 		*p->NotEnoughTimeForDynamicMetadata = false;
2818 	}
2819 
2820 	cnvc_delay_subtotal = (unsigned int)(p->DPPCLKDelaySubtotalPlusCNVCFormater);
2821 	if (p->display_cfg->plane_descriptors->composition.scaler_info.upsp_enabled && dml2_core_utils_is_420(p->display_cfg->plane_descriptors->pixel_format))
2822 		cnvc_delay_subtotal += 15;
2823 	if (p->display_cfg->plane_descriptors->composition.scaler_info.upsp_enabled &&
2824 		(dml2_core_utils_is_422_planar(p->display_cfg->plane_descriptors->pixel_format) || dml2_core_utils_is_422_packed(p->display_cfg->plane_descriptors->pixel_format)))
2825 		cnvc_delay_subtotal += 6;
2826 
2827 	if (!p->myPipe->ScalerEnabled)
2828 		s->DPPCycles = cnvc_delay_subtotal + (unsigned int)(p->DPPCLKDelaySCLLBOnly);
2829 	else if (!p->display_cfg->plane_descriptors->composition.scaler_info.easf_enabled && !p->display_cfg->plane_descriptors->composition.scaler_info.isharp_enabled)
2830 		s->DPPCycles = cnvc_delay_subtotal + (unsigned int)(p->DPPCLKDelaySCL);
2831 	else if (p->display_cfg->plane_descriptors->composition.scaler_info.easf_enabled && p->display_cfg->plane_descriptors->composition.scaler_info.isharp_enabled)
2832 		s->DPPCycles = cnvc_delay_subtotal + 100;
2833 	else // easf only
2834 		s->DPPCycles = cnvc_delay_subtotal + 80;
2835 
2836 	s->DPPCycles = (unsigned int)(s->DPPCycles + p->myPipe->NumberOfCursors * p->DPPCLKDelayCNVCCursor);
2837 
2838 	s->DISPCLKCycles = (unsigned int)p->DISPCLKDelaySubtotal;
2839 
2840 	if (p->display_cfg->plane_descriptors->tdlut.setup_for_tdlut && p->display_cfg->plane_descriptors->tdlut.tdlut_width_mode == dml2_tdlut_width_33_cube)
2841 		s->DISPCLKCycles += 34;
2842 
2843 	s->DISPCLKCycles += (p->myPipe->ODMMode != dml2_odm_mode_bypass ? 18 : 0);
2844 
2845 	if (p->myPipe->Dppclk == 0.0 || p->myPipe->Dispclk == 0.0)
2846 		return true;
2847 
2848 	*p->DSTXAfterScaler = (unsigned int)math_round(s->DPPCycles * p->myPipe->PixelClock / p->myPipe->Dppclk + s->DISPCLKCycles * p->myPipe->PixelClock / p->myPipe->Dispclk + p->DSCDelay);
2849 
2850 	if (p->myPipe->ODMMode == dml2_odm_mode_split_1to2 || p->myPipe->ODMMode == dml2_odm_mode_mso_1to2)
2851 		*p->DSTXAfterScaler += p->myPipe->HActive / 2;
2852 	else if (p->myPipe->ODMMode == dml2_odm_mode_mso_1to4)
2853 		*p->DSTXAfterScaler += (p->myPipe->HActive * 3) / 4;
2854 	else
2855 		*p->DSTXAfterScaler += (p->myPipe->DPPPerSurface - 1) * p->DPP_RECOUT_WIDTH;
2856 
2857 	DML_LOG_VERBOSE("DML::%s: DynamicMetadataVMEnabled = %u\n", __func__, p->DynamicMetadataVMEnabled);
2858 	DML_LOG_VERBOSE("DML::%s: DPPCycles = %u\n", __func__, s->DPPCycles);
2859 	DML_LOG_VERBOSE("DML::%s: PixelClock = %f\n", __func__, p->myPipe->PixelClock);
2860 	DML_LOG_VERBOSE("DML::%s: Dppclk = %f\n", __func__, p->myPipe->Dppclk);
2861 	DML_LOG_VERBOSE("DML::%s: DISPCLKCycles = %u\n", __func__, s->DISPCLKCycles);
2862 	DML_LOG_VERBOSE("DML::%s: DISPCLK = %f\n", __func__, p->myPipe->Dispclk);
2863 	DML_LOG_VERBOSE("DML::%s: DSCDelay = %u\n", __func__, p->DSCDelay);
2864 	DML_LOG_VERBOSE("DML::%s: ODMMode = %u\n", __func__, p->myPipe->ODMMode);
2865 	DML_LOG_VERBOSE("DML::%s: DPP_RECOUT_WIDTH = %u\n", __func__, p->DPP_RECOUT_WIDTH);
2866 	DML_LOG_VERBOSE("DML::%s: DSTXAfterScaler = %u\n", __func__, *p->DSTXAfterScaler);
2867 
2868 	DML_LOG_VERBOSE("DML::%s: setup_for_tdlut = %u\n", __func__, p->setup_for_tdlut);
2869 	DML_LOG_VERBOSE("DML::%s: tdlut_opt_time = %f\n", __func__, p->tdlut_opt_time);
2870 	DML_LOG_VERBOSE("DML::%s: tdlut_pte_bytes_per_frame = %u\n", __func__, p->tdlut_pte_bytes_per_frame);
2871 
2872 	if (p->OutputFormat == dml2_420 || (p->myPipe->InterlaceEnable && p->myPipe->ProgressiveToInterlaceUnitInOPP))
2873 		*p->DSTYAfterScaler = 1;
2874 	else
2875 		*p->DSTYAfterScaler = 0;
2876 
2877 	s->DSTTotalPixelsAfterScaler = *p->DSTYAfterScaler * p->myPipe->HTotal + *p->DSTXAfterScaler;
2878 	*p->DSTYAfterScaler = (unsigned int)(math_floor2(s->DSTTotalPixelsAfterScaler / p->myPipe->HTotal, 1));
2879 	*p->DSTXAfterScaler = (unsigned int)(s->DSTTotalPixelsAfterScaler - ((double)(*p->DSTYAfterScaler * p->myPipe->HTotal)));
2880 	DML_LOG_VERBOSE("DML::%s: DSTXAfterScaler = %u (final)\n", __func__, *p->DSTXAfterScaler);
2881 	DML_LOG_VERBOSE("DML::%s: DSTYAfterScaler = %u (final)\n", __func__, *p->DSTYAfterScaler);
2882 
2883 	s->NoTimeToPrefetch = false;
2884 	DML_LOG_VERBOSE("DML::%s: Tr0_trips = %f\n", __func__, *p->Tr0_trips);
2885 	DML_LOG_VERBOSE("DML::%s: Tvm_trips = %f\n", __func__, *p->Tvm_trips);
2886 	DML_LOG_VERBOSE("DML::%s: trip_to_mem = %f\n", __func__, s->trip_to_mem);
2887 	DML_LOG_VERBOSE("DML::%s: ExtraLatencyPrefetch = %f\n", __func__, p->ExtraLatencyPrefetch);
2888 	DML_LOG_VERBOSE("DML::%s: GPUVMPageTableLevels = %u\n", __func__, p->display_cfg->gpuvm_max_page_table_levels);
2889 	DML_LOG_VERBOSE("DML::%s: HostVMDynamicLevelsTrips = %u\n", __func__, s->HostVMDynamicLevelsTrips);
2890 	if (p->display_cfg->gpuvm_enable) {
2891 		s->Tvm_trips_rounded = math_ceil2(4.0 * *p->Tvm_trips / s->LineTime, 1.0) / 4.0 * s->LineTime;
2892 		*p->Tvm_trips_flip_rounded = math_ceil2(4.0 * *p->Tvm_trips_flip / s->LineTime, 1.0) / 4.0 * s->LineTime;
2893 	} else {
2894 		if (p->DynamicMetadataEnable || dcc_mrq_enable || p->setup_for_tdlut)
2895 			s->Tvm_trips_rounded = math_max2(s->LineTime * math_ceil2(4.0*math_max3(p->ExtraLatencyPrefetch, p->Turg, s->trip_to_mem)/s->LineTime, 1)/4, s->LineTime/4.0);
2896 		else
2897 			s->Tvm_trips_rounded = s->LineTime / 4.0;
2898 		*p->Tvm_trips_flip_rounded = s->LineTime / 4.0;
2899 	}
2900 
2901 	s->Tvm_trips_rounded = math_max2(s->Tvm_trips_rounded, s->LineTime / 4.0);
2902 	*p->Tvm_trips_flip_rounded = math_max2(*p->Tvm_trips_flip_rounded, s->LineTime / 4.0);
2903 
2904 	if (p->display_cfg->gpuvm_enable == true || p->setup_for_tdlut || dcc_mrq_enable) {
2905 		s->Tr0_trips_rounded = math_ceil2(4.0 * *p->Tr0_trips / s->LineTime, 1.0) / 4.0 * s->LineTime;
2906 		*p->Tr0_trips_flip_rounded = math_ceil2(4.0 * *p->Tr0_trips_flip / s->LineTime, 1.0) / 4.0 * s->LineTime;
2907 	} else {
2908 		s->Tr0_trips_rounded = s->LineTime / 4.0;
2909 		*p->Tr0_trips_flip_rounded = s->LineTime / 4.0;
2910 	}
2911 	s->Tr0_trips_rounded = math_max2(s->Tr0_trips_rounded, s->LineTime / 4.0);
2912 	*p->Tr0_trips_flip_rounded = math_max2(*p->Tr0_trips_flip_rounded, s->LineTime / 4.0);
2913 
2914 	if (p->display_cfg->gpuvm_enable == true) {
2915 		if (p->display_cfg->gpuvm_max_page_table_levels >= 3) {
2916 			*p->Tno_bw = p->ExtraLatencyPrefetch + s->trip_to_mem * (double)((p->display_cfg->gpuvm_max_page_table_levels - 2) * (s->HostVMDynamicLevelsTrips + 1));
2917 		} else if (p->display_cfg->gpuvm_max_page_table_levels == 1 && !dcc_mrq_enable && !p->setup_for_tdlut) {
2918 			*p->Tno_bw = p->ExtraLatencyPrefetch;
2919 		} else {
2920 			*p->Tno_bw = 0;
2921 		}
2922 	} else {
2923 		*p->Tno_bw = 0;
2924 	}
2925 
2926 	if (p->mrq_present || p->display_cfg->gpuvm_max_page_table_levels >= 3)
2927 		*p->Tno_bw_flip = *p->Tno_bw;
2928 	else
2929 		*p->Tno_bw_flip = 0; //because there is no 3DLUT for iFlip
2930 
2931 	if (dml2_core_utils_is_420(p->myPipe->SourcePixelFormat)) {
2932 		s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC / 4.0;
2933 	} else if (dml2_core_utils_is_422_planar(p->myPipe->SourcePixelFormat)) {
2934 		s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC / 2.0;
2935 	} else {
2936 		s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC;
2937 	}
2938 
2939 	s->prefetch_bw_pr = s->bytes_pp * p->myPipe->PixelClock / (double)p->myPipe->DPPPerSurface;
2940 	if (p->myPipe->VRatio < 1.0)
2941 		s->prefetch_bw_pr = p->myPipe->VRatio * s->prefetch_bw_pr;
2942 	s->max_Tsw = (math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) * s->LineTime);
2943 
2944 	*p->prefetch_sw_bytes = p->PrefetchSourceLinesY * p->swath_width_luma_ub * p->myPipe->BytePerPixelY + p->PrefetchSourceLinesC * p->swath_width_chroma_ub * p->myPipe->BytePerPixelC;
2945 	s->prefetch_bw_pr = s->prefetch_bw_pr;
2946 	*p->prefetch_sw_bytes = *p->prefetch_sw_bytes;
2947 	s->prefetch_bw_oto = math_max2(s->prefetch_bw_pr, *p->prefetch_sw_bytes / s->max_Tsw);
2948 
2949 	s->min_Lsw_oto = math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) / __DML2_CALCS_MAX_VRATIO_PRE_OTO__;
2950 	s->min_Lsw_oto = math_max2(s->min_Lsw_oto, 2.0);
2951 	s->min_Lsw_oto = math_max2(s->min_Lsw_oto, p->tdlut_drain_time / s->LineTime);
2952 
2953 	s->min_Lsw_equ = math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) / __DML2_CALCS_MAX_VRATIO_PRE_EQU__;
2954 	s->min_Lsw_equ = math_max2(s->min_Lsw_equ, 2.0);
2955 	s->min_Lsw_equ = math_max2(s->min_Lsw_equ, p->tdlut_drain_time / s->LineTime);
2956 
2957 	vm_bytes = p->vm_bytes; // vm_bytes is dpde0_bytes_per_frame_ub_l + dpde0_bytes_per_frame_ub_c + 2*extra_dpde_bytes;
2958 	extra_tdpe_bytes = (unsigned int)math_max2(0, (p->display_cfg->gpuvm_max_page_table_levels - 1) * 128);
2959 
2960 	if (p->setup_for_tdlut)
2961 		vm_bytes = vm_bytes + p->tdlut_pte_bytes_per_frame + (p->display_cfg->gpuvm_enable ? extra_tdpe_bytes : 0);
2962 
2963 	tdlut_row_bytes = (unsigned long) math_ceil2(p->tdlut_bytes_per_frame/2.0, 1.0);
2964 
2965 	s->prefetch_bw_oto = math_min2(s->prefetch_bw_oto, *p->prefetch_sw_bytes / (s->min_Lsw_oto * s->LineTime));
2966 
2967 	s->Lsw_oto = math_ceil2(4.0 * *p->prefetch_sw_bytes / s->prefetch_bw_oto / s->LineTime, 1.0) / 4.0;
2968 	s->prefetch_bw_oto = math_max3(s->prefetch_bw_oto,
2969 		p->vm_bytes * p->HostVMInefficiencyFactor / (31 * s->LineTime) - *p->Tno_bw,
2970 		(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / (15 * s->LineTime));
2971 
2972 	if (p->display_cfg->gpuvm_enable == true) {
2973 		s->Tvm_oto = math_max3(
2974 				*p->Tvm_trips,
2975 				*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto,
2976 				s->LineTime / 4.0);
2977 		DML_LOG_VERBOSE("DML::%s: Tvm_oto max0 = %f\n", __func__, *p->Tvm_trips);
2978 		DML_LOG_VERBOSE("DML::%s: Tvm_oto max1 = %f\n", __func__, *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto);
2979 		DML_LOG_VERBOSE("DML::%s: Tvm_oto max2 = %f\n", __func__, s->LineTime / 4.0);
2980 	} else {
2981 		s->Tvm_oto = s->Tvm_trips_rounded;
2982 	}
2983 
2984 	if ((p->display_cfg->gpuvm_enable == true || p->setup_for_tdlut || dcc_mrq_enable)) {
2985 		s->Tr0_oto = math_max3(
2986 				*p->Tr0_trips,
2987 				(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto,
2988 				s->LineTime / 4.0);
2989 		DML_LOG_VERBOSE("DML::%s: Tr0_oto max0 = %f\n", __func__, *p->Tr0_trips);
2990 		DML_LOG_VERBOSE("DML::%s: Tr0_oto max1 = %f\n", __func__, (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto);
2991 		DML_LOG_VERBOSE("DML::%s: Tr0_oto max2 = %f\n", __func__, s->LineTime / 4);
2992 	} else
2993 		s->Tr0_oto = s->LineTime / 4.0;
2994 
2995 	s->Tvm_oto_lines = math_ceil2(4.0 * s->Tvm_oto / s->LineTime, 1) / 4.0;
2996 	s->Tr0_oto_lines = math_ceil2(4.0 * s->Tr0_oto / s->LineTime, 1) / 4.0;
2997 	s->dst_y_prefetch_oto = s->Tvm_oto_lines + 2 * s->Tr0_oto_lines + s->Lsw_oto;
2998 
2999 	//To (time for delay after scaler) in line time
3000 	Lo = (unsigned int)(*p->DSTYAfterScaler + (double)*p->DSTXAfterScaler / (double)p->myPipe->HTotal);
3001 
3002 	//Tpre_equ in line time
3003 	if (p->DynamicMetadataVMEnabled && p->DynamicMetadataEnable)
3004 		s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + math_max2(p->TCalc, *p->Tvm_trips) + s->TWait_p) / s->LineTime - Lo;
3005 	else
3006 		s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + math_max2(p->TCalc, p->ExtraLatencyPrefetch) + s->TWait_p) / s->LineTime - Lo;
3007 	s->dst_y_prefetch_equ = math_min2(s->dst_y_prefetch_equ, 63.75); // limit to the reg limit of U6.2 for DST_Y_PREFETCH
3008 
3009 	DML_LOG_VERBOSE("DML::%s: HTotal = %u\n", __func__, p->myPipe->HTotal);
3010 	DML_LOG_VERBOSE("DML::%s: min_Lsw_oto = %f\n", __func__, s->min_Lsw_oto);
3011 	DML_LOG_VERBOSE("DML::%s: min_Lsw_equ = %f\n", __func__, s->min_Lsw_equ);
3012 	DML_LOG_VERBOSE("DML::%s: Tno_bw = %f\n", __func__, *p->Tno_bw);
3013 	DML_LOG_VERBOSE("DML::%s: Tno_bw_flip = %f\n", __func__, *p->Tno_bw_flip);
3014 	DML_LOG_VERBOSE("DML::%s: ExtraLatencyPrefetch = %f\n", __func__, p->ExtraLatencyPrefetch);
3015 	DML_LOG_VERBOSE("DML::%s: trip_to_mem = %f\n", __func__, s->trip_to_mem);
3016 	DML_LOG_VERBOSE("DML::%s: BytePerPixelY = %u\n", __func__, p->myPipe->BytePerPixelY);
3017 	DML_LOG_VERBOSE("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY);
3018 	DML_LOG_VERBOSE("DML::%s: swath_width_luma_ub = %u\n", __func__, p->swath_width_luma_ub);
3019 	DML_LOG_VERBOSE("DML::%s: BytePerPixelC = %u\n", __func__, p->myPipe->BytePerPixelC);
3020 	DML_LOG_VERBOSE("DML::%s: PrefetchSourceLinesC = %f\n", __func__, p->PrefetchSourceLinesC);
3021 	DML_LOG_VERBOSE("DML::%s: swath_width_chroma_ub = %u\n", __func__, p->swath_width_chroma_ub);
3022 	DML_LOG_VERBOSE("DML::%s: prefetch_sw_bytes = %f\n", __func__, *p->prefetch_sw_bytes);
3023 	DML_LOG_VERBOSE("DML::%s: max_Tsw = %f\n", __func__, s->max_Tsw);
3024 	DML_LOG_VERBOSE("DML::%s: bytes_pp = %f\n", __func__, s->bytes_pp);
3025 	DML_LOG_VERBOSE("DML::%s: vm_bytes = %u\n", __func__, vm_bytes);
3026 	DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow);
3027 	DML_LOG_VERBOSE("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
3028 	DML_LOG_VERBOSE("DML::%s: Tvm_trips = %f\n", __func__, *p->Tvm_trips);
3029 	DML_LOG_VERBOSE("DML::%s: Tr0_trips = %f\n", __func__, *p->Tr0_trips);
3030 	DML_LOG_VERBOSE("DML::%s: Tvm_trips_flip = %f\n", __func__, *p->Tvm_trips_flip);
3031 	DML_LOG_VERBOSE("DML::%s: Tr0_trips_flip = %f\n", __func__, *p->Tr0_trips_flip);
3032 	DML_LOG_VERBOSE("DML::%s: prefetch_bw_pr = %f\n", __func__, s->prefetch_bw_pr);
3033 	DML_LOG_VERBOSE("DML::%s: prefetch_bw_oto = %f\n", __func__, s->prefetch_bw_oto);
3034 	DML_LOG_VERBOSE("DML::%s: Tr0_oto = %f\n", __func__, s->Tr0_oto);
3035 	DML_LOG_VERBOSE("DML::%s: Tvm_oto = %f\n", __func__, s->Tvm_oto);
3036 	DML_LOG_VERBOSE("DML::%s: Tvm_oto_lines = %f\n", __func__, s->Tvm_oto_lines);
3037 	DML_LOG_VERBOSE("DML::%s: Tr0_oto_lines = %f\n", __func__, s->Tr0_oto_lines);
3038 	DML_LOG_VERBOSE("DML::%s: Lsw_oto = %f\n", __func__, s->Lsw_oto);
3039 	DML_LOG_VERBOSE("DML::%s: dst_y_prefetch_oto = %f\n", __func__, s->dst_y_prefetch_oto);
3040 	DML_LOG_VERBOSE("DML::%s: dst_y_prefetch_equ = %f\n", __func__, s->dst_y_prefetch_equ);
3041 	DML_LOG_VERBOSE("DML::%s: tdlut_row_bytes = %d\n", __func__, tdlut_row_bytes);
3042 	DML_LOG_VERBOSE("DML::%s: meta_row_bytes = %d\n", __func__, p->meta_row_bytes);
3043 	s->dst_y_prefetch_equ = math_floor2(4.0 * (s->dst_y_prefetch_equ + 0.125), 1) / 4.0;
3044 	*p->Tpre_rounded = s->dst_y_prefetch_equ * s->LineTime;
3045 
3046 	DML_LOG_VERBOSE("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, s->dst_y_prefetch_equ);
3047 	DML_LOG_VERBOSE("DML::%s: LineTime: %f\n", __func__, s->LineTime);
3048 	DML_LOG_VERBOSE("DML::%s: VStartup: %u\n", __func__, p->VStartup);
3049 	DML_LOG_VERBOSE("DML::%s: Tvstartup: %fus - time between vstartup and first pixel of active\n", __func__, p->VStartup * s->LineTime);
3050 	DML_LOG_VERBOSE("DML::%s: TSetup: %fus - time from vstartup to vready\n", __func__, *p->TSetup);
3051 	DML_LOG_VERBOSE("DML::%s: TCalc: %fus - time for calculations in dchub starting at vready\n", __func__, p->TCalc);
3052 	DML_LOG_VERBOSE("DML::%s: TWait: %fus - time for fabric to become ready max(pstate exit,cstate enter/exit, urgent latency) after TCalc\n", __func__, p->TWait);
3053 	DML_LOG_VERBOSE("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, s->Tdmbf);
3054 	DML_LOG_VERBOSE("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, s->Tdmec);
3055 	DML_LOG_VERBOSE("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, s->Tdmsks);
3056 	DML_LOG_VERBOSE("DML::%s: TWait = %f\n", __func__, p->TWait);
3057 	DML_LOG_VERBOSE("DML::%s: TWait_p = %f\n", __func__, s->TWait_p);
3058 	DML_LOG_VERBOSE("DML::%s: Ttrip = %f\n", __func__, p->Ttrip);
3059 	DML_LOG_VERBOSE("DML::%s: Tex = %f\n", __func__, p->ExtraLatencyPrefetch);
3060 	DML_LOG_VERBOSE("DML::%s: Tdmdl_vm: %fus - time for vm stages of dmd \n", __func__, *p->Tdmdl_vm);
3061 	DML_LOG_VERBOSE("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *p->Tdmdl);
3062 	DML_LOG_VERBOSE("DML::%s: TWait_p: %fus\n", __func__, s->TWait_p);
3063 	DML_LOG_VERBOSE("DML::%s: Ttrip: %fus\n", __func__, p->Ttrip);
3064 	DML_LOG_VERBOSE("DML::%s: DSTXAfterScaler: %u pixels - number of pixel clocks pipeline and buffer delay after scaler \n", __func__, *p->DSTXAfterScaler);
3065 	DML_LOG_VERBOSE("DML::%s: DSTYAfterScaler: %u lines - number of lines of pipeline and buffer delay after scaler \n", __func__, *p->DSTYAfterScaler);
3066 	DML_LOG_VERBOSE("DML::%s: vm_bytes: %f (hvm inefficiency scaled)\n", __func__, vm_bytes*p->HostVMInefficiencyFactor);
3067 	DML_LOG_VERBOSE("DML::%s: row_bytes: %f (hvm inefficiency scaled, 1 row)\n", __func__, p->PixelPTEBytesPerRow*p->HostVMInefficiencyFactor+p->meta_row_bytes+tdlut_row_bytes);
3068 	DML_LOG_VERBOSE("DML::%s: Tno_bw: %f\n", __func__, *p->Tno_bw);
3069 	DML_LOG_VERBOSE("DML::%s: Tpre_rounded: %f\n", __func__, *p->Tpre_rounded);
3070 	DML_LOG_VERBOSE("DML::%s: Tvm_trips=%f Tvm_trips_rounded: %f, delta=%f\n", __func__, *p->Tvm_trips, s->Tvm_trips_rounded, (s->Tvm_trips_rounded - *p->Tvm_trips));
3071 
3072 	*p->dst_y_per_vm_vblank = 0;
3073 	*p->dst_y_per_row_vblank = 0;
3074 	*p->VRatioPrefetchY = 0;
3075 	*p->VRatioPrefetchC = 0;
3076 	*p->RequiredPrefetchPixelDataBWLuma = 0;
3077 
3078 	// Derive bandwidth by finding how much data to move within the time constraint
3079 	// Tpre_rounded is Tpre rounding to 2-bit fraction
3080 	// Tvm_trips_rounded is Tvm_trips ceiling to 1/4 line time
3081 	// Tr0_trips_rounded is Tr0_trips ceiling to 1/4 line time
3082 	// So that means prefetch bw calculated can be higher since the total time availabe for prefetch is less
3083 	bool min_Lsw_equ_ok = *p->Tpre_rounded >= s->Tvm_trips_rounded + 2.0*s->Tr0_trips_rounded + s->min_Lsw_equ*s->LineTime;
3084 
3085 	if (s->dst_y_prefetch_equ > 1 && min_Lsw_equ_ok) {
3086 		s->prefetch_bw1 = 0.;
3087 		s->prefetch_bw2 = 0.;
3088 		s->prefetch_bw3 = 0.;
3089 		s->prefetch_bw4 = 0.;
3090 
3091 		// prefetch_bw1: VM + 2*R0 + SW
3092 		if (*p->Tpre_rounded - *p->Tno_bw > 0) {
3093 			s->prefetch_bw1 = (vm_bytes * p->HostVMInefficiencyFactor
3094 					+ 2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)
3095 					+ *p->prefetch_sw_bytes)
3096 								/ (*p->Tpre_rounded - *p->Tno_bw);
3097 			s->Tsw_est1 = *p->prefetch_sw_bytes / s->prefetch_bw1;
3098 		} else
3099 			s->prefetch_bw1 = 0;
3100 
3101 		DML_LOG_VERBOSE("DML::%s: prefetch_bw1: %f\n", __func__, s->prefetch_bw1);
3102 		if ((s->Tsw_est1 < s->min_Lsw_equ * s->LineTime) && (*p->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw > 0)) {
3103 			s->prefetch_bw1 = (vm_bytes * p->HostVMInefficiencyFactor + 2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)) /
3104 					(*p->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw);
3105 			DML_LOG_VERBOSE("DML::%s: vm and 2 rows bytes = %f\n", __func__, (vm_bytes * p->HostVMInefficiencyFactor + 2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)));
3106 			DML_LOG_VERBOSE("DML::%s: Tpre_rounded = %f\n", __func__, *p->Tpre_rounded);
3107 			DML_LOG_VERBOSE("DML::%s: minus term = %f\n", __func__, s->min_Lsw_equ * s->LineTime + 0.75 * s->LineTime + *p->Tno_bw);
3108 			DML_LOG_VERBOSE("DML::%s: min_Lsw_equ = %f\n", __func__, s->min_Lsw_equ);
3109 			DML_LOG_VERBOSE("DML::%s: LineTime = %f\n", __func__, s->LineTime);
3110 			DML_LOG_VERBOSE("DML::%s: Tno_bw = %f\n", __func__, *p->Tno_bw);
3111 			DML_LOG_VERBOSE("DML::%s: Time to fetch vm and 2 rows = %f\n", __func__, (*p->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw));
3112 			DML_LOG_VERBOSE("DML::%s: prefetch_bw1: %f (updated)\n", __func__, s->prefetch_bw1);
3113 		}
3114 
3115 		// prefetch_bw2: VM + SW
3116 		if (*p->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded > 0) {
3117 			s->prefetch_bw2 = (vm_bytes * p->HostVMInefficiencyFactor + *p->prefetch_sw_bytes) /
3118 					(*p->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded);
3119 			s->Tsw_est2 = *p->prefetch_sw_bytes / s->prefetch_bw2;
3120 		} else
3121 			s->prefetch_bw2 = 0;
3122 
3123 		DML_LOG_VERBOSE("DML::%s: prefetch_bw2: %f\n", __func__, s->prefetch_bw2);
3124 		if ((s->Tsw_est2 < s->min_Lsw_equ * s->LineTime) && ((*p->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded - s->min_Lsw_equ * s->LineTime - 0.25 * s->LineTime) > 0)) {
3125 			s->prefetch_bw2 = vm_bytes * p->HostVMInefficiencyFactor / (*p->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded - s->min_Lsw_equ * s->LineTime - 0.25 * s->LineTime);
3126 			DML_LOG_VERBOSE("DML::%s: prefetch_bw2: %f (updated)\n", __func__, s->prefetch_bw2);
3127 		}
3128 
3129 		// prefetch_bw3: 2*R0 + SW
3130 		if (*p->Tpre_rounded - s->Tvm_trips_rounded > 0) {
3131 			s->prefetch_bw3 = (2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) + *p->prefetch_sw_bytes) /
3132 					(*p->Tpre_rounded - s->Tvm_trips_rounded);
3133 			s->Tsw_est3 = *p->prefetch_sw_bytes / s->prefetch_bw3;
3134 		} else
3135 			s->prefetch_bw3 = 0;
3136 
3137 		DML_LOG_VERBOSE("DML::%s: prefetch_bw3: %f\n", __func__, s->prefetch_bw3);
3138 		if ((s->Tsw_est3 < s->min_Lsw_equ * s->LineTime) && ((*p->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded) > 0)) {
3139 			s->prefetch_bw3 = (2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)) / (*p->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded);
3140 			DML_LOG_VERBOSE("DML::%s: prefetch_bw3: %f (updated)\n", __func__, s->prefetch_bw3);
3141 		}
3142 
3143 		// prefetch_bw4: SW
3144 		if (*p->Tpre_rounded - s->Tvm_trips_rounded - 2 * s->Tr0_trips_rounded > 0)
3145 			s->prefetch_bw4 = *p->prefetch_sw_bytes / (*p->Tpre_rounded - s->Tvm_trips_rounded - 2 * s->Tr0_trips_rounded);
3146 		else
3147 			s->prefetch_bw4 = 0;
3148 
3149 		DML_LOG_VERBOSE("DML::%s: Tno_bw: %f\n", __func__, *p->Tno_bw);
3150 		DML_LOG_VERBOSE("DML::%s: Tpre_rounded: %f\n", __func__, *p->Tpre_rounded);
3151 		DML_LOG_VERBOSE("DML::%s: Tvm_trips=%f Tvm_trips_rounded: %f, delta=%f\n", __func__, *p->Tvm_trips, s->Tvm_trips_rounded, (s->Tvm_trips_rounded - *p->Tvm_trips));
3152 		DML_LOG_VERBOSE("DML::%s: Tr0_trips=%f Tr0_trips_rounded: %f, delta=%f\n", __func__, *p->Tr0_trips, s->Tr0_trips_rounded, (s->Tr0_trips_rounded - *p->Tr0_trips));
3153 		DML_LOG_VERBOSE("DML::%s: Tsw_est1: %f\n", __func__, s->Tsw_est1);
3154 		DML_LOG_VERBOSE("DML::%s: Tsw_est2: %f\n", __func__, s->Tsw_est2);
3155 		DML_LOG_VERBOSE("DML::%s: Tsw_est3: %f\n", __func__, s->Tsw_est3);
3156 		DML_LOG_VERBOSE("DML::%s: prefetch_bw1: %f (final)\n", __func__, s->prefetch_bw1);
3157 		DML_LOG_VERBOSE("DML::%s: prefetch_bw2: %f (final)\n", __func__, s->prefetch_bw2);
3158 		DML_LOG_VERBOSE("DML::%s: prefetch_bw3: %f (final)\n", __func__, s->prefetch_bw3);
3159 		DML_LOG_VERBOSE("DML::%s: prefetch_bw4: %f (final)\n", __func__, s->prefetch_bw4);
3160 		{
3161 			bool Case1OK = false;
3162 			bool Case2OK = false;
3163 			bool Case3OK = false;
3164 
3165 			// get "equalized" bw among all stages (vm, r0, sw), so based is all 3 stages are just above the latency-based requirement
3166 			// so it is not too dis-portionally favor a particular stage, next is either r0 more agressive and next is vm more agressive, the worst is all are agressive
3167 			// vs the latency based number
3168 
3169 			// prefetch_bw1: VM + 2*R0 + SW
3170 			// so prefetch_bw1 will have enough bw to transfer the necessary data within Tpre_rounded - Tno_bw (Tpre is the the worst-case latency based time to fetch the data)
3171 			// here is to make sure equ bw wont be more agressive than the latency-based requirement.
3172 			// check vm time >= vm_trips
3173 			// check r0 time >= r0_trips
3174 
3175 			double total_row_bytes = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes);
3176 
3177 			DML_LOG_VERBOSE("DML::%s: Tvm_trips_rounded = %f\n", __func__, s->Tvm_trips_rounded);
3178 			DML_LOG_VERBOSE("DML::%s: Tr0_trips_rounded = %f\n", __func__, s->Tr0_trips_rounded);
3179 
3180 			if (s->prefetch_bw1 > 0) {
3181 				double vm_transfer_time = *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw1;
3182 				double row_transfer_time = total_row_bytes / s->prefetch_bw1;
3183 				DML_LOG_VERBOSE("DML::%s: Case1: vm_transfer_time  = %f\n", __func__, vm_transfer_time);
3184 				DML_LOG_VERBOSE("DML::%s: Case1: row_transfer_time = %f\n", __func__, row_transfer_time);
3185 				if (vm_transfer_time >= s->Tvm_trips_rounded && row_transfer_time >= s->Tr0_trips_rounded) {
3186 					Case1OK = true;
3187 				}
3188 			}
3189 
3190 			// prefetch_bw2: VM + SW
3191 			// prefetch_bw2 will be enough bw to transfer VM and SW data within (Tpre_rounded - Tr0_trips_rounded - Tno_bw)
3192 			// check vm time >= vm_trips
3193 			// check r0 time < r0_trips
3194 			if (s->prefetch_bw2 > 0) {
3195 				double vm_transfer_time = *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw2;
3196 				double row_transfer_time = total_row_bytes / s->prefetch_bw2;
3197 				DML_LOG_VERBOSE("DML::%s: Case2: vm_transfer_time  = %f\n", __func__, vm_transfer_time);
3198 				DML_LOG_VERBOSE("DML::%s: Case2: row_transfer_time = %f\n", __func__, row_transfer_time);
3199 				if (vm_transfer_time >= s->Tvm_trips_rounded && row_transfer_time < s->Tr0_trips_rounded) {
3200 					Case2OK = true;
3201 				}
3202 			}
3203 
3204 			// prefetch_bw3: VM + 2*R0
3205 			// check vm time < vm_trips
3206 			// check r0 time >= r0_trips
3207 			if (s->prefetch_bw3 > 0) {
3208 				double vm_transfer_time = *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw3;
3209 				double row_transfer_time = total_row_bytes / s->prefetch_bw3;
3210 				DML_LOG_VERBOSE("DML::%s: Case3: vm_transfer_time  = %f\n", __func__, vm_transfer_time);
3211 				DML_LOG_VERBOSE("DML::%s: Case3: row_transfer_time = %f\n", __func__, row_transfer_time);
3212 				if (vm_transfer_time < s->Tvm_trips_rounded && row_transfer_time >= s->Tr0_trips_rounded) {
3213 					Case3OK = true;
3214 				}
3215 			}
3216 
3217 			if (Case1OK) {
3218 				s->prefetch_bw_equ = s->prefetch_bw1;
3219 			} else if (Case2OK) {
3220 				s->prefetch_bw_equ = s->prefetch_bw2;
3221 			} else if (Case3OK) {
3222 				s->prefetch_bw_equ = s->prefetch_bw3;
3223 			} else {
3224 				s->prefetch_bw_equ = s->prefetch_bw4;
3225 			}
3226 
3227 			s->prefetch_bw_equ = math_max3(s->prefetch_bw_equ,
3228 					p->vm_bytes * p->HostVMInefficiencyFactor / (31 * s->LineTime) - *p->Tno_bw,
3229 					(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / (15 * s->LineTime));
3230 			DML_LOG_VERBOSE("DML::%s: Case1OK: %u\n", __func__, Case1OK);
3231 			DML_LOG_VERBOSE("DML::%s: Case2OK: %u\n", __func__, Case2OK);
3232 			DML_LOG_VERBOSE("DML::%s: Case3OK: %u\n", __func__, Case3OK);
3233 			DML_LOG_VERBOSE("DML::%s: prefetch_bw_equ: %f\n", __func__, s->prefetch_bw_equ);
3234 
3235 			if (s->prefetch_bw_equ > 0) {
3236 				if (p->display_cfg->gpuvm_enable == true) {
3237 					s->Tvm_equ = math_max3(*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_equ, *p->Tvm_trips, s->LineTime / 4);
3238 				} else {
3239 					s->Tvm_equ = s->LineTime / 4;
3240 				}
3241 
3242 				if (p->display_cfg->gpuvm_enable == true || dcc_mrq_enable || p->setup_for_tdlut) {
3243 					s->Tr0_equ = math_max3((p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_equ, // PixelPTEBytesPerRow is dpte_row_bytes
3244 							*p->Tr0_trips,
3245 							s->LineTime / 4);
3246 				} else {
3247 					s->Tr0_equ = s->LineTime / 4;
3248 				}
3249 			} else {
3250 				s->Tvm_equ = 0;
3251 				s->Tr0_equ = 0;
3252 				DML_LOG_VERBOSE("DML::%s: prefetch_bw_equ equals 0!\n", __func__);
3253 			}
3254 		}
3255 		DML_LOG_VERBOSE("DML::%s: Tvm_equ = %f\n", __func__, s->Tvm_equ);
3256 		DML_LOG_VERBOSE("DML::%s: Tr0_equ = %f\n", __func__, s->Tr0_equ);
3257 
3258 		s->LinesToRequestPrefetchPixelData = s->dst_y_prefetch_equ -
3259 			(math_ceil2(4.0 * s->Tvm_equ / s->LineTime, 1.0) / 4.0) -
3260 			2 * (math_ceil2(4.0 * s->Tr0_equ / s->LineTime, 1.0) / 4.0);
3261 		if (s->dst_y_prefetch_oto < s->dst_y_prefetch_equ && !(p->use_max_lsw && s->min_Lsw_oto < s->LinesToRequestPrefetchPixelData)) {
3262 			*p->dst_y_prefetch = s->dst_y_prefetch_oto;
3263 			s->TimeForFetchingVM = s->Tvm_oto;
3264 			s->TimeForFetchingRowInVBlank = s->Tr0_oto;
3265 			DML_LOG_VERBOSE("DML::%s: Using oto scheduling for prefetch\n", __func__);
3266 		} else {
3267 			*p->dst_y_prefetch = s->dst_y_prefetch_equ;
3268 			s->TimeForFetchingVM = s->Tvm_equ;
3269 			s->TimeForFetchingRowInVBlank = s->Tr0_equ;
3270 			DML_LOG_VERBOSE("DML::%s: Using equ scheduling for prefetch\n", __func__);
3271 		}
3272 
3273 		*p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
3274 		*p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
3275 
3276 		s->LinesToRequestPrefetchPixelData = *p->dst_y_prefetch - *p->dst_y_per_vm_vblank - 2 * *p->dst_y_per_row_vblank;
3277 
3278 		s->cursor_prefetch_bytes = (unsigned int)math_max2(p->cursor_bytes_per_chunk, 4 * p->cursor_bytes_per_line);
3279 		*p->prefetch_cursor_bw = p->num_cursors * s->cursor_prefetch_bytes / (s->LinesToRequestPrefetchPixelData * s->LineTime);
3280 
3281 		DML_LOG_VERBOSE("DML::%s: TimeForFetchingVM = %f\n", __func__, s->TimeForFetchingVM);
3282 		DML_LOG_VERBOSE("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, s->TimeForFetchingRowInVBlank);
3283 		DML_LOG_VERBOSE("DML::%s: LineTime = %f\n", __func__, s->LineTime);
3284 		DML_LOG_VERBOSE("DML::%s: dst_y_prefetch = %f\n", __func__, *p->dst_y_prefetch);
3285 		DML_LOG_VERBOSE("DML::%s: dst_y_per_vm_vblank = %f\n", __func__, *p->dst_y_per_vm_vblank);
3286 		DML_LOG_VERBOSE("DML::%s: dst_y_per_row_vblank = %f\n", __func__, *p->dst_y_per_row_vblank);
3287 		DML_LOG_VERBOSE("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, s->LinesToRequestPrefetchPixelData);
3288 		DML_LOG_VERBOSE("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY);
3289 
3290 		DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_chunk = %d\n", __func__, p->cursor_bytes_per_chunk);
3291 		DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_line = %d\n", __func__, p->cursor_bytes_per_line);
3292 		DML_LOG_VERBOSE("DML::%s: cursor_prefetch_bytes = %d\n", __func__, s->cursor_prefetch_bytes);
3293 		DML_LOG_VERBOSE("DML::%s: prefetch_cursor_bw = %f\n", __func__, *p->prefetch_cursor_bw);
3294 		DML_ASSERT(*p->dst_y_prefetch < 64);
3295 
3296 		unsigned int min_lsw_required = (unsigned int)math_max2(2, p->tdlut_drain_time / s->LineTime);
3297 		if (s->LinesToRequestPrefetchPixelData >= min_lsw_required && s->prefetch_bw_equ > 0) {
3298 			*p->VRatioPrefetchY = (double)p->PrefetchSourceLinesY / s->LinesToRequestPrefetchPixelData;
3299 			*p->VRatioPrefetchY = math_max2(*p->VRatioPrefetchY, 1.0);
3300 			DML_LOG_VERBOSE("DML::%s: VRatioPrefetchY = %f\n", __func__, *p->VRatioPrefetchY);
3301 			DML_LOG_VERBOSE("DML::%s: SwathHeightY = %u\n", __func__, p->SwathHeightY);
3302 			DML_LOG_VERBOSE("DML::%s: VInitPreFillY = %u\n", __func__, p->VInitPreFillY);
3303 			if ((p->SwathHeightY > 4) && (p->VInitPreFillY > 3)) {
3304 				if (s->LinesToRequestPrefetchPixelData > (p->VInitPreFillY - 3.0) / 2.0) {
3305 					*p->VRatioPrefetchY = math_max2(*p->VRatioPrefetchY,
3306 							(double)p->MaxNumSwathY * p->SwathHeightY / (s->LinesToRequestPrefetchPixelData - (p->VInitPreFillY - 3.0) / 2.0));
3307 				} else {
3308 					s->NoTimeToPrefetch = true;
3309 					DML_LOG_VERBOSE("DML::%s: No time to prefetch!. LinesToRequestPrefetchPixelData=%f VinitPreFillY=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillY);
3310 					*p->VRatioPrefetchY = 0;
3311 				}
3312 				DML_LOG_VERBOSE("DML::%s: VRatioPrefetchY = %f\n", __func__, *p->VRatioPrefetchY);
3313 				DML_LOG_VERBOSE("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY);
3314 				DML_LOG_VERBOSE("DML::%s: MaxNumSwathY = %u\n", __func__, p->MaxNumSwathY);
3315 			}
3316 
3317 			*p->VRatioPrefetchC = (double)p->PrefetchSourceLinesC / s->LinesToRequestPrefetchPixelData;
3318 			*p->VRatioPrefetchC = math_max2(*p->VRatioPrefetchC, 1.0);
3319 
3320 			DML_LOG_VERBOSE("DML::%s: VRatioPrefetchC = %f\n", __func__, *p->VRatioPrefetchC);
3321 			DML_LOG_VERBOSE("DML::%s: SwathHeightC = %u\n", __func__, p->SwathHeightC);
3322 			DML_LOG_VERBOSE("DML::%s: VInitPreFillC = %u\n", __func__, p->VInitPreFillC);
3323 			if ((p->SwathHeightC > 4) && (p->VInitPreFillC > 3)) {
3324 				if (s->LinesToRequestPrefetchPixelData > (p->VInitPreFillC - 3.0) / 2.0) {
3325 					*p->VRatioPrefetchC = math_max2(*p->VRatioPrefetchC, (double)p->MaxNumSwathC * p->SwathHeightC / (s->LinesToRequestPrefetchPixelData - (p->VInitPreFillC - 3.0) / 2.0));
3326 				} else {
3327 					s->NoTimeToPrefetch = true;
3328 					DML_LOG_VERBOSE("DML::%s: No time to prefetch!. LinesToRequestPrefetchPixelData=%f VInitPreFillC=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillC);
3329 					*p->VRatioPrefetchC = 0;
3330 				}
3331 				DML_LOG_VERBOSE("DML::%s: VRatioPrefetchC = %f\n", __func__, *p->VRatioPrefetchC);
3332 				DML_LOG_VERBOSE("DML::%s: PrefetchSourceLinesC = %f\n", __func__, p->PrefetchSourceLinesC);
3333 				DML_LOG_VERBOSE("DML::%s: MaxNumSwathC = %u\n", __func__, p->MaxNumSwathC);
3334 			}
3335 
3336 			*p->RequiredPrefetchPixelDataBWLuma = (double)p->PrefetchSourceLinesY / s->LinesToRequestPrefetchPixelData * p->myPipe->BytePerPixelY * p->swath_width_luma_ub / s->LineTime;
3337 			*p->RequiredPrefetchPixelDataBWChroma = (double)p->PrefetchSourceLinesC / s->LinesToRequestPrefetchPixelData * p->myPipe->BytePerPixelC * p->swath_width_chroma_ub / s->LineTime;
3338 
3339 			DML_LOG_VERBOSE("DML::%s: BytePerPixelY = %u\n", __func__, p->myPipe->BytePerPixelY);
3340 			DML_LOG_VERBOSE("DML::%s: swath_width_luma_ub = %u\n", __func__, p->swath_width_luma_ub);
3341 			DML_LOG_VERBOSE("DML::%s: LineTime = %f\n", __func__, s->LineTime);
3342 			DML_LOG_VERBOSE("DML::%s: RequiredPrefetchPixelDataBWLuma = %f\n", __func__, *p->RequiredPrefetchPixelDataBWLuma);
3343 			DML_LOG_VERBOSE("DML::%s: RequiredPrefetchPixelDataBWChroma = %f\n", __func__, *p->RequiredPrefetchPixelDataBWChroma);
3344 		} else {
3345 			s->NoTimeToPrefetch = true;
3346 			DML_LOG_VERBOSE("DML::%s: No time to prefetch!, LinesToRequestPrefetchPixelData: %f, should be >= %d\n", __func__, s->LinesToRequestPrefetchPixelData, min_lsw_required);
3347 			DML_LOG_VERBOSE("DML::%s: No time to prefetch!, prefetch_bw_equ: %f, should be > 0\n", __func__, s->prefetch_bw_equ);
3348 			*p->VRatioPrefetchY = 0;
3349 			*p->VRatioPrefetchC = 0;
3350 			*p->RequiredPrefetchPixelDataBWLuma = 0;
3351 			*p->RequiredPrefetchPixelDataBWChroma = 0;
3352 		}
3353 
3354 		DML_LOG_VERBOSE("DML: Tpre: %fus - sum of time to request 2 x data pte, swaths\n", (double)s->LinesToRequestPrefetchPixelData * s->LineTime + 2.0 * s->TimeForFetchingRowInVBlank + s->TimeForFetchingVM);
3355 		DML_LOG_VERBOSE("DML: Tvm: %fus - time to fetch vm\n", s->TimeForFetchingVM);
3356 		DML_LOG_VERBOSE("DML: Tr0: %fus - time to fetch first row of data pagetables\n", s->TimeForFetchingRowInVBlank);
3357 		DML_LOG_VERBOSE("DML: Tsw: %fus = time to fetch enough pixel data and cursor data to feed the scalers init position and detile\n", (double)s->LinesToRequestPrefetchPixelData * s->LineTime);
3358 		DML_LOG_VERBOSE("DML: To: %fus - time for propagation from scaler to optc\n", (*p->DSTYAfterScaler + ((double)(*p->DSTXAfterScaler) / (double)p->myPipe->HTotal)) * s->LineTime);
3359 		DML_LOG_VERBOSE("DML: Tvstartup - TSetup - Tcalc - TWait - Tpre - To > 0\n");
3360 		DML_LOG_VERBOSE("DML: Tslack(pre): %fus - time left over in schedule\n", p->VStartup * s->LineTime - s->TimeForFetchingVM - 2 * s->TimeForFetchingRowInVBlank - (*p->DSTYAfterScaler + ((double)(*p->DSTXAfterScaler) / (double)p->myPipe->HTotal)) * s->LineTime - p->TWait - p->TCalc - *p->TSetup);
3361 		DML_LOG_VERBOSE("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %u\n", p->PixelPTEBytesPerRow);
3362 
3363 	} else {
3364 		DML_LOG_VERBOSE("DML::%s: No time to prefetch! dst_y_prefetch_equ = %f (should be > 1)\n", __func__, s->dst_y_prefetch_equ);
3365 		DML_LOG_VERBOSE("DML::%s: No time to prefetch! Tpre_rounded (%f) should be >= Tvm_trips_rounded (%f)  + 2.0*Tr0_trips_rounded (%f) + min_Tsw_equ (%f)\n",
3366 				__func__, *p->Tpre_rounded, s->Tvm_trips_rounded, 2.0*s->Tr0_trips_rounded, s->min_Lsw_equ*s->LineTime);
3367 		s->NoTimeToPrefetch = true;
3368 		s->TimeForFetchingVM = 0;
3369 		s->TimeForFetchingRowInVBlank = 0;
3370 		*p->dst_y_per_vm_vblank = 0;
3371 		*p->dst_y_per_row_vblank = 0;
3372 		s->LinesToRequestPrefetchPixelData = 0;
3373 		*p->VRatioPrefetchY = 0;
3374 		*p->VRatioPrefetchC = 0;
3375 		*p->RequiredPrefetchPixelDataBWLuma = 0;
3376 		*p->RequiredPrefetchPixelDataBWChroma = 0;
3377 	}
3378 
3379 	{
3380 		double prefetch_vm_bw;
3381 		double prefetch_row_bw;
3382 
3383 		if (vm_bytes == 0) {
3384 			prefetch_vm_bw = 0;
3385 		} else if (*p->dst_y_per_vm_vblank > 0) {
3386 			DML_LOG_VERBOSE("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
3387 			DML_LOG_VERBOSE("DML::%s: dst_y_per_vm_vblank = %f\n", __func__, *p->dst_y_per_vm_vblank);
3388 			DML_LOG_VERBOSE("DML::%s: LineTime = %f\n", __func__, s->LineTime);
3389 			prefetch_vm_bw = vm_bytes * p->HostVMInefficiencyFactor / (*p->dst_y_per_vm_vblank * s->LineTime);
3390 			DML_LOG_VERBOSE("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
3391 		} else {
3392 			prefetch_vm_bw = 0;
3393 			s->NoTimeToPrefetch = true;
3394 			DML_LOG_VERBOSE("DML::%s: No time to prefetch!. dst_y_per_vm_vblank=%f (should be > 0)\n", __func__, *p->dst_y_per_vm_vblank);
3395 		}
3396 
3397 		if (p->PixelPTEBytesPerRow == 0 && tdlut_row_bytes == 0) {
3398 			prefetch_row_bw = 0;
3399 		} else if (*p->dst_y_per_row_vblank > 0) {
3400 			prefetch_row_bw = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + tdlut_row_bytes) / (*p->dst_y_per_row_vblank * s->LineTime);
3401 
3402 			DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow);
3403 			DML_LOG_VERBOSE("DML::%s: dst_y_per_row_vblank = %f\n", __func__, *p->dst_y_per_row_vblank);
3404 			DML_LOG_VERBOSE("DML::%s: prefetch_row_bw = %f\n", __func__, prefetch_row_bw);
3405 		} else {
3406 			prefetch_row_bw = 0;
3407 			s->NoTimeToPrefetch = true;
3408 			DML_LOG_VERBOSE("DML::%s: No time to prefetch!. dst_y_per_row_vblank=%f (should be > 0)\n", __func__, *p->dst_y_per_row_vblank);
3409 		}
3410 
3411 		*p->prefetch_vmrow_bw = math_max2(prefetch_vm_bw, prefetch_row_bw);
3412 	}
3413 
3414 	if (s->NoTimeToPrefetch) {
3415 		s->TimeForFetchingVM = 0;
3416 		s->TimeForFetchingRowInVBlank = 0;
3417 		*p->dst_y_per_vm_vblank = 0;
3418 		*p->dst_y_per_row_vblank = 0;
3419 		*p->dst_y_prefetch = 0;
3420 		s->LinesToRequestPrefetchPixelData = 0;
3421 		*p->VRatioPrefetchY = 0;
3422 		*p->VRatioPrefetchC = 0;
3423 		*p->RequiredPrefetchPixelDataBWLuma = 0;
3424 		*p->RequiredPrefetchPixelDataBWChroma = 0;
3425 		*p->prefetch_vmrow_bw = 0;
3426 	}
3427 
3428 	DML_LOG_VERBOSE("DML::%s: dst_y_per_vm_vblank = %f (final)\n", __func__, *p->dst_y_per_vm_vblank);
3429 	DML_LOG_VERBOSE("DML::%s: dst_y_per_row_vblank = %f (final)\n", __func__, *p->dst_y_per_row_vblank);
3430 	DML_LOG_VERBOSE("DML::%s: prefetch_vmrow_bw = %f (final)\n", __func__, *p->prefetch_vmrow_bw);
3431 	DML_LOG_VERBOSE("DML::%s: RequiredPrefetchPixelDataBWLuma = %f (final)\n", __func__, *p->RequiredPrefetchPixelDataBWLuma);
3432 	DML_LOG_VERBOSE("DML::%s: RequiredPrefetchPixelDataBWChroma = %f (final)\n", __func__, *p->RequiredPrefetchPixelDataBWChroma);
3433 	DML_LOG_VERBOSE("DML::%s: NoTimeToPrefetch=%d\n", __func__, s->NoTimeToPrefetch);
3434 	return s->NoTimeToPrefetch;
3435 }
3436 
dcn5_calculate_urgent_bandwidth_required(struct dml2_core_shared_get_urgent_bandwidth_required_locals * l,const struct dml2_display_cfg * display_cfg,bool inc_flip_bw,bool use_qual_row_bw,unsigned int NumberOfActiveSurfaces,unsigned int NumberOfDPP[],double dcc_dram_bw_nom_overhead_factor_p0[],double dcc_dram_bw_nom_overhead_factor_p1[],double dcc_dram_bw_pref_overhead_factor_p0[],double dcc_dram_bw_pref_overhead_factor_p1[],double ReadBandwidthLuma[],double ReadBandwidthChroma[],double PrefetchBandwidthLuma[],double PrefetchBandwidthChroma[],double excess_vactive_fill_bw_l[],double excess_vactive_fill_bw_c[],double cursor_bw[],double dpte_row_bw[],double meta_row_bw[],double prefetch_cursor_bw[],double prefetch_vmrow_bw[],double flip_bw[],double UrgentBurstFactorLuma[],double UrgentBurstFactorChroma[],double UrgentBurstFactorCursor[],double UrgentBurstFactorLumaPre[],double UrgentBurstFactorChromaPre[],double UrgentBurstFactorCursorPre[],double surface_required_bw[],double surface_peak_required_bw[])3437 static double dcn5_calculate_urgent_bandwidth_required(
3438 		struct dml2_core_shared_get_urgent_bandwidth_required_locals *l,
3439 		const struct dml2_display_cfg *display_cfg,
3440 		bool inc_flip_bw, // including flip bw
3441 		bool use_qual_row_bw,
3442 		unsigned int NumberOfActiveSurfaces,
3443 		unsigned int NumberOfDPP[],
3444 		double dcc_dram_bw_nom_overhead_factor_p0[],
3445 		double dcc_dram_bw_nom_overhead_factor_p1[],
3446 		double dcc_dram_bw_pref_overhead_factor_p0[],
3447 		double dcc_dram_bw_pref_overhead_factor_p1[],
3448 		double ReadBandwidthLuma[],
3449 		double ReadBandwidthChroma[],
3450 		double PrefetchBandwidthLuma[],
3451 		double PrefetchBandwidthChroma[],
3452 		double excess_vactive_fill_bw_l[],
3453 		double excess_vactive_fill_bw_c[],
3454 		double cursor_bw[],
3455 		double dpte_row_bw[],
3456 		double meta_row_bw[],
3457 		double prefetch_cursor_bw[],
3458 		double prefetch_vmrow_bw[],
3459 		double flip_bw[],
3460 		double UrgentBurstFactorLuma[],
3461 		double UrgentBurstFactorChroma[],
3462 		double UrgentBurstFactorCursor[],
3463 		double UrgentBurstFactorLumaPre[],
3464 		double UrgentBurstFactorChromaPre[],
3465 		double UrgentBurstFactorCursorPre[],
3466 		/* outputs */
3467 		double surface_required_bw[],
3468 		double surface_peak_required_bw[])
3469 {
3470 	// set inc_flip_bw = 0 for total_dchub_urgent_read_bw_noflip calculation, 1 for total_dchub_urgent_read_bw as described in the MAS
3471 	// set use_qual_row_bw = 1 to calculate using qualified row bandwidth, used for total_flip_bw calculation
3472 
3473 	memset(l, 0, sizeof(struct dml2_core_shared_get_urgent_bandwidth_required_locals));
3474 
3475 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
3476 		l->adj_factor_p0 = UrgentBurstFactorLuma[k] * dcc_dram_bw_nom_overhead_factor_p0[k];
3477 		l->adj_factor_p1 = UrgentBurstFactorChroma[k] * dcc_dram_bw_nom_overhead_factor_p1[k];
3478 		l->adj_factor_cur = UrgentBurstFactorCursor[k];
3479 		l->adj_factor_p0_pre = UrgentBurstFactorLumaPre[k] * dcc_dram_bw_pref_overhead_factor_p0[k];
3480 		l->adj_factor_p1_pre = UrgentBurstFactorChromaPre[k] * dcc_dram_bw_pref_overhead_factor_p1[k];
3481 		l->adj_factor_cur_pre = UrgentBurstFactorCursorPre[k];
3482 
3483 		// The qualified row bandwidth, qual_row_bw, accounts for the regular non-flip row bandwidth when there is no possible immediate flip or HostVM invalidation flip.
3484 		// The qual_row_bw is zero if HostVM is possible and only non-zero and equal to row_bw(i) if immediate flip is not allowed for that pipe.
3485 		if (use_qual_row_bw) {
3486 			if (display_cfg->hostvm_enable)
3487 				l->per_plane_flip_bw[k] = 0; // qual_row_bw
3488 			else if (!display_cfg->plane_descriptors[k].immediate_flip)
3489 				l->per_plane_flip_bw[k] = NumberOfDPP[k] * (dpte_row_bw[k] + meta_row_bw[k]);
3490 		} else {
3491 			// the final_flip_bw includes the regular row_bw when immediate flip is disallowed (and no HostVM)
3492 			if ((!display_cfg->plane_descriptors[k].immediate_flip && !display_cfg->hostvm_enable) || !inc_flip_bw)
3493 				l->per_plane_flip_bw[k] = NumberOfDPP[k] * (dpte_row_bw[k] + meta_row_bw[k]);
3494 			else
3495 				l->per_plane_flip_bw[k] = NumberOfDPP[k] * flip_bw[k];
3496 		}
3497 
3498 		l->vm_row_bw = NumberOfDPP[k] * prefetch_vmrow_bw[k];
3499 		l->flip_and_active_bw = l->per_plane_flip_bw[k]
3500 			+ ReadBandwidthLuma[k] * l->adj_factor_p0
3501 			+ ReadBandwidthChroma[k] * l->adj_factor_p1
3502 			+ cursor_bw[k] * l->adj_factor_cur;
3503 		l->flip_and_prefetch_bw = l->per_plane_flip_bw[k]
3504 			+ NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * l->adj_factor_p0_pre + PrefetchBandwidthChroma[k] * l->adj_factor_p1_pre)
3505 			+ prefetch_cursor_bw[k] * l->adj_factor_cur_pre;
3506 		l->active_and_excess_bw = (ReadBandwidthLuma[k] + excess_vactive_fill_bw_l[k]) * dcc_dram_bw_nom_overhead_factor_p0[k]
3507 			+ (ReadBandwidthChroma[k] + excess_vactive_fill_bw_c[k]) * dcc_dram_bw_nom_overhead_factor_p1[k]
3508 			+ dpte_row_bw[k] + meta_row_bw[k];
3509 
3510 		surface_required_bw[k] = math_max4(l->vm_row_bw, l->flip_and_active_bw, l->flip_and_prefetch_bw, l->active_and_excess_bw);
3511 
3512 		/* export peak required bandwidth for the surface */
3513 		surface_peak_required_bw[k] = math_max2(surface_required_bw[k], surface_peak_required_bw[k]);
3514 
3515 		DML_LOG_VERBOSE("DML::%s: k=%d, max1: vm_row_bw=%f\n", __func__, k, l->vm_row_bw);
3516 		DML_LOG_VERBOSE("DML::%s: k=%d, max2: flip_and_active_bw=%f\n", __func__, k, l->flip_and_active_bw);
3517 		DML_LOG_VERBOSE("DML::%s: k=%d, max3: flip_and_prefetch_bw=%f\n", __func__, k, l->flip_and_prefetch_bw);
3518 		DML_LOG_VERBOSE("DML::%s: k=%d, max4: active_and_excess_bw=%f\n", __func__, k, l->active_and_excess_bw);
3519 		DML_LOG_VERBOSE("DML::%s: k=%d, surface_required_bw=%f\n", __func__, k, surface_required_bw[k]);
3520 		DML_LOG_VERBOSE("DML::%s: k=%d, surface_peak_required_bw=%f\n", __func__, k, surface_peak_required_bw[k]);
3521 
3522 		l->required_bandwidth_mbps += surface_required_bw[k];
3523 
3524 		DML_LOG_VERBOSE("DML::%s: k=%d, NumberOfDPP=%d\n", __func__, k, NumberOfDPP[k]);
3525 		DML_LOG_VERBOSE("DML::%s: k=%d, use_qual_row_bw=%d\n", __func__, k, use_qual_row_bw);
3526 		DML_LOG_VERBOSE("DML::%s: k=%d, immediate_flip=%d\n", __func__, k, display_cfg->plane_descriptors[k].immediate_flip);
3527 		DML_LOG_VERBOSE("DML::%s: k=%d, adj_factor_p0=%f\n", __func__, k, l->adj_factor_p0);
3528 		DML_LOG_VERBOSE("DML::%s: k=%d, adj_factor_p1=%f\n", __func__, k, l->adj_factor_p1);
3529 		DML_LOG_VERBOSE("DML::%s: k=%d, adj_factor_cur=%f\n", __func__, k, l->adj_factor_cur);
3530 
3531 		DML_LOG_VERBOSE("DML::%s: k=%d, adj_factor_p0_pre=%f\n", __func__, k, l->adj_factor_p0_pre);
3532 		DML_LOG_VERBOSE("DML::%s: k=%d, adj_factor_p1_pre=%f\n", __func__, k, l->adj_factor_p1_pre);
3533 		DML_LOG_VERBOSE("DML::%s: k=%d, adj_factor_cur_pre=%f\n", __func__, k, l->adj_factor_cur_pre);
3534 
3535 		DML_LOG_VERBOSE("DML::%s: k=%d, per_plane_flip_bw=%f\n", __func__, k, l->per_plane_flip_bw[k]);
3536 		DML_LOG_VERBOSE("DML::%s: k=%d, prefetch_vmrow_bw=%f\n", __func__, k, prefetch_vmrow_bw[k]);
3537 		DML_LOG_VERBOSE("DML::%s: k=%d, ReadBandwidthLuma=%f\n", __func__, k, ReadBandwidthLuma[k]);
3538 		DML_LOG_VERBOSE("DML::%s: k=%d, ReadBandwidthChroma=%f\n", __func__, k, ReadBandwidthChroma[k]);
3539 		DML_LOG_VERBOSE("DML::%s: k=%d, excess_vactive_fill_bw_l=%f\n", __func__, k, excess_vactive_fill_bw_l[k]);
3540 		DML_LOG_VERBOSE("DML::%s: k=%d, excess_vactive_fill_bw_c=%f\n", __func__, k, excess_vactive_fill_bw_c[k]);
3541 		DML_LOG_VERBOSE("DML::%s: k=%d, cursor_bw=%f\n", __func__, k, cursor_bw[k]);
3542 
3543 		DML_LOG_VERBOSE("DML::%s: k=%d, meta_row_bw=%f\n", __func__, k, meta_row_bw[k]);
3544 		DML_LOG_VERBOSE("DML::%s: k=%d, dpte_row_bw=%f\n", __func__, k, dpte_row_bw[k]);
3545 		DML_LOG_VERBOSE("DML::%s: k=%d, PrefetchBandwidthLuma=%f\n", __func__, k, PrefetchBandwidthLuma[k]);
3546 		DML_LOG_VERBOSE("DML::%s: k=%d, PrefetchBandwidthChroma=%f\n", __func__, k, PrefetchBandwidthChroma[k]);
3547 		DML_LOG_VERBOSE("DML::%s: k=%d, prefetch_cursor_bw=%f\n", __func__, k, prefetch_cursor_bw[k]);
3548 	}
3549 
3550 	return l->required_bandwidth_mbps;
3551 }
3552 
dcn5_calculate_peak_bandwidth_required(struct dml2_core_internal_scratch * s,struct dml2_core_calcs_calculate_peak_bandwidth_required_params * p)3553 void dcn5_calculate_peak_bandwidth_required(
3554 		struct dml2_core_internal_scratch *s,
3555 		struct dml2_core_calcs_calculate_peak_bandwidth_required_params *p)
3556 {
3557 	struct dml2_core_shared_calculate_peak_bandwidth_required_locals *l = &s->calculate_peak_bandwidth_required_locals;
3558 
3559 	memset(l, 0, sizeof(struct dml2_core_shared_calculate_peak_bandwidth_required_locals));
3560 
3561 	DML_LOG_VERBOSE("DML::%s: inc_flip_bw = %d\n", __func__, p->inc_flip_bw);
3562 	DML_LOG_VERBOSE("DML::%s: NumberOfActiveSurfaces = %d\n", __func__, p->num_active_planes);
3563 
3564 	for (unsigned int k = 0; k < p->num_active_planes; ++k) {
3565 		l->unity_array[k] = 1.0;
3566 		l->zero_array[k] = 0.0;
3567 	}
3568 
3569 	dcn5_calculate_urgent_bandwidth_required(
3570 			&s->get_urgent_bandwidth_required_locals,
3571 			p->display_cfg,
3572 			0, //inc_flip_bw,
3573 			0, //use_qual_row_bw
3574 			p->num_active_planes,
3575 			p->num_of_dpp,
3576 			p->dcc_dram_bw_nom_overhead_factor_p0,
3577 			p->dcc_dram_bw_nom_overhead_factor_p1,
3578 			p->dcc_dram_bw_pref_overhead_factor_p0,
3579 			p->dcc_dram_bw_pref_overhead_factor_p1,
3580 			p->surface_read_bandwidth_l,
3581 			p->surface_read_bandwidth_c,
3582 			l->zero_array, //PrefetchBandwidthLuma,
3583 			l->zero_array, //PrefetchBandwidthChroma,
3584 			l->zero_array,
3585 			l->zero_array,
3586 			l->zero_array,
3587 			p->dpte_row_bw,
3588 			p->meta_row_bw,
3589 			l->zero_array, //prefetch_cursor_bw,
3590 			l->zero_array, //prefetch_vmrow_bw,
3591 			l->zero_array, //flip_bw,
3592 			l->zero_array,
3593 			l->zero_array,
3594 			l->zero_array,
3595 			l->zero_array,
3596 			l->zero_array,
3597 			l->zero_array,
3598 			**p->surface_avg_vactive_required_bw,
3599 			l->surface_dummy_bw);
3600 
3601 	**p->urg_bandwidth_required = dcn5_calculate_urgent_bandwidth_required(
3602 			&s->get_urgent_bandwidth_required_locals,
3603 			p->display_cfg,
3604 			p->inc_flip_bw,
3605 			0, //use_qual_row_bw
3606 			p->num_active_planes,
3607 			p->num_of_dpp,
3608 			p->dcc_dram_bw_nom_overhead_factor_p0,
3609 			p->dcc_dram_bw_nom_overhead_factor_p1,
3610 			p->dcc_dram_bw_pref_overhead_factor_p0,
3611 			p->dcc_dram_bw_pref_overhead_factor_p1,
3612 			p->surface_read_bandwidth_l,
3613 			p->surface_read_bandwidth_c,
3614 			p->prefetch_bandwidth_l,
3615 			p->prefetch_bandwidth_c,
3616 			p->excess_vactive_fill_bw_l,
3617 			p->excess_vactive_fill_bw_c,
3618 			p->cursor_bw,
3619 			p->dpte_row_bw,
3620 			p->meta_row_bw,
3621 			p->prefetch_cursor_bw,
3622 			p->prefetch_vmrow_bw,
3623 			p->flip_bw,
3624 			p->urgent_burst_factor_l,
3625 			p->urgent_burst_factor_c,
3626 			p->urgent_burst_factor_cursor,
3627 			p->urgent_burst_factor_prefetch_l,
3628 			p->urgent_burst_factor_prefetch_c,
3629 			p->urgent_burst_factor_prefetch_cursor,
3630 			l->surface_dummy_bw,
3631 			l->surface_dummy_bw);
3632 
3633 	**p->urg_bandwidth_required_qual = dcn5_calculate_urgent_bandwidth_required(
3634 			&s->get_urgent_bandwidth_required_locals,
3635 			p->display_cfg,
3636 			0, //inc_flip_bw
3637 			1, //use_qual_row_bw
3638 			p->num_active_planes,
3639 			p->num_of_dpp,
3640 			p->dcc_dram_bw_nom_overhead_factor_p0,
3641 			p->dcc_dram_bw_nom_overhead_factor_p1,
3642 			p->dcc_dram_bw_pref_overhead_factor_p0,
3643 			p->dcc_dram_bw_pref_overhead_factor_p1,
3644 			p->surface_read_bandwidth_l,
3645 			p->surface_read_bandwidth_c,
3646 			p->prefetch_bandwidth_l,
3647 			p->prefetch_bandwidth_c,
3648 			p->excess_vactive_fill_bw_l,
3649 			p->excess_vactive_fill_bw_c,
3650 			p->cursor_bw,
3651 			p->dpte_row_bw,
3652 			p->meta_row_bw,
3653 			p->prefetch_cursor_bw,
3654 			p->prefetch_vmrow_bw,
3655 			p->flip_bw,
3656 			p->urgent_burst_factor_l,
3657 			p->urgent_burst_factor_c,
3658 			p->urgent_burst_factor_cursor,
3659 			p->urgent_burst_factor_prefetch_l,
3660 			p->urgent_burst_factor_prefetch_c,
3661 			p->urgent_burst_factor_prefetch_cursor,
3662 			l->surface_dummy_bw,
3663 			l->surface_dummy_bw);
3664 
3665 	**p->non_urg_bandwidth_required = dcn5_calculate_urgent_bandwidth_required(
3666 			&s->get_urgent_bandwidth_required_locals,
3667 			p->display_cfg,
3668 			p->inc_flip_bw,
3669 			0, //use_qual_row_bw
3670 			p->num_active_planes,
3671 			p->num_of_dpp,
3672 			p->dcc_dram_bw_nom_overhead_factor_p0,
3673 			p->dcc_dram_bw_nom_overhead_factor_p1,
3674 			p->dcc_dram_bw_pref_overhead_factor_p0,
3675 			p->dcc_dram_bw_pref_overhead_factor_p1,
3676 			p->surface_read_bandwidth_l,
3677 			p->surface_read_bandwidth_c,
3678 			p->prefetch_bandwidth_l,
3679 			p->prefetch_bandwidth_c,
3680 			p->excess_vactive_fill_bw_l,
3681 			p->excess_vactive_fill_bw_c,
3682 			p->cursor_bw,
3683 			p->dpte_row_bw,
3684 			p->meta_row_bw,
3685 			p->prefetch_cursor_bw,
3686 			p->prefetch_vmrow_bw,
3687 			p->flip_bw,
3688 			l->unity_array,
3689 			l->unity_array,
3690 			l->unity_array,
3691 			l->unity_array,
3692 			l->unity_array,
3693 			l->unity_array,
3694 			l->surface_dummy_bw,
3695 			**p->surface_peak_required_bw);
3696 
3697 	DML_LOG_VERBOSE("DML::%s: urg_bandwidth_required%s=%f\n", __func__, (p->inc_flip_bw ? "_flip" : ""), **p->urg_bandwidth_required);
3698 	DML_LOG_VERBOSE("DML::%s: urg_bandwidth_required_qual=%f\n", __func__, **p->urg_bandwidth_required);
3699 	DML_LOG_VERBOSE("DML::%s: non_urg_bandwidth_required%s=%f\n", __func__, (p->inc_flip_bw ? "_flip" : ""), **p->non_urg_bandwidth_required);
3700 	DML_ASSERT(**p->urg_bandwidth_required >= **p->non_urg_bandwidth_required);
3701 
3702 }
3703 
dcn5_calculate_dcc_configuration(bool DCCEnabled,bool DCCProgrammingAssumesScanDirectionUnknown,enum dml2_source_format_class SourcePixelFormat,unsigned int SurfaceWidthLuma,unsigned int SurfaceWidthChroma,unsigned int SurfaceHeightLuma,unsigned int SurfaceHeightChroma,unsigned int nomDETInKByte,unsigned int RequestHeight256ByteLuma,unsigned int RequestHeight256ByteChroma,enum dml2_swizzle_mode TilingFormat,unsigned int BytePerPixelY,unsigned int BytePerPixelC,double BytePerPixelDETY,double BytePerPixelDETC,enum dml2_rotation_angle RotationAngle,enum dml2_core_internal_request_type * RequestLuma,enum dml2_core_internal_request_type * RequestChroma,unsigned int * MaxUncompressedBlockLuma,unsigned int * MaxUncompressedBlockChroma,unsigned int * MaxCompressedBlockLuma,unsigned int * MaxCompressedBlockChroma,unsigned int * IndependentBlockLuma,unsigned int * IndependentBlockChroma)3704 void dcn5_calculate_dcc_configuration(
3705 		bool DCCEnabled,
3706 		bool DCCProgrammingAssumesScanDirectionUnknown,
3707 		enum dml2_source_format_class SourcePixelFormat,
3708 		unsigned int SurfaceWidthLuma,
3709 		unsigned int SurfaceWidthChroma,
3710 		unsigned int SurfaceHeightLuma,
3711 		unsigned int SurfaceHeightChroma,
3712 		unsigned int nomDETInKByte,
3713 		unsigned int RequestHeight256ByteLuma,
3714 		unsigned int RequestHeight256ByteChroma,
3715 		enum dml2_swizzle_mode TilingFormat,
3716 		unsigned int BytePerPixelY,
3717 		unsigned int BytePerPixelC,
3718 		double BytePerPixelDETY,
3719 		double BytePerPixelDETC,
3720 		enum dml2_rotation_angle RotationAngle,
3721 
3722 		// Output
3723 		enum dml2_core_internal_request_type *RequestLuma,
3724 		enum dml2_core_internal_request_type *RequestChroma,
3725 		unsigned int *MaxUncompressedBlockLuma,
3726 		unsigned int *MaxUncompressedBlockChroma,
3727 		unsigned int *MaxCompressedBlockLuma,
3728 		unsigned int *MaxCompressedBlockChroma,
3729 		unsigned int *IndependentBlockLuma,
3730 		unsigned int *IndependentBlockChroma)
3731 {
3732 	(void)SurfaceWidthChroma;
3733 	(void)SurfaceHeightChroma;
3734 	(void)TilingFormat;
3735 	(void)BytePerPixelDETY;
3736 	(void)BytePerPixelDETC;
3737 	unsigned int DETBufferSizeForDCC = nomDETInKByte * 1024;
3738 
3739 	unsigned int segment_order_horz_contiguous_luma;
3740 	unsigned int segment_order_horz_contiguous_chroma;
3741 	unsigned int segment_order_vert_contiguous_luma;
3742 	unsigned int segment_order_vert_contiguous_chroma;
3743 
3744 	unsigned int req128_horz_wc_l;
3745 	unsigned int req128_horz_wc_c;
3746 	unsigned int req128_vert_wc_l;
3747 	unsigned int req128_vert_wc_c;
3748 
3749 	bool yuv420_planar;
3750 	bool yuv422_planar;
3751 	unsigned int horz_subsample;
3752 	unsigned int vert_subsample;
3753 	unsigned int horz_div_l;
3754 	unsigned int horz_div_c;
3755 	unsigned int vert_div_l;
3756 	unsigned int vert_div_c;
3757 
3758 	unsigned int swath_buf_size;
3759 	double detile_buf_vp_horz_limit;
3760 	double detile_buf_vp_vert_limit;
3761 
3762 	unsigned int MAS_vp_horz_limit;
3763 	unsigned int MAS_vp_vert_limit;
3764 	unsigned int max_vp_horz_width;
3765 	unsigned int max_vp_vert_height;
3766 	unsigned int eff_surf_width_l;
3767 	unsigned int eff_surf_width_c;
3768 	unsigned int eff_surf_height_l;
3769 	unsigned int eff_surf_height_c;
3770 
3771 	unsigned int full_swath_bytes_horz_wc_l;
3772 	unsigned int full_swath_bytes_horz_wc_c;
3773 	unsigned int full_swath_bytes_vert_wc_l;
3774 	unsigned int full_swath_bytes_vert_wc_c;
3775 
3776 	yuv420_planar = dml2_core_utils_is_420(SourcePixelFormat);
3777 	yuv422_planar = dml2_core_utils_is_422_planar(SourcePixelFormat);
3778 	horz_subsample = (yuv420_planar || yuv422_planar) ? 1 : 0;
3779 	vert_subsample = yuv420_planar ? 1 : 0;
3780 	horz_div_l = 1;
3781 	horz_div_c = 1;
3782 	vert_div_l = 1;
3783 	vert_div_c = 1;
3784 
3785 	if (BytePerPixelY == 1)
3786 		vert_div_l = 0;
3787 	if (BytePerPixelC == 1)
3788 		vert_div_c = 0;
3789 
3790 	if (BytePerPixelC == 0) {
3791 		swath_buf_size = DETBufferSizeForDCC / 2 - 2 * 256;
3792 		detile_buf_vp_horz_limit = (double)swath_buf_size / ((double)RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l));
3793 		detile_buf_vp_vert_limit = (double)swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l));
3794 	} else {
3795 		swath_buf_size = DETBufferSizeForDCC / 2 - 2 * 2 * 256;
3796 		detile_buf_vp_horz_limit = (double)swath_buf_size / ((double)RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l) + (double)RequestHeight256ByteChroma * BytePerPixelC / (1 + horz_div_c) / (1 + horz_subsample));
3797 		detile_buf_vp_vert_limit = (double)swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l) + 256.0 / RequestHeight256ByteChroma / (1 + vert_div_c) / (1 + vert_subsample));
3798 	}
3799 
3800 	if (SourcePixelFormat == dml2_420_10 || SourcePixelFormat == dml2_422_planar_10 || SourcePixelFormat == dml2_422_packed_10) {
3801 		detile_buf_vp_horz_limit = 1.5 * detile_buf_vp_horz_limit;
3802 		detile_buf_vp_vert_limit = 1.5 * detile_buf_vp_vert_limit;
3803 	}
3804 
3805 	detile_buf_vp_horz_limit = math_floor2(detile_buf_vp_horz_limit - 1, 16);
3806 	detile_buf_vp_vert_limit = math_floor2(detile_buf_vp_vert_limit - 1, 16);
3807 
3808 	MAS_vp_horz_limit = SourcePixelFormat == dml2_rgbe_alpha ? 3840 : 6144;
3809 	MAS_vp_vert_limit = SourcePixelFormat == dml2_rgbe_alpha ? 3840 : (BytePerPixelY == 8 ? 3072 : 6144);
3810 	max_vp_horz_width = (unsigned int)(math_min2((double)MAS_vp_horz_limit, detile_buf_vp_horz_limit));
3811 	max_vp_vert_height = (unsigned int)(math_min2((double)MAS_vp_vert_limit, detile_buf_vp_vert_limit));
3812 	eff_surf_width_l = (SurfaceWidthLuma > max_vp_horz_width ? max_vp_horz_width : SurfaceWidthLuma);
3813 	eff_surf_width_c = eff_surf_width_l / (1 + horz_subsample);
3814 	eff_surf_height_l = (SurfaceHeightLuma > max_vp_vert_height ? max_vp_vert_height : SurfaceHeightLuma);
3815 	eff_surf_height_c = eff_surf_height_l / (1 + vert_subsample);
3816 
3817 	full_swath_bytes_horz_wc_l = eff_surf_width_l * RequestHeight256ByteLuma * BytePerPixelY;
3818 	full_swath_bytes_vert_wc_l = eff_surf_height_l * 256 / RequestHeight256ByteLuma;
3819 	if (BytePerPixelC > 0) {
3820 		full_swath_bytes_horz_wc_c = eff_surf_width_c * RequestHeight256ByteChroma * BytePerPixelC;
3821 		full_swath_bytes_vert_wc_c = eff_surf_height_c * 256 / RequestHeight256ByteChroma;
3822 	} else {
3823 		full_swath_bytes_horz_wc_c = 0;
3824 		full_swath_bytes_vert_wc_c = 0;
3825 	}
3826 
3827 	if (SourcePixelFormat == dml2_420_10 || SourcePixelFormat == dml2_422_planar_10 || SourcePixelFormat == dml2_422_packed_10) {
3828 		full_swath_bytes_horz_wc_l = (unsigned int)(math_ceil2((double)full_swath_bytes_horz_wc_l * 2.0 / 3.0, 256.0));
3829 		full_swath_bytes_horz_wc_c = (unsigned int)(math_ceil2((double)full_swath_bytes_horz_wc_c * 2.0 / 3.0, 256.0));
3830 		full_swath_bytes_vert_wc_l = (unsigned int)(math_ceil2((double)full_swath_bytes_vert_wc_l * 2.0 / 3.0, 256.0));
3831 		full_swath_bytes_vert_wc_c = (unsigned int)(math_ceil2((double)full_swath_bytes_vert_wc_c * 2.0 / 3.0, 256.0));
3832 	}
3833 
3834 	if (2 * full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) {
3835 		req128_horz_wc_l = 0;
3836 		req128_horz_wc_c = 0;
3837 	} else if (full_swath_bytes_horz_wc_l < 1.5 * full_swath_bytes_horz_wc_c && 2 * full_swath_bytes_horz_wc_l + full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) {
3838 		req128_horz_wc_l = 0;
3839 		req128_horz_wc_c = 1;
3840 	} else if (full_swath_bytes_horz_wc_l >= 1.5 * full_swath_bytes_horz_wc_c && full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) {
3841 		req128_horz_wc_l = 1;
3842 		req128_horz_wc_c = 0;
3843 	} else {
3844 		req128_horz_wc_l = 1;
3845 		req128_horz_wc_c = 1;
3846 	}
3847 
3848 	if (2 * full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) {
3849 		req128_vert_wc_l = 0;
3850 		req128_vert_wc_c = 0;
3851 	} else if (full_swath_bytes_vert_wc_l < 1.5 * full_swath_bytes_vert_wc_c && 2 * full_swath_bytes_vert_wc_l + full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) {
3852 		req128_vert_wc_l = 0;
3853 		req128_vert_wc_c = 1;
3854 	} else if (full_swath_bytes_vert_wc_l >= 1.5 * full_swath_bytes_vert_wc_c && full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) {
3855 		req128_vert_wc_l = 1;
3856 		req128_vert_wc_c = 0;
3857 	} else {
3858 		req128_vert_wc_l = 1;
3859 		req128_vert_wc_c = 1;
3860 	}
3861 
3862 	if (BytePerPixelY == 2) {
3863 		segment_order_horz_contiguous_luma = 0;
3864 		segment_order_vert_contiguous_luma = 1;
3865 	} else {
3866 		segment_order_horz_contiguous_luma = 1;
3867 		segment_order_vert_contiguous_luma = 0;
3868 	}
3869 
3870 	if (BytePerPixelC == 2) {
3871 		segment_order_horz_contiguous_chroma = 0;
3872 		segment_order_vert_contiguous_chroma = 1;
3873 	} else {
3874 		segment_order_horz_contiguous_chroma = 1;
3875 		segment_order_vert_contiguous_chroma = 0;
3876 	}
3877 	DML_LOG_VERBOSE("DML::%s: DCCEnabled = %u\n", __func__, DCCEnabled);
3878 	DML_LOG_VERBOSE("DML::%s: nomDETInKByte = %u\n", __func__, nomDETInKByte);
3879 	DML_LOG_VERBOSE("DML::%s: DETBufferSizeForDCC = %u\n", __func__, DETBufferSizeForDCC);
3880 	DML_LOG_VERBOSE("DML::%s: req128_horz_wc_l = %u\n", __func__, req128_horz_wc_l);
3881 	DML_LOG_VERBOSE("DML::%s: req128_horz_wc_c = %u\n", __func__, req128_horz_wc_c);
3882 	DML_LOG_VERBOSE("DML::%s: full_swath_bytes_horz_wc_l = %u\n", __func__, full_swath_bytes_horz_wc_l);
3883 	DML_LOG_VERBOSE("DML::%s: full_swath_bytes_vert_wc_c = %u\n", __func__, full_swath_bytes_vert_wc_c);
3884 	DML_LOG_VERBOSE("DML::%s: segment_order_horz_contiguous_luma = %u\n", __func__, segment_order_horz_contiguous_luma);
3885 	DML_LOG_VERBOSE("DML::%s: segment_order_horz_contiguous_chroma = %u\n", __func__, segment_order_horz_contiguous_chroma);
3886 	if (DCCProgrammingAssumesScanDirectionUnknown == true) {
3887 		if (req128_horz_wc_l == 0 && req128_vert_wc_l == 0) {
3888 			*RequestLuma = dml2_core_internal_request_type_256_bytes;
3889 		} else if ((req128_horz_wc_l == 1 && segment_order_horz_contiguous_luma == 0) || (req128_vert_wc_l == 1 && segment_order_vert_contiguous_luma == 0)) {
3890 			*RequestLuma = dml2_core_internal_request_type_128_bytes_non_contiguous;
3891 		} else {
3892 			*RequestLuma = dml2_core_internal_request_type_128_bytes_contiguous;
3893 		}
3894 		if (req128_horz_wc_c == 0 && req128_vert_wc_c == 0) {
3895 			*RequestChroma = dml2_core_internal_request_type_256_bytes;
3896 		} else if ((req128_horz_wc_c == 1 && segment_order_horz_contiguous_chroma == 0) || (req128_vert_wc_c == 1 && segment_order_vert_contiguous_chroma == 0)) {
3897 			*RequestChroma = dml2_core_internal_request_type_128_bytes_non_contiguous;
3898 		} else {
3899 			*RequestChroma = dml2_core_internal_request_type_128_bytes_contiguous;
3900 		}
3901 	} else if (!dml2_core_utils_is_vertical_rotation(RotationAngle)) {
3902 		if (req128_horz_wc_l == 0) {
3903 			*RequestLuma = dml2_core_internal_request_type_256_bytes;
3904 		} else if (segment_order_horz_contiguous_luma == 0) {
3905 			*RequestLuma = dml2_core_internal_request_type_128_bytes_non_contiguous;
3906 		} else {
3907 			*RequestLuma = dml2_core_internal_request_type_128_bytes_contiguous;
3908 		}
3909 		if (req128_horz_wc_c == 0) {
3910 			*RequestChroma = dml2_core_internal_request_type_256_bytes;
3911 		} else if (segment_order_horz_contiguous_chroma == 0) {
3912 			*RequestChroma = dml2_core_internal_request_type_128_bytes_non_contiguous;
3913 		} else {
3914 			*RequestChroma = dml2_core_internal_request_type_128_bytes_contiguous;
3915 		}
3916 	} else {
3917 		if (req128_vert_wc_l == 0) {
3918 			*RequestLuma = dml2_core_internal_request_type_256_bytes;
3919 		} else if (segment_order_vert_contiguous_luma == 0) {
3920 			*RequestLuma = dml2_core_internal_request_type_128_bytes_non_contiguous;
3921 		} else {
3922 			*RequestLuma = dml2_core_internal_request_type_128_bytes_contiguous;
3923 		}
3924 		if (req128_vert_wc_c == 0) {
3925 			*RequestChroma = dml2_core_internal_request_type_256_bytes;
3926 		} else if (segment_order_vert_contiguous_chroma == 0) {
3927 			*RequestChroma = dml2_core_internal_request_type_128_bytes_non_contiguous;
3928 		} else {
3929 			*RequestChroma = dml2_core_internal_request_type_128_bytes_contiguous;
3930 		}
3931 	}
3932 
3933 	if (*RequestLuma == dml2_core_internal_request_type_256_bytes) {
3934 		*MaxUncompressedBlockLuma = 256;
3935 		*MaxCompressedBlockLuma = 256;
3936 		*IndependentBlockLuma = 0;
3937 	} else if (*RequestLuma == dml2_core_internal_request_type_128_bytes_contiguous) {
3938 		*MaxUncompressedBlockLuma = 256;
3939 		*MaxCompressedBlockLuma = 128;
3940 		*IndependentBlockLuma = 128;
3941 	} else {
3942 		*MaxUncompressedBlockLuma = 256;
3943 		*MaxCompressedBlockLuma = 64;
3944 		*IndependentBlockLuma = 64;
3945 	}
3946 
3947 	if (*RequestChroma == dml2_core_internal_request_type_256_bytes) {
3948 		*MaxUncompressedBlockChroma = 256;
3949 		*MaxCompressedBlockChroma = 256;
3950 		*IndependentBlockChroma = 0;
3951 	} else if (*RequestChroma == dml2_core_internal_request_type_128_bytes_contiguous) {
3952 		*MaxUncompressedBlockChroma = 256;
3953 		*MaxCompressedBlockChroma = 128;
3954 		*IndependentBlockChroma = 128;
3955 	} else {
3956 		*MaxUncompressedBlockChroma = 256;
3957 		*MaxCompressedBlockChroma = 64;
3958 		*IndependentBlockChroma = 64;
3959 	}
3960 
3961 	if (DCCEnabled != true || BytePerPixelC == 0) {
3962 		*MaxUncompressedBlockChroma = 0;
3963 		*MaxCompressedBlockChroma = 0;
3964 		*IndependentBlockChroma = 0;
3965 	}
3966 
3967 	if (DCCEnabled != true) {
3968 		*MaxUncompressedBlockLuma = 0;
3969 		*MaxCompressedBlockLuma = 0;
3970 		*IndependentBlockLuma = 0;
3971 	}
3972 
3973 	DML_LOG_VERBOSE("DML::%s: MaxUncompressedBlockLuma = %u\n", __func__, *MaxUncompressedBlockLuma);
3974 	DML_LOG_VERBOSE("DML::%s: MaxCompressedBlockLuma = %u\n", __func__, *MaxCompressedBlockLuma);
3975 	DML_LOG_VERBOSE("DML::%s: IndependentBlockLuma = %u\n", __func__, *IndependentBlockLuma);
3976 	DML_LOG_VERBOSE("DML::%s: MaxUncompressedBlockChroma = %u\n", __func__, *MaxUncompressedBlockChroma);
3977 	DML_LOG_VERBOSE("DML::%s: MaxCompressedBlockChroma = %u\n", __func__, *MaxCompressedBlockChroma);
3978 	DML_LOG_VERBOSE("DML::%s: IndependentBlockChroma = %u\n", __func__, *IndependentBlockChroma);
3979 }
3980 
dcn5_calculate_flip_schedule(struct dml2_core_internal_scratch * s,bool iflip_enable,bool use_lb_flip_bw,double HostVMInefficiencyFactor,double Tvm_trips_flip,double Tr0_trips_flip,double Tvm_trips_flip_rounded,double Tr0_trips_flip_rounded,bool GPUVMEnable,double vm_bytes,double DPTEBytesPerRow,double BandwidthAvailableForImmediateFlip,unsigned int TotImmediateFlipBytes,enum dml2_source_format_class SourcePixelFormat,double LineTime,double VRatio,double VRatioChroma,double Tno_bw_flip,unsigned int dpte_row_height,unsigned int dpte_row_height_chroma,bool use_one_row_for_frame_flip,unsigned int max_flip_time_us,unsigned int max_flip_time_lines,unsigned int per_pipe_flip_bytes,unsigned int meta_row_bytes,unsigned int meta_row_height,unsigned int meta_row_height_chroma,bool dcc_mrq_enable,double * dst_y_per_vm_flip,double * dst_y_per_row_flip,double * final_flip_bw,bool * ImmediateFlipSupportedForPipe)3981 void dcn5_calculate_flip_schedule(
3982 		struct dml2_core_internal_scratch *s,
3983 		bool iflip_enable,
3984 		bool use_lb_flip_bw,
3985 		double HostVMInefficiencyFactor,
3986 		double Tvm_trips_flip,
3987 		double Tr0_trips_flip,
3988 		double Tvm_trips_flip_rounded,
3989 		double Tr0_trips_flip_rounded,
3990 		bool GPUVMEnable,
3991 		double vm_bytes, // vm_bytes
3992 		double DPTEBytesPerRow, // dpte_row_bytes
3993 		double BandwidthAvailableForImmediateFlip,
3994 		unsigned int TotImmediateFlipBytes,
3995 		enum dml2_source_format_class SourcePixelFormat,
3996 		double LineTime,
3997 		double VRatio,
3998 		double VRatioChroma,
3999 		double Tno_bw_flip,
4000 		unsigned int dpte_row_height,
4001 		unsigned int dpte_row_height_chroma,
4002 		bool use_one_row_for_frame_flip,
4003 		unsigned int max_flip_time_us,
4004 		unsigned int max_flip_time_lines,
4005 		unsigned int per_pipe_flip_bytes,
4006 		unsigned int meta_row_bytes,
4007 		unsigned int meta_row_height,
4008 		unsigned int meta_row_height_chroma,
4009 		bool dcc_mrq_enable,
4010 
4011 		// Output
4012 		double *dst_y_per_vm_flip,
4013 		double *dst_y_per_row_flip,
4014 		double *final_flip_bw,
4015 		bool *ImmediateFlipSupportedForPipe)
4016 {
4017 	(void)use_one_row_for_frame_flip;
4018 	struct dml2_core_shared_CalculateFlipSchedule_locals *l = &s->CalculateFlipSchedule_locals;
4019 
4020 	l->dual_plane = dml2_core_utils_is_420(SourcePixelFormat) || dml2_core_utils_is_422_planar(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha;
4021 	l->dpte_row_bytes = DPTEBytesPerRow;
4022 
4023 	DML_LOG_VERBOSE("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
4024 	DML_LOG_VERBOSE("DML::%s: ip.max_flip_time_us = %d\n", __func__, max_flip_time_us);
4025 	DML_LOG_VERBOSE("DML::%s: ip.max_flip_time_lines = %d\n", __func__, max_flip_time_lines);
4026 	DML_LOG_VERBOSE("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
4027 	DML_LOG_VERBOSE("DML::%s: TotImmediateFlipBytes = %u\n", __func__, TotImmediateFlipBytes);
4028 	DML_LOG_VERBOSE("DML::%s: use_lb_flip_bw = %u\n", __func__, use_lb_flip_bw);
4029 	DML_LOG_VERBOSE("DML::%s: iflip_enable = %u\n", __func__, iflip_enable);
4030 	DML_LOG_VERBOSE("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
4031 	DML_LOG_VERBOSE("DML::%s: LineTime = %f\n", __func__, LineTime);
4032 	DML_LOG_VERBOSE("DML::%s: Tno_bw_flip = %f\n", __func__, Tno_bw_flip);
4033 	DML_LOG_VERBOSE("DML::%s: Tvm_trips_flip = %f\n", __func__, Tvm_trips_flip);
4034 	DML_LOG_VERBOSE("DML::%s: Tr0_trips_flip = %f\n", __func__, Tr0_trips_flip);
4035 	DML_LOG_VERBOSE("DML::%s: Tvm_trips_flip_rounded = %f\n", __func__, Tvm_trips_flip_rounded);
4036 	DML_LOG_VERBOSE("DML::%s: Tr0_trips_flip_rounded = %f\n", __func__, Tr0_trips_flip_rounded);
4037 	DML_LOG_VERBOSE("DML::%s: vm_bytes = %f\n", __func__, vm_bytes);
4038 	DML_LOG_VERBOSE("DML::%s: DPTEBytesPerRow = %f\n", __func__, DPTEBytesPerRow);
4039 	DML_LOG_VERBOSE("DML::%s: meta_row_bytes = %d\n", __func__, meta_row_bytes);
4040 	DML_LOG_VERBOSE("DML::%s: dpte_row_bytes = %f\n", __func__, l->dpte_row_bytes);
4041 	DML_LOG_VERBOSE("DML::%s: dpte_row_height = %d\n", __func__, dpte_row_height);
4042 	DML_LOG_VERBOSE("DML::%s: meta_row_height = %d\n", __func__, meta_row_height);
4043 	DML_LOG_VERBOSE("DML::%s: VRatio = %f\n", __func__, VRatio);
4044 
4045 	if (TotImmediateFlipBytes > 0 && (GPUVMEnable || dcc_mrq_enable)) {
4046 		if (l->dual_plane) {
4047 			if (dcc_mrq_enable & GPUVMEnable) {
4048 				l->min_row_height = math_min2(dpte_row_height, meta_row_height);
4049 				l->min_row_height_chroma = math_min2(dpte_row_height_chroma, meta_row_height_chroma);
4050 			} else if (GPUVMEnable) {
4051 				l->min_row_height = dpte_row_height;
4052 				l->min_row_height_chroma = dpte_row_height_chroma;
4053 			} else {
4054 				l->min_row_height = meta_row_height;
4055 				l->min_row_height_chroma = meta_row_height_chroma;
4056 			}
4057 			l->min_row_time = math_min2(l->min_row_height * LineTime / VRatio, l->min_row_height_chroma * LineTime / VRatioChroma);
4058 		} else {
4059 			if (dcc_mrq_enable & GPUVMEnable)
4060 				l->min_row_height = math_min2(dpte_row_height, meta_row_height);
4061 			else if (GPUVMEnable)
4062 				l->min_row_height = dpte_row_height;
4063 			else
4064 				l->min_row_height = meta_row_height;
4065 
4066 			l->min_row_time = l->min_row_height * LineTime / VRatio;
4067 		}
4068 		DML_LOG_VERBOSE("DML::%s: min_row_time = %f\n", __func__, l->min_row_time);
4069 		DML_ASSERT(l->min_row_time > 0);
4070 
4071 		if (use_lb_flip_bw) {
4072 			// For mode check, calculation the flip bw requirement with worst case flip time
4073 			l->max_flip_time = math_min2(math_min2(l->min_row_time, (double)max_flip_time_lines * LineTime / VRatio),
4074 					math_max2(Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded, (double)max_flip_time_us));
4075 
4076 			//The lower bound on flip bandwidth
4077 			// Note: The get_urgent_bandwidth_required already consider dpte_row_bw and meta_row_bw in bandwidth calculation, so leave final_flip_bw = 0 if iflip not required
4078 			l->lb_flip_bw = 0;
4079 
4080 			if (iflip_enable) {
4081 				l->hvm_scaled_vm_bytes = vm_bytes * HostVMInefficiencyFactor;
4082 				l->num_rows = 2;
4083 				l->hvm_scaled_row_bytes = (l->num_rows * l->dpte_row_bytes * HostVMInefficiencyFactor + l->num_rows * meta_row_bytes);
4084 				l->hvm_scaled_vm_row_bytes = l->hvm_scaled_vm_bytes + l->hvm_scaled_row_bytes;
4085 				l->lb_flip_bw = math_max3(
4086 						l->hvm_scaled_vm_row_bytes / (l->max_flip_time - Tno_bw_flip),
4087 						l->hvm_scaled_vm_bytes / (l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded),
4088 						l->hvm_scaled_row_bytes / (l->max_flip_time - Tvm_trips_flip_rounded));
4089 				DML_LOG_VERBOSE("DML::%s: max_flip_time = %f\n", __func__, l->max_flip_time);
4090 				DML_LOG_VERBOSE("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_bytes);
4091 				DML_LOG_VERBOSE("DML::%s: total row bytes (%f row, hvm ineff scaled) = %f\n", __func__, l->num_rows, l->hvm_scaled_row_bytes);
4092 				DML_LOG_VERBOSE("DML::%s: total vm+row bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_row_bytes);
4093 				DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm and row = %f\n", __func__, l->hvm_scaled_vm_row_bytes / (l->max_flip_time - Tno_bw_flip));
4094 				DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm = %f\n", __func__, l->hvm_scaled_vm_bytes / (l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded));
4095 				DML_LOG_VERBOSE("DML::%s: lb_flip_bw for row = %f\n", __func__, l->hvm_scaled_row_bytes / (l->max_flip_time - Tvm_trips_flip_rounded));
4096 
4097 				if (l->lb_flip_bw > 0) {
4098 					DML_LOG_VERBOSE("DML::%s: mode_support est Tvm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw);
4099 					DML_LOG_VERBOSE("DML::%s: mode_support est Tr0_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / l->num_rows);
4100 					DML_LOG_VERBOSE("DML::%s: mode_support est dst_y_per_vm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw / LineTime);
4101 					DML_LOG_VERBOSE("DML::%s: mode_support est dst_y_per_row_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / LineTime / l->num_rows);
4102 					DML_LOG_VERBOSE("DML::%s: Tvm_trips_flip_rounded + 2*Tr0_trips_flip_rounded = %f\n", __func__, (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded));
4103 				}
4104 				l->lb_flip_bw = math_max3(l->lb_flip_bw,
4105 						l->hvm_scaled_vm_bytes / (31 * LineTime) - Tno_bw_flip,
4106 						(l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15 * LineTime));
4107 
4108 				DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm reg limit = %f\n", __func__, l->hvm_scaled_vm_bytes / (31 * LineTime) - Tno_bw_flip);
4109 				DML_LOG_VERBOSE("DML::%s: lb_flip_bw for row reg limit = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15 * LineTime));
4110 			}
4111 
4112 			*final_flip_bw = l->lb_flip_bw;
4113 
4114 			*dst_y_per_vm_flip = 1; // not used
4115 			*dst_y_per_row_flip = 1; // not used
4116 			*ImmediateFlipSupportedForPipe = l->min_row_time >= (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded);
4117 		} else {
4118 			if (iflip_enable) {
4119 				l->ImmediateFlipBW = (double)per_pipe_flip_bytes * BandwidthAvailableForImmediateFlip / (double)TotImmediateFlipBytes; // flip_bw(i)
4120 				DML_LOG_VERBOSE("DML::%s: per_pipe_flip_bytes = %d\n", __func__, per_pipe_flip_bytes);
4121 				DML_LOG_VERBOSE("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
4122 				DML_LOG_VERBOSE("DML::%s: ImmediateFlipBW = %f\n", __func__, l->ImmediateFlipBW);
4123 				DML_LOG_VERBOSE("DML::%s: portion of flip bw = %f\n", __func__, (double)per_pipe_flip_bytes / (double)TotImmediateFlipBytes);
4124 				if (l->ImmediateFlipBW == 0) {
4125 					l->Tvm_flip = 0;
4126 					l->Tr0_flip = 0;
4127 				} else {
4128 					l->Tvm_flip = math_max3(Tvm_trips_flip,
4129 							Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->ImmediateFlipBW,
4130 							LineTime / 4.0);
4131 
4132 					l->Tr0_flip = math_max3(Tr0_trips_flip,
4133 							(l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / l->ImmediateFlipBW,
4134 							LineTime / 4.0);
4135 				}
4136 				DML_LOG_VERBOSE("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, vm_bytes * HostVMInefficiencyFactor);
4137 				DML_LOG_VERBOSE("DML::%s: total row bytes (hvm ineff scaled, one row) = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes));
4138 				DML_LOG_VERBOSE("DML::%s: Tvm_flip = %f (bw-based), Tvm_trips_flip = %f (latency-based)\n", __func__, Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->ImmediateFlipBW, Tvm_trips_flip);
4139 				DML_LOG_VERBOSE("DML::%s: Tr0_flip = %f (bw-based), Tr0_trips_flip = %f (latency-based)\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / l->ImmediateFlipBW, Tr0_trips_flip);
4140 				*dst_y_per_vm_flip = math_ceil2(4.0 * (l->Tvm_flip / LineTime), 1.0) / 4.0;
4141 				*dst_y_per_row_flip = math_ceil2(4.0 * (l->Tr0_flip / LineTime), 1.0) / 4.0;
4142 
4143 				*final_flip_bw = math_max2(vm_bytes * HostVMInefficiencyFactor / (*dst_y_per_vm_flip * LineTime),
4144 						(l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (*dst_y_per_row_flip * LineTime));
4145 
4146 				if (*dst_y_per_vm_flip >= 32 || *dst_y_per_row_flip >= 16 || l->Tvm_flip + 2 * l->Tr0_flip > l->min_row_time) {
4147 					*ImmediateFlipSupportedForPipe = false;
4148 				} else {
4149 					*ImmediateFlipSupportedForPipe = iflip_enable;
4150 				}
4151 			} else {
4152 				l->Tvm_flip = 0;
4153 				l->Tr0_flip = 0;
4154 				*dst_y_per_vm_flip = 0;
4155 				*dst_y_per_row_flip = 0;
4156 				*final_flip_bw = 0;
4157 				*ImmediateFlipSupportedForPipe = iflip_enable;
4158 			}
4159 		}
4160 	} else {
4161 		l->Tvm_flip = 0;
4162 		l->Tr0_flip = 0;
4163 		*dst_y_per_vm_flip = 0;
4164 		*dst_y_per_row_flip = 0;
4165 		*final_flip_bw = 0;
4166 		*ImmediateFlipSupportedForPipe = iflip_enable;
4167 	}
4168 
4169 	if (!use_lb_flip_bw) {
4170 		DML_LOG_VERBOSE("DML::%s: dst_y_per_vm_flip = %f (should be < 32)\n", __func__, *dst_y_per_vm_flip);
4171 		DML_LOG_VERBOSE("DML::%s: dst_y_per_row_flip = %f (should be < 16)\n", __func__, *dst_y_per_row_flip);
4172 		DML_LOG_VERBOSE("DML::%s: Tvm_flip = %f (final)\n", __func__, l->Tvm_flip);
4173 		DML_LOG_VERBOSE("DML::%s: Tr0_flip = %f (final)\n", __func__, l->Tr0_flip);
4174 		DML_LOG_VERBOSE("DML::%s: Tvm_flip + 2*Tr0_flip = %f (should be <= min_row_time=%f)\n", __func__, l->Tvm_flip + 2 * l->Tr0_flip, l->min_row_time);
4175 	}
4176 	DML_LOG_VERBOSE("DML::%s: final_flip_bw = %f\n", __func__, *final_flip_bw);
4177 	DML_LOG_VERBOSE("DML::%s: ImmediateFlipSupportedForPipe = %u\n", __func__, *ImmediateFlipSupportedForPipe);
4178 }
4179 
dcn5_calculate_pstate_support_method(enum dml2_pstate_method method,double vactive_margin_us,double reserved_vblank_us,double blackout_us,bool all_streams_blanked,enum dml2_pstate_change_support * surface_pstate_change_support)4180 bool dcn5_calculate_pstate_support_method(
4181 		enum dml2_pstate_method method,
4182 		double vactive_margin_us,
4183 		double reserved_vblank_us,
4184 		double blackout_us,
4185 		bool all_streams_blanked,
4186 		/* output */
4187 		enum dml2_pstate_change_support *surface_pstate_change_support)
4188 {
4189 	*surface_pstate_change_support = dml2_pstate_change_unsupported;
4190 	if (method == dml2_pstate_method_na) {
4191 		/* automatic */
4192 		if (all_streams_blanked ||
4193 				(vactive_margin_us > 0 && reserved_vblank_us >= blackout_us))
4194 			*surface_pstate_change_support = dml2_pstate_change_vblank_and_vactive;
4195 		else if (vactive_margin_us > 0)
4196 			*surface_pstate_change_support = dml2_pstate_change_vactive;
4197 		else if (reserved_vblank_us >= blackout_us)
4198 			*surface_pstate_change_support = dml2_pstate_change_vblank;
4199 	} else if (method == dml2_pstate_method_vactive || method == dml2_pstate_method_fw_vactive_drr) {
4200 		/* vactive */
4201 		if (all_streams_blanked ||
4202 				(vactive_margin_us > 0 && reserved_vblank_us >= blackout_us))
4203 			*surface_pstate_change_support = dml2_pstate_change_vblank_and_vactive;
4204 		else if (vactive_margin_us > 0)
4205 			*surface_pstate_change_support = dml2_pstate_change_vactive;
4206 	} else if ((method == dml2_pstate_method_vblank || method == dml2_pstate_method_fw_vblank_drr) &&
4207 			reserved_vblank_us >= blackout_us) {
4208 		/* vblank */
4209 		*surface_pstate_change_support = dml2_pstate_change_vblank;
4210 	} else if (method == dml2_pstate_method_fw_drr) {
4211 		/* drr */
4212 		*surface_pstate_change_support = dml2_pstate_change_drr;
4213 	} else if (method == dml2_pstate_method_alternate) {
4214 		/* TODO - alternate */
4215 		*surface_pstate_change_support = dml2_pstate_change_mall_svp;
4216 	}
4217 
4218 	return *surface_pstate_change_support != dml2_pstate_change_unsupported;
4219 }
4220 
dcn5_calculate_writeback_latency_hiding_us(const struct dml2_display_cfg * display_cfg,unsigned int writeback_buffer_size_bytes,unsigned int stream_index,unsigned int dwb_index)4221 static double dcn5_calculate_writeback_latency_hiding_us(
4222 		const struct dml2_display_cfg *display_cfg,
4223 		unsigned int writeback_buffer_size_bytes,
4224 		unsigned int stream_index,
4225 		unsigned int dwb_index)
4226 {
4227 	double byte_per_pixel_luma_in_buffer = 1.0;
4228 	double buffer_for_luma_bytes = (double)writeback_buffer_size_bytes * 1024.0;
4229 	double line_time_us = (double)display_cfg->stream_descriptors[stream_index].timing.h_total /
4230 			(double)display_cfg->stream_descriptors[stream_index].timing.pixel_clock_khz / 1000.0;
4231 
4232 	if (display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format == dml2_444_64) {
4233 		byte_per_pixel_luma_in_buffer = 8.0;
4234 	} else if (display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format == dml2_444_32) {
4235 		byte_per_pixel_luma_in_buffer = 4.0;
4236 	} else if (display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format == dml2_422_packed_8
4237 		|| display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format == dml2_420_8) {
4238 		byte_per_pixel_luma_in_buffer = 1.0;
4239 		buffer_for_luma_bytes = buffer_for_luma_bytes / 2.0;
4240 	} else if (display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format == dml2_422_packed_10
4241 		|| display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format == dml2_420_10) {
4242 		byte_per_pixel_luma_in_buffer = 10.0 / 8.0;
4243 	}
4244 
4245 	return (double)buffer_for_luma_bytes /
4246 			((double)display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].output_height *
4247 			(double)display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].output_width /
4248 			((double)display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].input_height *
4249 			line_time_us) * byte_per_pixel_luma_in_buffer);
4250 }
4251 
dcn5_calculate_watermarks_and_dram_speed_change_support(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params * p)4252 void dcn5_calculate_watermarks_and_dram_speed_change_support(
4253 		struct dml2_core_internal_scratch *scratch,
4254 		struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *p)
4255 {
4256 	struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals *s = &scratch->CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals;
4257 
4258 	double reserved_vblank_time_us;
4259 	bool FoundCriticalSurface = false;
4260 
4261 	s->TotalActiveWriteback = 0;
4262 	p->Watermark->UrgentWatermark = p->mmSOCParameters.UrgentLatency + p->mmSOCParameters.ExtraLatency;
4263 
4264 	DML_LOG_VERBOSE("DML::%s: UrgentLatency = %f\n", __func__, p->mmSOCParameters.UrgentLatency);
4265 	DML_LOG_VERBOSE("DML::%s: ExtraLatency = %f\n", __func__, p->mmSOCParameters.ExtraLatency);
4266 	DML_LOG_VERBOSE("DML::%s: UrgentWatermark = %f\n", __func__, p->Watermark->UrgentWatermark);
4267 
4268 	p->Watermark->USRRetrainingWatermark = p->mmSOCParameters.UrgentLatency + p->mmSOCParameters.ExtraLatency + p->mmSOCParameters.USRRetrainingLatency + p->mmSOCParameters.SMNLatency;
4269 	p->Watermark->DRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->Watermark->UrgentWatermark;
4270 	p->Watermark->FCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->Watermark->UrgentWatermark;
4271 	p->Watermark->StutterExitWatermark = p->mmSOCParameters.SRExitTime + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
4272 	p->Watermark->StutterEnterPlusExitWatermark = p->mmSOCParameters.SREnterPlusExitTime + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
4273 	p->Watermark->Z8StutterExitWatermark = p->mmSOCParameters.SRExitZ8Time + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
4274 	p->Watermark->Z8StutterEnterPlusExitWatermark = p->mmSOCParameters.SREnterPlusExitZ8Time + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
4275 	if (p->mmSOCParameters.qos_type == dml2_qos_param_type_dcn4x) {
4276 		p->Watermark->StutterExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
4277 		p->Watermark->StutterEnterPlusExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
4278 		p->Watermark->Z8StutterExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
4279 		p->Watermark->Z8StutterEnterPlusExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
4280 	}
4281 	p->Watermark->temp_read_or_ppt_watermark_us = p->mmSOCParameters.temp_read_or_ppt_blackout_us + p->Watermark->UrgentWatermark;
4282 
4283 	DML_LOG_VERBOSE("DML::%s: UrgentLatency = %f\n", __func__, p->mmSOCParameters.UrgentLatency);
4284 	DML_LOG_VERBOSE("DML::%s: ExtraLatency = %f\n", __func__, p->mmSOCParameters.ExtraLatency);
4285 	DML_LOG_VERBOSE("DML::%s: DRAMClockChangeLatency = %f\n", __func__, p->mmSOCParameters.DRAMClockChangeLatency);
4286 	DML_LOG_VERBOSE("DML::%s: SREnterPlusExitZ8Time = %f\n", __func__, p->mmSOCParameters.SREnterPlusExitZ8Time);
4287 	DML_LOG_VERBOSE("DML::%s: SREnterPlusExitTime = %f\n", __func__, p->mmSOCParameters.SREnterPlusExitTime);
4288 	DML_LOG_VERBOSE("DML::%s: UrgentWatermark = %f\n", __func__, p->Watermark->UrgentWatermark);
4289 	DML_LOG_VERBOSE("DML::%s: USRRetrainingWatermark = %f\n", __func__, p->Watermark->USRRetrainingWatermark);
4290 	DML_LOG_VERBOSE("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, p->Watermark->DRAMClockChangeWatermark);
4291 	DML_LOG_VERBOSE("DML::%s: FCLKChangeWatermark = %f\n", __func__, p->Watermark->FCLKChangeWatermark);
4292 	DML_LOG_VERBOSE("DML::%s: StutterExitWatermark = %f\n", __func__, p->Watermark->StutterExitWatermark);
4293 	DML_LOG_VERBOSE("DML::%s: StutterEnterPlusExitWatermark = %f\n", __func__, p->Watermark->StutterEnterPlusExitWatermark);
4294 	DML_LOG_VERBOSE("DML::%s: Z8StutterExitWatermark = %f\n", __func__, p->Watermark->Z8StutterExitWatermark);
4295 	DML_LOG_VERBOSE("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, p->Watermark->Z8StutterEnterPlusExitWatermark);
4296 	DML_LOG_VERBOSE("DML::%s: temp_read_or_ppt_watermark_us = %f\n", __func__, p->Watermark->temp_read_or_ppt_watermark_us);
4297 
4298 	s->TotalActiveWriteback = 0;
4299 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k)
4300 		if (p->display_cfg->plane_descriptors[k].stream_index == k)
4301 			s->TotalActiveWriteback = s->TotalActiveWriteback + p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream;
4302 
4303 	if (s->TotalActiveWriteback <= 1) {
4304 		p->Watermark->WritebackUrgentWatermark = p->mmSOCParameters.WritebackLatency;
4305 	} else {
4306 		p->Watermark->WritebackUrgentWatermark = p->mmSOCParameters.WritebackLatency + (s->TotalActiveWriteback - 1) * p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK;
4307 	}
4308 	if (p->USRRetrainingRequired)
4309 		p->Watermark->WritebackUrgentWatermark = p->Watermark->WritebackUrgentWatermark + p->mmSOCParameters.USRRetrainingLatency;
4310 
4311 	if (s->TotalActiveWriteback <= 1) {
4312 		p->Watermark->WritebackDRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.WritebackLatency;
4313 		p->Watermark->WritebackFCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->mmSOCParameters.WritebackLatency;
4314 	} else {
4315 		p->Watermark->WritebackDRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.WritebackLatency + (s->TotalActiveWriteback - 1) * p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK;
4316 		p->Watermark->WritebackFCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->mmSOCParameters.WritebackLatency + (s->TotalActiveWriteback - 1) * p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK;
4317 	}
4318 
4319 	if (p->USRRetrainingRequired)
4320 		p->Watermark->WritebackDRAMClockChangeWatermark = p->Watermark->WritebackDRAMClockChangeWatermark + p->mmSOCParameters.USRRetrainingLatency;
4321 
4322 	if (p->USRRetrainingRequired)
4323 		p->Watermark->WritebackFCLKChangeWatermark = p->Watermark->WritebackFCLKChangeWatermark + p->mmSOCParameters.USRRetrainingLatency;
4324 
4325 	if (s->TotalActiveWriteback <= 1) {
4326 		p->Watermark->writeback_temp_read_or_ppt_watermark_us = p->mmSOCParameters.temp_read_or_ppt_blackout_us;
4327 	} else {
4328 		p->Watermark->writeback_temp_read_or_ppt_watermark_us = p->mmSOCParameters.temp_read_or_ppt_blackout_us + (s->TotalActiveWriteback - 1) * p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK;
4329 	}
4330 
4331 	DML_LOG_VERBOSE("DML::%s: WritebackDRAMClockChangeWatermark = %f\n", __func__, p->Watermark->WritebackDRAMClockChangeWatermark);
4332 	DML_LOG_VERBOSE("DML::%s: WritebackFCLKChangeWatermark = %f\n", __func__, p->Watermark->WritebackFCLKChangeWatermark);
4333 	DML_LOG_VERBOSE("DML::%s: writeback_temp_read_or_ppt_watermark_us = %f\n", __func__, p->Watermark->writeback_temp_read_or_ppt_watermark_us);
4334 	DML_LOG_VERBOSE("DML::%s: WritebackUrgentWatermark = %f\n", __func__, p->Watermark->WritebackUrgentWatermark);
4335 	DML_LOG_VERBOSE("DML::%s: USRRetrainingRequired = %u\n", __func__, p->USRRetrainingRequired);
4336 	DML_LOG_VERBOSE("DML::%s: USRRetrainingLatency = %f\n", __func__, p->mmSOCParameters.USRRetrainingLatency);
4337 
4338 	s->TotalPixelBW = 0.0;
4339 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4340 		double h_total = (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total;
4341 		double pixel_clock_mhz = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000.0;
4342 		double v_ratio = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
4343 		double v_ratio_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
4344 		s->TotalPixelBW = s->TotalPixelBW + p->DPPPerSurface[k]
4345 								     * (p->SwathWidthY[k] * p->BytePerPixelDETY[k] * v_ratio + p->SwathWidthC[k] * p->BytePerPixelDETC[k] * v_ratio_c) / (h_total / pixel_clock_mhz);
4346 	}
4347 
4348 	*p->global_fclk_change_supported = true;
4349 	*p->global_dram_clock_change_supported = true;
4350 	*p->global_temp_read_or_ppt_supported = true;
4351 
4352 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4353 		double h_total = (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total;
4354 		double pixel_clock_mhz = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000.0;
4355 		double v_ratio = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
4356 		double v_ratio_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
4357 		double v_taps = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps;
4358 		double v_taps_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps;
4359 		double h_ratio = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio;
4360 		double h_ratio_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio;
4361 		double LBBitPerPixel = 57;
4362 
4363 		s->LBLatencyHidingSourceLinesY[k] = (unsigned int)(math_min2((double)p->MaxLineBufferLines, math_floor2((double)p->LineBufferSize / LBBitPerPixel / ((double)p->SwathWidthY[k] / math_max2(h_ratio, 1.0)), 1)) - (v_taps - 1));
4364 		s->LBLatencyHidingSourceLinesC[k] = (unsigned int)(math_min2((double)p->MaxLineBufferLines, math_floor2((double)p->LineBufferSize / LBBitPerPixel / ((double)p->SwathWidthC[k] / math_max2(h_ratio_c, 1.0)), 1)) - (v_taps_c - 1));
4365 
4366 		DML_LOG_VERBOSE("DML::%s: k=%u, MaxLineBufferLines= %u\n", __func__, k, p->MaxLineBufferLines);
4367 		DML_LOG_VERBOSE("DML::%s: k=%u, LineBufferSize = %u\n", __func__, k, p->LineBufferSize);
4368 		DML_LOG_VERBOSE("DML::%s: k=%u, LBBitPerPixel = %f\n", __func__, k, LBBitPerPixel);
4369 		DML_LOG_VERBOSE("DML::%s: k=%u, HRatio = %f\n", __func__, k, h_ratio);
4370 		DML_LOG_VERBOSE("DML::%s: k=%u, VTaps = %f\n", __func__, k, v_taps);
4371 
4372 		s->EffectiveLBLatencyHidingY = s->LBLatencyHidingSourceLinesY[k] / v_ratio * (h_total / pixel_clock_mhz);
4373 		s->EffectiveLBLatencyHidingC = s->LBLatencyHidingSourceLinesC[k] / v_ratio_c * (h_total / pixel_clock_mhz);
4374 
4375 		s->EffectiveDETBufferSizeY = p->DETBufferSizeY[k];
4376 		if (p->UnboundedRequestEnabled) {
4377 			s->EffectiveDETBufferSizeY = s->EffectiveDETBufferSizeY + p->CompressedBufferSizeInkByte * 1024 * (p->SwathWidthY[k] * p->BytePerPixelDETY[k] * v_ratio) / (h_total / pixel_clock_mhz) / s->TotalPixelBW;
4378 		}
4379 
4380 		s->LinesInDETY[k] = (double)s->EffectiveDETBufferSizeY / p->BytePerPixelDETY[k] / p->SwathWidthY[k];
4381 		s->LinesInDETYRoundedDownToSwath[k] = (unsigned int)(math_floor2(s->LinesInDETY[k], p->SwathHeightY[k]));
4382 		s->FullDETBufferingTimeY = s->LinesInDETYRoundedDownToSwath[k] * (h_total / pixel_clock_mhz) / v_ratio;
4383 
4384 		s->ActiveClockChangeLatencyHidingY = s->EffectiveLBLatencyHidingY + s->FullDETBufferingTimeY - ((double)p->DSTXAfterScaler[k] / h_total + (double)p->DSTYAfterScaler[k]) * h_total / pixel_clock_mhz;
4385 
4386 		if (p->NumberOfActiveSurfaces > 1) {
4387 			s->ActiveClockChangeLatencyHidingY = s->ActiveClockChangeLatencyHidingY - (1.0 - 1.0 / (double)p->NumberOfActiveSurfaces) * (double)p->SwathHeightY[k] * (double)h_total / pixel_clock_mhz / v_ratio;
4388 		}
4389 
4390 		if (p->BytePerPixelDETC[k] > 0) {
4391 			s->LinesInDETC[k] = p->DETBufferSizeC[k] / p->BytePerPixelDETC[k] / p->SwathWidthC[k];
4392 			s->LinesInDETCRoundedDownToSwath[k] = (unsigned int)(math_floor2(s->LinesInDETC[k], p->SwathHeightC[k]));
4393 			s->FullDETBufferingTimeC = s->LinesInDETCRoundedDownToSwath[k] * (h_total / pixel_clock_mhz) / v_ratio_c;
4394 			s->ActiveClockChangeLatencyHidingC = s->EffectiveLBLatencyHidingC + s->FullDETBufferingTimeC - ((double)p->DSTXAfterScaler[k] / (double)h_total + (double)p->DSTYAfterScaler[k]) * (double)h_total / pixel_clock_mhz;
4395 			if (p->NumberOfActiveSurfaces > 1) {
4396 				s->ActiveClockChangeLatencyHidingC = s->ActiveClockChangeLatencyHidingC - (1.0 - 1.0 / (double)p->NumberOfActiveSurfaces) * (double)p->SwathHeightC[k] * (double)h_total / pixel_clock_mhz / v_ratio_c;
4397 			}
4398 			s->ActiveClockChangeLatencyHiding = math_min2(s->ActiveClockChangeLatencyHidingY, s->ActiveClockChangeLatencyHidingC);
4399 		} else {
4400 			s->ActiveClockChangeLatencyHiding = s->ActiveClockChangeLatencyHidingY;
4401 		}
4402 
4403 		DML_LOG_VERBOSE("DML::%s: ActiveClockChangeLatencyHidingY = %f\n", __func__, s->ActiveClockChangeLatencyHidingY);
4404 		DML_LOG_VERBOSE("DML::%s: ActiveClockChangeLatencyHidingC = %f\n", __func__, s->ActiveClockChangeLatencyHidingC);
4405 		DML_LOG_VERBOSE("DML::%s: ActiveClockChangeLatencyHiding = %f\n", __func__, s->ActiveClockChangeLatencyHiding);
4406 
4407 		s->ActiveDRAMClockChangeLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->DRAMClockChangeWatermark;
4408 		s->ActiveFCLKChangeLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->FCLKChangeWatermark;
4409 		s->USRRetrainingLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->USRRetrainingWatermark;
4410 		s->temp_read_or_ppt_latency_margin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->temp_read_or_ppt_watermark_us;
4411 
4412 		DML_LOG_VERBOSE("DML::%s: k=%u, ActiveFCLKChangeLatencyMargin = %f\n", __func__, k, s->ActiveFCLKChangeLatencyMargin[k]);
4413 		DML_LOG_VERBOSE("DML::%s: k=%u, ActiveDRAMClockChangeLatencyMargin = %f\n", __func__, k, s->ActiveDRAMClockChangeLatencyMargin[k]);
4414 
4415 		if (p->VActiveLatencyHidingMargin) {
4416 			p->VActiveLatencyHidingMargin[k] = s->ActiveDRAMClockChangeLatencyMargin[k];
4417 			DML_LOG_VERBOSE("DML::%s: k=%u, VActiveLatencyHidingMargin = %f\n", __func__, k, p->VActiveLatencyHidingMargin[k]);
4418 		}
4419 
4420 		if (p->VActiveLatencyHidingUs) {
4421 			p->VActiveLatencyHidingUs[k] = s->ActiveClockChangeLatencyHiding;
4422 			DML_LOG_VERBOSE("DML::%s: k=%u, VActiveLatencyHidingUs = %f\n", __func__, k, p->VActiveLatencyHidingUs[k]);
4423 		}
4424 
4425 		for (unsigned int j = 0; j < p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream; ++j) {
4426 			s->WritebackLatencyHiding = dcn5_calculate_writeback_latency_hiding_us(p->display_cfg,
4427 					p->WritebackInterfaceBufferSize * 1024,
4428 					p->display_cfg->plane_descriptors[k].stream_index,
4429 					j);
4430 
4431 			s->WritebackDRAMClockChangeLatencyMargin = s->WritebackLatencyHiding - p->Watermark->WritebackDRAMClockChangeWatermark;
4432 			s->WritebackFCLKChangeLatencyMargin = s->WritebackLatencyHiding - p->Watermark->WritebackFCLKChangeWatermark;
4433 			s->WritebackTempReadOrPptLatencyMargin = s->WritebackLatencyHiding - p->Watermark->writeback_temp_read_or_ppt_watermark_us;
4434 			s->ActiveDRAMClockChangeLatencyMargin[k] = math_min2(s->ActiveDRAMClockChangeLatencyMargin[k], s->WritebackDRAMClockChangeLatencyMargin);
4435 			s->ActiveFCLKChangeLatencyMargin[k] = math_min2(s->ActiveFCLKChangeLatencyMargin[k], s->WritebackFCLKChangeLatencyMargin);
4436 			s->temp_read_or_ppt_latency_margin[k] = math_min2(s->temp_read_or_ppt_latency_margin[k], s->WritebackTempReadOrPptLatencyMargin);
4437 			DML_LOG_VERBOSE("DML::%s: k=%u, ActiveFCLKChangeLatencyMargin = %f (WB)\n", __func__, k, s->ActiveFCLKChangeLatencyMargin[k]);
4438 		}
4439 
4440 		p->MaxActiveDRAMClockChangeLatencySupported[k] = s->ActiveDRAMClockChangeLatencyMargin[k] + p->mmSOCParameters.DRAMClockChangeLatency;
4441 
4442 		reserved_vblank_time_us = (double)p->display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns / 1000;
4443 
4444 		*p->global_fclk_change_supported &= dcn5_calculate_pstate_support_method(
4445 				dml2_pstate_method_vactive,
4446 				s->ActiveFCLKChangeLatencyMargin[k],
4447 				reserved_vblank_time_us,
4448 				p->mmSOCParameters.FCLKChangeLatency,
4449 				p->display_cfg->overrides.all_streams_blanked,
4450 				/* output */
4451 				&p->FCLKChangeSupport[k]);
4452 
4453 		*p->global_temp_read_or_ppt_supported &= dcn5_calculate_pstate_support_method(
4454 				dml2_pstate_method_vactive,
4455 				s->temp_read_or_ppt_latency_margin[k],
4456 				reserved_vblank_time_us,
4457 				p->mmSOCParameters.temp_read_or_ppt_blackout_us,
4458 				p->display_cfg->overrides.all_streams_blanked,
4459 				/* output */
4460 				&p->temp_read_or_ppt_support[k]);
4461 
4462 		*p->global_dram_clock_change_support_required |= p->uclk_pstate_switch_modes[k] != dml2_pstate_method_na;
4463 		*p->global_dram_clock_change_supported &= dcn5_calculate_pstate_support_method(
4464 				p->uclk_pstate_switch_modes[k],
4465 				s->ActiveDRAMClockChangeLatencyMargin[k],
4466 				reserved_vblank_time_us,
4467 				p->mmSOCParameters.DRAMClockChangeLatency,
4468 				p->display_cfg->overrides.all_streams_blanked,
4469 				/* output */
4470 				&p->DRAMClockChangeSupport[k]);
4471 
4472 		s->dst_y_pstate = (unsigned int)(math_ceil2((p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.UrgentLatency) / (h_total / pixel_clock_mhz), 1));
4473 		s->src_y_pstate_l = (unsigned int)(math_ceil2(s->dst_y_pstate * v_ratio, p->SwathHeightY[k]));
4474 		s->src_y_ahead_l = (unsigned int)(math_floor2(p->DETBufferSizeY[k] / p->BytePerPixelDETY[k] / p->SwathWidthY[k], p->SwathHeightY[k]) + s->LBLatencyHidingSourceLinesY[k]);
4475 
4476 		DML_LOG_VERBOSE("DML::%s: k=%u, DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]);
4477 		DML_LOG_VERBOSE("DML::%s: k=%u, BytePerPixelDETY = %f\n", __func__, k, p->BytePerPixelDETY[k]);
4478 		DML_LOG_VERBOSE("DML::%s: k=%u, SwathWidthY = %u\n", __func__, k, p->SwathWidthY[k]);
4479 		DML_LOG_VERBOSE("DML::%s: k=%u, SwathHeightY = %u\n", __func__, k, p->SwathHeightY[k]);
4480 		DML_LOG_VERBOSE("DML::%s: k=%u, LBLatencyHidingSourceLinesY = %u\n", __func__, k, s->LBLatencyHidingSourceLinesY[k]);
4481 		DML_LOG_VERBOSE("DML::%s: k=%u, dst_y_pstate = %u\n", __func__, k, s->dst_y_pstate);
4482 		DML_LOG_VERBOSE("DML::%s: k=%u, src_y_pstate_l = %u\n", __func__, k, s->src_y_pstate_l);
4483 		DML_LOG_VERBOSE("DML::%s: k=%u, src_y_ahead_l = %u\n", __func__, k, s->src_y_ahead_l);
4484 		DML_LOG_VERBOSE("DML::%s: k=%u, meta_row_height_l = %u\n", __func__, k, p->meta_row_height_l[k]);
4485 
4486 		if (p->BytePerPixelDETC[k] > 0) {
4487 			s->src_y_pstate_c = (unsigned int)(math_ceil2(s->dst_y_pstate * v_ratio_c, p->SwathHeightC[k]));
4488 			s->src_y_ahead_c = (unsigned int)(math_floor2(p->DETBufferSizeC[k] / p->BytePerPixelDETC[k] / p->SwathWidthC[k], p->SwathHeightC[k]) + s->LBLatencyHidingSourceLinesC[k]);
4489 
4490 			DML_LOG_VERBOSE("DML::%s: k=%u, meta_row_height_c = %u\n", __func__, k, p->meta_row_height_c[k]);
4491 			DML_LOG_VERBOSE("DML::%s: k=%u, src_y_pstate_c = %u\n", __func__, k, s->src_y_pstate_c);
4492 			DML_LOG_VERBOSE("DML::%s: k=%u, src_y_ahead_c = %u\n", __func__, k, s->src_y_ahead_c);
4493 			DML_LOG_VERBOSE("DML::%s: k=%u, sub_vp_lines_c = %u\n", __func__, k, s->sub_vp_lines_c);
4494 		}
4495 	}
4496 
4497 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4498 		DML_LOG_VERBOSE("DML::%s: k=%u, ActiveFCLKChangeLatencyMargin=%f\n", __func__, k, s->ActiveFCLKChangeLatencyMargin[k]);
4499 		if (((!FoundCriticalSurface) || ((s->ActiveFCLKChangeLatencyMargin[k] + p->mmSOCParameters.FCLKChangeLatency) < *p->MaxActiveFCLKChangeLatencySupported))) {
4500 			FoundCriticalSurface = true;
4501 			*p->MaxActiveFCLKChangeLatencySupported = s->ActiveFCLKChangeLatencyMargin[k] + p->mmSOCParameters.FCLKChangeLatency;
4502 		}
4503 	}
4504 
4505 	DML_LOG_VERBOSE("DML::%s: DRAMClockChangeSupport = %u\n", __func__, *p->global_dram_clock_change_supported);
4506 	DML_LOG_VERBOSE("DML::%s: FCLKChangeSupport = %u\n", __func__, *p->global_fclk_change_supported);
4507 	DML_LOG_VERBOSE("DML::%s: MaxActiveFCLKChangeLatencySupported = %f\n", __func__, *p->MaxActiveFCLKChangeLatencySupported);
4508 	DML_LOG_VERBOSE("DML::%s: USRRetrainingSupport = %u\n", __func__, *p->USRRetrainingSupport);
4509 }
4510 
dcn5_calculate_pstate_keepout_dst_lines(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_watermarks * watermarks,unsigned int pstate_keepout_dst_lines[])4511 void dcn5_calculate_pstate_keepout_dst_lines(
4512 		const struct dml2_display_cfg *display_cfg,
4513 		const struct dml2_core_internal_watermarks *watermarks,
4514 		unsigned int pstate_keepout_dst_lines[])
4515 {
4516 	const struct dml2_stream_parameters *stream_descriptor;
4517 	unsigned int i;
4518 
4519 	for (i = 0; i < display_cfg->num_planes; i++) {
4520 		(void)display_cfg;
4521 		stream_descriptor = &display_cfg->stream_descriptors[display_cfg->plane_descriptors[i].stream_index];
4522 
4523 		pstate_keepout_dst_lines[i] =
4524 				(unsigned int)math_ceil(watermarks->DRAMClockChangeWatermark / ((double)stream_descriptor->timing.h_total * 1000.0 / (double)stream_descriptor->timing.pixel_clock_khz));
4525 
4526 		if (pstate_keepout_dst_lines[i] > stream_descriptor->timing.v_total - 1) {
4527 			pstate_keepout_dst_lines[i] = stream_descriptor->timing.v_total - 1;
4528 		}
4529 	}
4530 }
4531 
dcn5_calculate_vactive_det_fill_latency(const struct dml2_display_cfg * display_cfg,unsigned int num_active_planes,unsigned int bytes_required_l[],unsigned int bytes_required_c[],double dcc_dram_bw_nom_overhead_factor_p0[],double dcc_dram_bw_nom_overhead_factor_p1[],double surface_read_bw_l[],double surface_read_bw_c[],double surface_avg_vactive_required_bw[],double surface_peak_required_bw[],double vactive_det_fill_delay_us[])4532 void dcn5_calculate_vactive_det_fill_latency(
4533 		const struct dml2_display_cfg *display_cfg,
4534 		unsigned int num_active_planes,
4535 		unsigned int bytes_required_l[],
4536 		unsigned int bytes_required_c[],
4537 		double dcc_dram_bw_nom_overhead_factor_p0[],
4538 		double dcc_dram_bw_nom_overhead_factor_p1[],
4539 		double surface_read_bw_l[],
4540 		double surface_read_bw_c[],
4541 		double surface_avg_vactive_required_bw[],
4542 		double surface_peak_required_bw[],
4543 		/* output */
4544 		double vactive_det_fill_delay_us[])
4545 {
4546 	(void)display_cfg;
4547 	double effective_excess_bandwidth;
4548 	double effective_excess_bandwidth_l;
4549 	double effective_excess_bandwidth_c;
4550 	unsigned int plane_index;
4551 
4552 	for (plane_index = 0; plane_index < num_active_planes; plane_index++) {
4553 		if (bytes_required_l[plane_index] <= 0 && bytes_required_c[plane_index] <= 0) {
4554 			continue;
4555 		}
4556 
4557 		vactive_det_fill_delay_us[plane_index] = 0.0;
4558 		effective_excess_bandwidth = (surface_peak_required_bw[plane_index] - surface_avg_vactive_required_bw[plane_index]);
4559 
4560 		effective_excess_bandwidth_l = effective_excess_bandwidth * surface_read_bw_l[plane_index]
4561 			/ (surface_read_bw_l[plane_index] + surface_read_bw_c[plane_index]) / dcc_dram_bw_nom_overhead_factor_p0[plane_index];
4562 		if (effective_excess_bandwidth_l > 0.0) {
4563 			vactive_det_fill_delay_us[plane_index] = math_max2(vactive_det_fill_delay_us[plane_index], bytes_required_l[plane_index] / effective_excess_bandwidth_l);
4564 		}
4565 
4566 		effective_excess_bandwidth_c = effective_excess_bandwidth * surface_read_bw_c[plane_index]
4567 			/ (surface_read_bw_l[plane_index] + surface_read_bw_c[plane_index]) / dcc_dram_bw_nom_overhead_factor_p1[plane_index];
4568 		if (effective_excess_bandwidth_c > 0.0) {
4569 			vactive_det_fill_delay_us[plane_index] = math_max2(vactive_det_fill_delay_us[plane_index], bytes_required_c[plane_index] / effective_excess_bandwidth_c);
4570 		}
4571 	}
4572 }
4573 
dcn5_calculate_write_back_delay(enum dml2_source_format_class WritebackPixelFormat,double WritebackHRatio,double WritebackVRatio,unsigned int WritebackVTaps,unsigned int WritebackVTapsChroma,unsigned int WritebackDestinationWidth,unsigned int WritebackDestinationHeight,unsigned int WritebackSourceWidth,unsigned int WritebackSourceHeight,unsigned int HTotal)4574 double dcn5_calculate_write_back_delay(
4575 		enum dml2_source_format_class WritebackPixelFormat,
4576 		double WritebackHRatio,
4577 		double WritebackVRatio,
4578 		unsigned int WritebackVTaps,
4579 		unsigned int WritebackVTapsChroma,
4580 		unsigned int WritebackDestinationWidth,
4581 		unsigned int WritebackDestinationHeight,
4582 		unsigned int WritebackSourceWidth,
4583 		unsigned int WritebackSourceHeight,
4584 		unsigned int HTotal)
4585 {
4586 	(void)WritebackHRatio;
4587 	double CalculateWriteBackDelay;
4588 	double Line_length;
4589 	double Output_lines_last_notclamped;
4590 	double WritebackVInit;
4591 
4592 	WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2;
4593 	Line_length = math_max2((double)WritebackDestinationWidth, math_ceil2((double)WritebackDestinationWidth / 6.0, 1.0) * WritebackVTaps);
4594 	Output_lines_last_notclamped = WritebackDestinationHeight - 1 - math_ceil2(((double)WritebackSourceHeight - (double)WritebackVInit) / (double)WritebackVRatio, 1.0);
4595 	if (Output_lines_last_notclamped < 0)
4596 		CalculateWriteBackDelay = 0;
4597 	else
4598 		CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackSourceWidth) + 80;
4599 
4600 	double v_ratio_chroma;
4601 	double output_width_chroma;
4602 	double output_height_chroma;
4603 
4604 	if (WritebackPixelFormat == dml2_420_8 || WritebackPixelFormat == dml2_422_packed_8
4605 		|| WritebackPixelFormat == dml2_420_10 || WritebackPixelFormat == dml2_422_packed_10)
4606 		output_width_chroma = 0.5 * WritebackDestinationWidth;
4607 	else
4608 		output_width_chroma = WritebackDestinationWidth;
4609 
4610 	if (WritebackPixelFormat == dml2_420_8 || WritebackPixelFormat == dml2_420_10) {
4611 		v_ratio_chroma = 2.0 * WritebackVRatio;
4612 		output_height_chroma = 0.5 * WritebackDestinationHeight;
4613 	} else {
4614 		v_ratio_chroma = WritebackVRatio;
4615 		output_height_chroma = WritebackDestinationHeight;
4616 	}
4617 
4618 	double CalculateWriteBackDelay_chroma;
4619 	double Line_length_chroma;
4620 	double Output_lines_last_notclamped_chroma;
4621 	double WritebackVInit_chroma;
4622 
4623 	WritebackVInit_chroma = (v_ratio_chroma + WritebackVTapsChroma + 1) / 2;
4624 	Line_length_chroma = math_max2((double)output_height_chroma, math_ceil2((double)output_width_chroma / 6.0, 1.0) * WritebackVTapsChroma);
4625 	Output_lines_last_notclamped_chroma = output_height_chroma - 1 - math_ceil2(((double)WritebackSourceHeight - (double)WritebackVInit_chroma) / (double)v_ratio_chroma, 1.0);
4626 	if (Output_lines_last_notclamped_chroma < 0)
4627 		CalculateWriteBackDelay_chroma = 0;
4628 	else
4629 		CalculateWriteBackDelay_chroma = Output_lines_last_notclamped_chroma * Line_length_chroma + (HTotal - WritebackSourceWidth) + 80;
4630 
4631 	return math_max2(CalculateWriteBackDelay, CalculateWriteBackDelay_chroma);
4632 }
4633 
dcn5_calculate_meta_and_pte_times(struct dml2_core_shared_CalculateMetaAndPTETimes_params * p)4634 void dcn5_calculate_meta_and_pte_times(struct dml2_core_shared_CalculateMetaAndPTETimes_params *p)
4635 {
4636 	unsigned int meta_chunk_width;
4637 	unsigned int min_meta_chunk_width;
4638 	unsigned int meta_chunk_per_row_int;
4639 	unsigned int meta_row_remainder;
4640 	unsigned int meta_chunk_threshold;
4641 	unsigned int meta_chunks_per_row_ub;
4642 	unsigned int meta_chunk_width_chroma;
4643 	unsigned int min_meta_chunk_width_chroma;
4644 	unsigned int meta_chunk_per_row_int_chroma;
4645 	unsigned int meta_row_remainder_chroma;
4646 	unsigned int meta_chunk_threshold_chroma;
4647 	unsigned int meta_chunks_per_row_ub_chroma;
4648 	unsigned int dpte_group_width_luma;
4649 	unsigned int dpte_groups_per_row_luma_ub;
4650 	unsigned int dpte_group_width_chroma;
4651 	unsigned int dpte_groups_per_row_chroma_ub;
4652 	double pixel_clock_mhz;
4653 
4654 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4655 		p->DST_Y_PER_PTE_ROW_NOM_L[k] = p->dpte_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
4656 		if (p->BytePerPixelC[k] == 0) {
4657 			p->DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
4658 		} else {
4659 			p->DST_Y_PER_PTE_ROW_NOM_C[k] = p->dpte_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
4660 		}
4661 		p->DST_Y_PER_META_ROW_NOM_L[k] = p->meta_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
4662 		if (p->BytePerPixelC[k] == 0) {
4663 			p->DST_Y_PER_META_ROW_NOM_C[k] = 0;
4664 		} else {
4665 			p->DST_Y_PER_META_ROW_NOM_C[k] = p->meta_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
4666 		}
4667 	}
4668 
4669 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4670 		if (p->display_cfg->plane_descriptors[k].surface.dcc.enable == true && p->mrq_present) {
4671 			meta_chunk_width = p->MetaChunkSize * 1024 * 256 / p->BytePerPixelY[k] / p->meta_row_height[k];
4672 			min_meta_chunk_width = p->MinMetaChunkSizeBytes * 256 / p->BytePerPixelY[k] / p->meta_row_height[k];
4673 			meta_chunk_per_row_int = p->meta_row_width[k] / meta_chunk_width;
4674 			meta_row_remainder = p->meta_row_width[k] % meta_chunk_width;
4675 			if (!dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) {
4676 				meta_chunk_threshold = 2 * min_meta_chunk_width - p->meta_req_width[k];
4677 			} else {
4678 				meta_chunk_threshold = 2 * min_meta_chunk_width - p->meta_req_height[k];
4679 			}
4680 			if (meta_row_remainder <= meta_chunk_threshold) {
4681 				meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
4682 			} else {
4683 				meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
4684 			}
4685 			p->TimePerMetaChunkNominal[k] = p->meta_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio *
4686 					p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total /
4687 					(p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub;
4688 			p->TimePerMetaChunkVBlank[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total /
4689 					(p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub;
4690 			p->TimePerMetaChunkFlip[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total /
4691 					(p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub;
4692 			if (p->BytePerPixelC[k] == 0) {
4693 				p->TimePerChromaMetaChunkNominal[k] = 0;
4694 				p->TimePerChromaMetaChunkVBlank[k] = 0;
4695 				p->TimePerChromaMetaChunkFlip[k] = 0;
4696 			} else {
4697 				meta_chunk_width_chroma = p->MetaChunkSize * 1024 * 256 / p->BytePerPixelC[k] / p->meta_row_height_chroma[k];
4698 				min_meta_chunk_width_chroma = p->MinMetaChunkSizeBytes * 256 / p->BytePerPixelC[k] / p->meta_row_height_chroma[k];
4699 				meta_chunk_per_row_int_chroma = (unsigned int)((double)p->meta_row_width_chroma[k] / meta_chunk_width_chroma);
4700 				meta_row_remainder_chroma = p->meta_row_width_chroma[k] % meta_chunk_width_chroma;
4701 				if (!dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) {
4702 					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - p->meta_req_width_chroma[k];
4703 				} else {
4704 					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - p->meta_req_height_chroma[k];
4705 				}
4706 				if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) {
4707 					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1;
4708 				} else {
4709 					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2;
4710 				}
4711 				p->TimePerChromaMetaChunkNominal[k] = p->meta_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub_chroma;
4712 				p->TimePerChromaMetaChunkVBlank[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub_chroma;
4713 				p->TimePerChromaMetaChunkFlip[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub_chroma;
4714 			}
4715 		} else {
4716 			p->TimePerMetaChunkNominal[k] = 0;
4717 			p->TimePerMetaChunkVBlank[k] = 0;
4718 			p->TimePerMetaChunkFlip[k] = 0;
4719 			p->TimePerChromaMetaChunkNominal[k] = 0;
4720 			p->TimePerChromaMetaChunkVBlank[k] = 0;
4721 			p->TimePerChromaMetaChunkFlip[k] = 0;
4722 		}
4723 
4724 		DML_LOG_VERBOSE("DML::%s: k=%d, DST_Y_PER_META_ROW_NOM_L = %f\n", __func__, k, p->DST_Y_PER_META_ROW_NOM_L[k]);
4725 		DML_LOG_VERBOSE("DML::%s: k=%d, DST_Y_PER_META_ROW_NOM_C = %f\n", __func__, k, p->DST_Y_PER_META_ROW_NOM_C[k]);
4726 		DML_LOG_VERBOSE("DML::%s: k=%d, TimePerMetaChunkNominal  = %f\n", __func__, k, p->TimePerMetaChunkNominal[k]);
4727 		DML_LOG_VERBOSE("DML::%s: k=%d, TimePerMetaChunkVBlank	 = %f\n", __func__, k, p->TimePerMetaChunkVBlank[k]);
4728 		DML_LOG_VERBOSE("DML::%s: k=%d, TimePerMetaChunkFlip		 = %f\n", __func__, k, p->TimePerMetaChunkFlip[k]);
4729 		DML_LOG_VERBOSE("DML::%s: k=%d, TimePerChromaMetaChunkNominal= %f\n", __func__, k, p->TimePerChromaMetaChunkNominal[k]);
4730 		DML_LOG_VERBOSE("DML::%s: k=%d, TimePerChromaMetaChunkVBlank = %f\n", __func__, k, p->TimePerChromaMetaChunkVBlank[k]);
4731 		DML_LOG_VERBOSE("DML::%s: k=%d, TimePerChromaMetaChunkFlip	 = %f\n", __func__, k, p->TimePerChromaMetaChunkFlip[k]);
4732 	}
4733 
4734 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4735 		p->DST_Y_PER_PTE_ROW_NOM_L[k] = p->dpte_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
4736 		if (p->BytePerPixelC[k] == 0) {
4737 			p->DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
4738 		} else {
4739 			p->DST_Y_PER_PTE_ROW_NOM_C[k] = p->dpte_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
4740 		}
4741 	}
4742 
4743 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4744 		pixel_clock_mhz = ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
4745 
4746 		if (p->display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut)
4747 			p->time_per_tdlut_group[k] = 2 * p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / p->tdlut_groups_per_2row_ub[k];
4748 		else
4749 			p->time_per_tdlut_group[k] = 0;
4750 
4751 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_tdlut_group = %f\n", __func__, k, p->time_per_tdlut_group[k]);
4752 
4753 		if (p->display_cfg->gpuvm_enable == true) {
4754 			if (!dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) {
4755 				dpte_group_width_luma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeY[k] * p->PixelPTEReqWidthY[k]);
4756 			} else {
4757 				dpte_group_width_luma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeY[k] * p->PixelPTEReqHeightY[k]);
4758 			}
4759 			if (p->use_one_row_for_frame[k]) {
4760 				dpte_groups_per_row_luma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_luma_ub[k] / (double)dpte_group_width_luma / 2.0, 1.0));
4761 			} else {
4762 				dpte_groups_per_row_luma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_luma_ub[k] / (double)dpte_group_width_luma, 1.0));
4763 			}
4764 			if (dpte_groups_per_row_luma_ub <= 2) {
4765 				dpte_groups_per_row_luma_ub = dpte_groups_per_row_luma_ub + 1;
4766 			}
4767 			DML_LOG_VERBOSE("DML::%s: k=%u, use_one_row_for_frame = %u\n", __func__, k, p->use_one_row_for_frame[k]);
4768 			DML_LOG_VERBOSE("DML::%s: k=%u, dpte_group_bytes = %u\n", __func__, k, p->dpte_group_bytes[k]);
4769 			DML_LOG_VERBOSE("DML::%s: k=%u, PTERequestSizeY = %u\n", __func__, k, p->PTERequestSizeY[k]);
4770 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEReqWidthY = %u\n", __func__, k, p->PixelPTEReqWidthY[k]);
4771 			DML_LOG_VERBOSE("DML::%s: k=%u, PixelPTEReqHeightY = %u\n", __func__, k, p->PixelPTEReqHeightY[k]);
4772 			DML_LOG_VERBOSE("DML::%s: k=%u, dpte_row_width_luma_ub = %u\n", __func__, k, p->dpte_row_width_luma_ub[k]);
4773 			DML_LOG_VERBOSE("DML::%s: k=%u, dpte_group_width_luma = %u\n", __func__, k, dpte_group_width_luma);
4774 			DML_LOG_VERBOSE("DML::%s: k=%u, dpte_groups_per_row_luma_ub = %u\n", __func__, k, dpte_groups_per_row_luma_ub);
4775 
4776 			p->time_per_pte_group_nom_luma[k] = p->DST_Y_PER_PTE_ROW_NOM_L[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_luma_ub;
4777 			p->time_per_pte_group_vblank_luma[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_luma_ub;
4778 			p->time_per_pte_group_flip_luma[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_luma_ub;
4779 			if (p->BytePerPixelC[k] == 0) {
4780 				p->time_per_pte_group_nom_chroma[k] = 0;
4781 				p->time_per_pte_group_vblank_chroma[k] = 0;
4782 				p->time_per_pte_group_flip_chroma[k] = 0;
4783 			} else {
4784 				if (!dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) {
4785 					dpte_group_width_chroma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeC[k] * p->PixelPTEReqWidthC[k]);
4786 				} else {
4787 					dpte_group_width_chroma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeC[k] * p->PixelPTEReqHeightC[k]);
4788 				}
4789 
4790 				if (p->use_one_row_for_frame[k]) {
4791 					dpte_groups_per_row_chroma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_chroma_ub[k] / (double)dpte_group_width_chroma / 2.0, 1.0));
4792 				} else {
4793 					dpte_groups_per_row_chroma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_chroma_ub[k] / (double)dpte_group_width_chroma, 1.0));
4794 				}
4795 				if (dpte_groups_per_row_chroma_ub <= 2) {
4796 					dpte_groups_per_row_chroma_ub = dpte_groups_per_row_chroma_ub + 1;
4797 				}
4798 				DML_LOG_VERBOSE("DML::%s: k=%u, dpte_row_width_chroma_ub = %u\n", __func__, k, p->dpte_row_width_chroma_ub[k]);
4799 				DML_LOG_VERBOSE("DML::%s: k=%u, dpte_group_width_chroma = %u\n", __func__, k, dpte_group_width_chroma);
4800 				DML_LOG_VERBOSE("DML::%s: k=%u, dpte_groups_per_row_chroma_ub = %u\n", __func__, k, dpte_groups_per_row_chroma_ub);
4801 
4802 				p->time_per_pte_group_nom_chroma[k] = p->DST_Y_PER_PTE_ROW_NOM_C[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_chroma_ub;
4803 				p->time_per_pte_group_vblank_chroma[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_chroma_ub;
4804 				p->time_per_pte_group_flip_chroma[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_chroma_ub;
4805 			}
4806 		} else {
4807 			p->time_per_pte_group_nom_luma[k] = 0;
4808 			p->time_per_pte_group_vblank_luma[k] = 0;
4809 			p->time_per_pte_group_flip_luma[k] = 0;
4810 			p->time_per_pte_group_nom_chroma[k] = 0;
4811 			p->time_per_pte_group_vblank_chroma[k] = 0;
4812 			p->time_per_pte_group_flip_chroma[k] = 0;
4813 		}
4814 		DML_LOG_VERBOSE("DML::%s: k=%u, dst_y_per_row_vblank = %f\n", __func__, k, p->dst_y_per_row_vblank[k]);
4815 		DML_LOG_VERBOSE("DML::%s: k=%u, dst_y_per_row_flip = %f\n", __func__, k, p->dst_y_per_row_flip[k]);
4816 
4817 		DML_LOG_VERBOSE("DML::%s: k=%u, DST_Y_PER_PTE_ROW_NOM_L = %f\n", __func__, k, p->DST_Y_PER_PTE_ROW_NOM_L[k]);
4818 		DML_LOG_VERBOSE("DML::%s: k=%u, DST_Y_PER_PTE_ROW_NOM_C = %f\n", __func__, k, p->DST_Y_PER_PTE_ROW_NOM_C[k]);
4819 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_pte_group_nom_luma = %f\n", __func__, k, p->time_per_pte_group_nom_luma[k]);
4820 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_pte_group_vblank_luma = %f\n", __func__, k, p->time_per_pte_group_vblank_luma[k]);
4821 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_pte_group_flip_luma = %f\n", __func__, k, p->time_per_pte_group_flip_luma[k]);
4822 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_pte_group_nom_chroma = %f\n", __func__, k, p->time_per_pte_group_nom_chroma[k]);
4823 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_pte_group_vblank_chroma = %f\n", __func__, k, p->time_per_pte_group_vblank_chroma[k]);
4824 		DML_LOG_VERBOSE("DML::%s: k=%u, time_per_pte_group_flip_chroma = %f\n", __func__, k, p->time_per_pte_group_flip_chroma[k]);
4825 	}
4826 }
4827 
dcn5_calculate_vm_group_and_request_times(const struct dml2_display_cfg * display_cfg,unsigned int NumberOfActiveSurfaces,unsigned int BytePerPixelC[],double dst_y_per_vm_vblank[],double dst_y_per_vm_flip[],unsigned int dpte_row_width_luma_ub[],unsigned int dpte_row_width_chroma_ub[],unsigned int vm_group_bytes[],unsigned int dpde0_bytes_per_frame_ub_l[],unsigned int dpde0_bytes_per_frame_ub_c[],unsigned int tdlut_pte_bytes_per_frame[],unsigned int meta_pte_bytes_per_frame_ub_l[],unsigned int meta_pte_bytes_per_frame_ub_c[],bool mrq_present,double TimePerVMGroupVBlank[],double TimePerVMGroupFlip[],double TimePerVMRequestVBlank[],double TimePerVMRequestFlip[])4828 void dcn5_calculate_vm_group_and_request_times(
4829 		const struct dml2_display_cfg *display_cfg,
4830 		unsigned int NumberOfActiveSurfaces,
4831 		unsigned int BytePerPixelC[],
4832 		double dst_y_per_vm_vblank[],
4833 		double dst_y_per_vm_flip[],
4834 		unsigned int dpte_row_width_luma_ub[],
4835 		unsigned int dpte_row_width_chroma_ub[],
4836 		unsigned int vm_group_bytes[],
4837 		unsigned int dpde0_bytes_per_frame_ub_l[],
4838 		unsigned int dpde0_bytes_per_frame_ub_c[],
4839 		unsigned int tdlut_pte_bytes_per_frame[],
4840 		unsigned int meta_pte_bytes_per_frame_ub_l[],
4841 		unsigned int meta_pte_bytes_per_frame_ub_c[],
4842 		bool mrq_present,
4843 
4844 		// Output
4845 		double TimePerVMGroupVBlank[],
4846 		double TimePerVMGroupFlip[],
4847 		double TimePerVMRequestVBlank[],
4848 		double TimePerVMRequestFlip[])
4849 {
4850 	(void)dpte_row_width_luma_ub;
4851 	(void)dpte_row_width_chroma_ub;
4852 	unsigned int num_group_per_lower_vm_stage = 0;
4853 	unsigned int num_req_per_lower_vm_stage = 0;
4854 	unsigned int num_group_per_lower_vm_stage_flip;
4855 	unsigned int num_group_per_lower_vm_stage_pref;
4856 	unsigned int num_req_per_lower_vm_stage_flip;
4857 	unsigned int num_req_per_lower_vm_stage_pref;
4858 	double line_time;
4859 
4860 	DML_LOG_VERBOSE("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
4861 	for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) {
4862 		double pixel_clock_mhz = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
4863 		bool dcc_mrq_enable = display_cfg->plane_descriptors[k].surface.dcc.enable && mrq_present;
4864 		DML_LOG_VERBOSE("DML::%s: k=%u, dcc_mrq_enable = %u\n", __func__, k, dcc_mrq_enable);
4865 		DML_LOG_VERBOSE("DML::%s: k=%u, vm_group_bytes = %u\n", __func__, k, vm_group_bytes[k]);
4866 		DML_LOG_VERBOSE("DML::%s: k=%u, dpde0_bytes_per_frame_ub_l = %u\n", __func__, k, dpde0_bytes_per_frame_ub_l[k]);
4867 		DML_LOG_VERBOSE("DML::%s: k=%u, dpde0_bytes_per_frame_ub_c = %u\n", __func__, k, dpde0_bytes_per_frame_ub_c[k]);
4868 		DML_LOG_VERBOSE("DML::%s: k=%d, meta_pte_bytes_per_frame_ub_l = %d\n", __func__, k, meta_pte_bytes_per_frame_ub_l[k]);
4869 		DML_LOG_VERBOSE("DML::%s: k=%d, meta_pte_bytes_per_frame_ub_c = %d\n", __func__, k, meta_pte_bytes_per_frame_ub_c[k]);
4870 
4871 		if (display_cfg->gpuvm_enable) {
4872 			if (display_cfg->gpuvm_max_page_table_levels >= 2) {
4873 				num_group_per_lower_vm_stage += (unsigned int) math_ceil2((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
4874 
4875 				if (BytePerPixelC[k] > 0)
4876 					num_group_per_lower_vm_stage += (unsigned int) math_ceil2((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
4877 			}
4878 
4879 			if (dcc_mrq_enable) {
4880 				if (BytePerPixelC[k] > 0) {
4881 					num_group_per_lower_vm_stage += (unsigned int)(2.0 /*for each mpde0 group*/ + math_ceil2((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1) +
4882 							math_ceil2((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1));
4883 				} else {
4884 					num_group_per_lower_vm_stage += (unsigned int)(1.0 + math_ceil2((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1));
4885 				}
4886 			}
4887 
4888 			num_group_per_lower_vm_stage_flip = num_group_per_lower_vm_stage;
4889 			num_group_per_lower_vm_stage_pref = num_group_per_lower_vm_stage;
4890 
4891 			if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut && display_cfg->gpuvm_enable) {
4892 				num_group_per_lower_vm_stage_pref += (unsigned int) math_ceil2(tdlut_pte_bytes_per_frame[k] / vm_group_bytes[k], 1);
4893 				if (display_cfg->gpuvm_max_page_table_levels >= 2)
4894 					num_group_per_lower_vm_stage_pref += 1; // tdpe0 group
4895 			}
4896 
4897 			if (display_cfg->gpuvm_max_page_table_levels >= 2) {
4898 				num_req_per_lower_vm_stage += dpde0_bytes_per_frame_ub_l[k] / 64;
4899 				if (BytePerPixelC[k] > 0)
4900 					num_req_per_lower_vm_stage += dpde0_bytes_per_frame_ub_c[k];
4901 			}
4902 
4903 			if (dcc_mrq_enable) {
4904 				num_req_per_lower_vm_stage += meta_pte_bytes_per_frame_ub_l[k] / 64;
4905 				if (BytePerPixelC[k] > 0)
4906 					num_req_per_lower_vm_stage += meta_pte_bytes_per_frame_ub_c[k] / 64;
4907 			}
4908 
4909 			num_req_per_lower_vm_stage_flip = num_req_per_lower_vm_stage;
4910 			num_req_per_lower_vm_stage_pref = num_req_per_lower_vm_stage;
4911 
4912 			if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut && display_cfg->gpuvm_enable) {
4913 				num_req_per_lower_vm_stage_pref += tdlut_pte_bytes_per_frame[k] / 64;
4914 			}
4915 
4916 			line_time = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz;
4917 
4918 			if (num_group_per_lower_vm_stage_pref > 0)
4919 				TimePerVMGroupVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_group_per_lower_vm_stage_pref;
4920 			else
4921 				TimePerVMGroupVBlank[k] = 0;
4922 
4923 			if (num_group_per_lower_vm_stage_flip > 0)
4924 				TimePerVMGroupFlip[k] = dst_y_per_vm_flip[k] * line_time / num_group_per_lower_vm_stage_flip;
4925 			else
4926 				TimePerVMGroupFlip[k] = 0;
4927 
4928 			if (num_req_per_lower_vm_stage_pref > 0)
4929 				TimePerVMRequestVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_req_per_lower_vm_stage_pref;
4930 			else
4931 				TimePerVMRequestVBlank[k] = 0.0;
4932 			if (num_req_per_lower_vm_stage_flip > 0)
4933 				TimePerVMRequestFlip[k] = dst_y_per_vm_flip[k] * line_time / num_req_per_lower_vm_stage_flip;
4934 			else
4935 				TimePerVMRequestFlip[k] = 0.0;
4936 
4937 			DML_LOG_VERBOSE("DML::%s: k=%u, dst_y_per_vm_vblank = %f\n", __func__, k, dst_y_per_vm_vblank[k]);
4938 			DML_LOG_VERBOSE("DML::%s: k=%u, dst_y_per_vm_flip = %f\n", __func__, k, dst_y_per_vm_flip[k]);
4939 			DML_LOG_VERBOSE("DML::%s: k=%u, line_time = %f\n", __func__, k, line_time);
4940 			DML_LOG_VERBOSE("DML::%s: k=%u, num_group_per_lower_vm_stage_pref = %d\n", __func__, k, num_group_per_lower_vm_stage_pref);
4941 			DML_LOG_VERBOSE("DML::%s: k=%u, num_group_per_lower_vm_stage_flip = %d\n", __func__, k, num_group_per_lower_vm_stage_flip);
4942 			DML_LOG_VERBOSE("DML::%s: k=%u, num_req_per_lower_vm_stage_pref = %d\n", __func__, k, num_req_per_lower_vm_stage_pref);
4943 			DML_LOG_VERBOSE("DML::%s: k=%u, num_req_per_lower_vm_stage_flip = %d\n", __func__, k, num_req_per_lower_vm_stage_flip);
4944 
4945 			if (display_cfg->gpuvm_max_page_table_levels > 2) {
4946 				TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2;
4947 				TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2;
4948 				TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2;
4949 				TimePerVMRequestFlip[k] = TimePerVMRequestFlip[k] / 2;
4950 			}
4951 
4952 		} else {
4953 			TimePerVMGroupVBlank[k] = 0;
4954 			TimePerVMGroupFlip[k] = 0;
4955 			TimePerVMRequestVBlank[k] = 0;
4956 			TimePerVMRequestFlip[k] = 0;
4957 		}
4958 		DML_LOG_VERBOSE("DML::%s: k=%u, TimePerVMGroupVBlank = %f\n", __func__, k, TimePerVMGroupVBlank[k]);
4959 		DML_LOG_VERBOSE("DML::%s: k=%u, TimePerVMGroupFlip = %f\n", __func__, k, TimePerVMGroupFlip[k]);
4960 		DML_LOG_VERBOSE("DML::%s: k=%u, TimePerVMRequestVBlank = %f\n", __func__, k, TimePerVMRequestVBlank[k]);
4961 		DML_LOG_VERBOSE("DML::%s: k=%u, TimePerVMRequestFlip = %f\n", __func__, k, TimePerVMRequestFlip[k]);
4962 	}
4963 }
4964 
dcn5_calculate_stutter_efficiency(struct dml2_core_internal_scratch * scratch,struct dml2_core_calcs_CalculateStutterEfficiency_params * p)4965 void dcn5_calculate_stutter_efficiency(struct dml2_core_internal_scratch *scratch,
4966 		struct dml2_core_calcs_CalculateStutterEfficiency_params *p)
4967 {
4968 	struct dml2_core_calcs_CalculateStutterEfficiency_locals *l = &scratch->CalculateStutterEfficiency_locals;
4969 
4970 	unsigned int TotalNumberOfActiveOTG = 0;
4971 	double SinglePixelClock = 0;
4972 	unsigned int SingleHTotal = 0;
4973 	unsigned int SingleVTotal = 0;
4974 	bool SameTiming = true;
4975 	bool at_least_one_single_pipe_single_plane_surface = false;
4976 	bool FoundCriticalSurface = false;
4977 
4978 	memset(l, 0, sizeof(struct dml2_core_calcs_CalculateStutterEfficiency_locals));
4979 
4980 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4981 		if (p->display_cfg->plane_descriptors[k].surface.dcc.enable == true) {
4982 			if ((dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockWidth256BytesY[k] > p->SwathHeightY[k]) || (!dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockHeight256BytesY[k] > p->SwathHeightY[k]) || p->DCCYMaxUncompressedBlock[k] < 256) {
4983 				l->MaximumEffectiveCompressionLuma = 2;
4984 			} else {
4985 				l->MaximumEffectiveCompressionLuma = 4;
4986 			}
4987 			l->TotalCompressedReadBandwidth = l->TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] / math_min2(p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane0, l->MaximumEffectiveCompressionLuma);
4988 			DML_LOG_VERBOSE("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, p->ReadBandwidthSurfaceLuma[k]);
4989 			DML_LOG_VERBOSE("DML::%s: k=%u, NetDCCRateLuma = %f\n", __func__, k, p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane0);
4990 			DML_LOG_VERBOSE("DML::%s: k=%u, MaximumEffectiveCompressionLuma = %f\n", __func__, k, l->MaximumEffectiveCompressionLuma);
4991 			l->TotalZeroSizeRequestReadBandwidth = l->TotalZeroSizeRequestReadBandwidth + p->ReadBandwidthSurfaceLuma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane0;
4992 			l->TotalZeroSizeCompressedReadBandwidth = l->TotalZeroSizeCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane0 / l->MaximumEffectiveCompressionLuma;
4993 
4994 			if (p->ReadBandwidthSurfaceChroma[k] > 0) {
4995 				if ((dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockWidth256BytesC[k] > p->SwathHeightC[k]) || (!dml2_core_utils_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockHeight256BytesC[k] > p->SwathHeightC[k]) || p->DCCCMaxUncompressedBlock[k] < 256) {
4996 					l->MaximumEffectiveCompressionChroma = 2;
4997 				} else {
4998 					l->MaximumEffectiveCompressionChroma = 4;
4999 				}
5000 				l->TotalCompressedReadBandwidth = l->TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceChroma[k] / math_min2(p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane1, l->MaximumEffectiveCompressionChroma);
5001 				DML_LOG_VERBOSE("DML::%s: k=%u, ReadBandwidthSurfaceChroma = %f\n", __func__, k, p->ReadBandwidthSurfaceChroma[k]);
5002 				DML_LOG_VERBOSE("DML::%s: k=%u, NetDCCRateChroma = %f\n", __func__, k, p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane1);
5003 				DML_LOG_VERBOSE("DML::%s: k=%u, MaximumEffectiveCompressionChroma = %f\n", __func__, k, l->MaximumEffectiveCompressionChroma);
5004 				l->TotalZeroSizeRequestReadBandwidth = l->TotalZeroSizeRequestReadBandwidth + p->ReadBandwidthSurfaceChroma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane1;
5005 				l->TotalZeroSizeCompressedReadBandwidth = l->TotalZeroSizeCompressedReadBandwidth + p->ReadBandwidthSurfaceChroma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane1 / l->MaximumEffectiveCompressionChroma;
5006 			}
5007 		} else {
5008 			l->TotalCompressedReadBandwidth = l->TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] + p->ReadBandwidthSurfaceChroma[k];
5009 		}
5010 		l->TotalRowReadBandwidth = l->TotalRowReadBandwidth + p->DPPPerSurface[k] * (p->meta_row_bw[k] + p->dpte_row_bw[k]);
5011 	}
5012 
5013 	l->AverageDCCCompressionRate = p->TotalDataReadBandwidth / l->TotalCompressedReadBandwidth;
5014 	l->AverageDCCZeroSizeFraction = l->TotalZeroSizeRequestReadBandwidth / p->TotalDataReadBandwidth;
5015 
5016 	DML_LOG_VERBOSE("DML::%s: UnboundedRequestEnabled = %u\n", __func__, p->UnboundedRequestEnabled);
5017 	DML_LOG_VERBOSE("DML::%s: TotalCompressedReadBandwidth = %f\n", __func__, l->TotalCompressedReadBandwidth);
5018 	DML_LOG_VERBOSE("DML::%s: TotalZeroSizeRequestReadBandwidth = %f\n", __func__, l->TotalZeroSizeRequestReadBandwidth);
5019 	DML_LOG_VERBOSE("DML::%s: TotalZeroSizeCompressedReadBandwidth = %f\n", __func__, l->TotalZeroSizeCompressedReadBandwidth);
5020 	DML_LOG_VERBOSE("DML::%s: MaximumEffectiveCompressionLuma = %f\n", __func__, l->MaximumEffectiveCompressionLuma);
5021 	DML_LOG_VERBOSE("DML::%s: MaximumEffectiveCompressionChroma = %f\n", __func__, l->MaximumEffectiveCompressionChroma);
5022 	DML_LOG_VERBOSE("DML::%s: AverageDCCCompressionRate = %f\n", __func__, l->AverageDCCCompressionRate);
5023 	DML_LOG_VERBOSE("DML::%s: AverageDCCZeroSizeFraction = %f\n", __func__, l->AverageDCCZeroSizeFraction);
5024 
5025 	DML_LOG_VERBOSE("DML::%s: CompbufReservedSpace64B = %u (%f kbytes)\n", __func__, p->CompbufReservedSpace64B, p->CompbufReservedSpace64B * 64 / 1024.0);
5026 	DML_LOG_VERBOSE("DML::%s: CompbufReservedSpaceZs = %u\n", __func__, p->CompbufReservedSpaceZs);
5027 	DML_LOG_VERBOSE("DML::%s: CompressedBufferSizeInkByte = %u kbytes\n", __func__, p->CompressedBufferSizeInkByte);
5028 	DML_LOG_VERBOSE("DML::%s: ROBBufferSizeInKByte = %u kbytes\n", __func__, p->ROBBufferSizeInKByte);
5029 	if (l->AverageDCCZeroSizeFraction == 1) {
5030 		l->AverageZeroSizeCompressionRate = l->TotalZeroSizeRequestReadBandwidth / l->TotalZeroSizeCompressedReadBandwidth;
5031 		l->EffectiveCompressedBufferSize = (double)p->MetaFIFOSizeInKEntries * 1024 * 64 * l->AverageZeroSizeCompressionRate + ((double)p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 * l->AverageZeroSizeCompressionRate;
5032 
5033 
5034 	} else if (l->AverageDCCZeroSizeFraction > 0) {
5035 		l->AverageZeroSizeCompressionRate = l->TotalZeroSizeRequestReadBandwidth / l->TotalZeroSizeCompressedReadBandwidth;
5036 		l->EffectiveCompressedBufferSize = math_min2((double)p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate,
5037 				(double)p->MetaFIFOSizeInKEntries * 1024 * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate + 1 / l->AverageDCCCompressionRate)) +
5038 						(p->rob_alloc_compressed ? math_min2(((double)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * l->AverageDCCCompressionRate,
5039 								((double)p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate))
5040 								: ((double)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64));
5041 
5042 
5043 		DML_LOG_VERBOSE("DML::%s: min 1 = %f\n", __func__, p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate);
5044 		DML_LOG_VERBOSE("DML::%s: min 2 = %f\n", __func__, p->MetaFIFOSizeInKEntries * 1024 * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate + 1 / l->AverageDCCCompressionRate));
5045 		DML_LOG_VERBOSE("DML::%s: min 3 = %d\n", __func__, (p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64));
5046 		DML_LOG_VERBOSE("DML::%s: min 4 = %f\n", __func__, (p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate));
5047 	} else {
5048 		l->EffectiveCompressedBufferSize = math_min2((double)p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate,
5049 				(double)p->MetaFIFOSizeInKEntries * 1024 * 64 * l->AverageDCCCompressionRate) +
5050 						((double)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * (p->rob_alloc_compressed ? l->AverageDCCCompressionRate : 1.0);
5051 
5052 		DML_LOG_VERBOSE("DML::%s: min 1 = %f\n", __func__, p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate);
5053 		DML_LOG_VERBOSE("DML::%s: min 2 = %f\n", __func__, p->MetaFIFOSizeInKEntries * 1024 * 64 * l->AverageDCCCompressionRate);
5054 	}
5055 
5056 	DML_LOG_VERBOSE("DML::%s: MetaFIFOSizeInKEntries = %u\n", __func__, p->MetaFIFOSizeInKEntries);
5057 	DML_LOG_VERBOSE("DML::%s: ZeroSizeBufferEntries = %u\n", __func__, p->ZeroSizeBufferEntries);
5058 	DML_LOG_VERBOSE("DML::%s: AverageZeroSizeCompressionRate = %f\n", __func__, l->AverageZeroSizeCompressionRate);
5059 	DML_LOG_VERBOSE("DML::%s: EffectiveCompressedBufferSize = %f (%f kbytes)\n", __func__, l->EffectiveCompressedBufferSize, l->EffectiveCompressedBufferSize / 1024.0);
5060 
5061 	*p->StutterPeriod = 0;
5062 
5063 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
5064 		l->LinesInDETY = ((double)p->DETBufferSizeY[k] + (p->UnboundedRequestEnabled == true ? l->EffectiveCompressedBufferSize : 0) * p->ReadBandwidthSurfaceLuma[k] / p->TotalDataReadBandwidth) / p->BytePerPixelDETY[k] / p->SwathWidthY[k];
5065 		l->LinesInDETYRoundedDownToSwath = math_floor2(l->LinesInDETY, p->SwathHeightY[k]);
5066 		l->DETBufferingTimeY = l->LinesInDETYRoundedDownToSwath * ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
5067 		at_least_one_single_pipe_single_plane_surface |= (p->DPPPerSurface[k] == 1) && (p->ReadBandwidthSurfaceChroma[k] == 0);
5068 		DML_LOG_VERBOSE("DML::%s: k=%u, DETBufferSizeY = %u (%u kbytes)\n", __func__, k, p->DETBufferSizeY[k], p->DETBufferSizeY[k] / 1024);
5069 		DML_LOG_VERBOSE("DML::%s: k=%u, BytePerPixelDETY = %f\n", __func__, k, p->BytePerPixelDETY[k]);
5070 		DML_LOG_VERBOSE("DML::%s: k=%u, SwathWidthY = %u\n", __func__, k, p->SwathWidthY[k]);
5071 		DML_LOG_VERBOSE("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, p->ReadBandwidthSurfaceLuma[k]);
5072 		DML_LOG_VERBOSE("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, p->TotalDataReadBandwidth);
5073 		DML_LOG_VERBOSE("DML::%s: k=%u, LinesInDETY = %f\n", __func__, k, l->LinesInDETY);
5074 		DML_LOG_VERBOSE("DML::%s: k=%u, LinesInDETYRoundedDownToSwath = %f\n", __func__, k, l->LinesInDETYRoundedDownToSwath);
5075 		DML_LOG_VERBOSE("DML::%s: k=%u, VRatio = %f\n", __func__, k, p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio);
5076 		DML_LOG_VERBOSE("DML::%s: k=%u, DETBufferingTimeY = %f\n", __func__, k, l->DETBufferingTimeY);
5077 
5078 		if (!FoundCriticalSurface || l->DETBufferingTimeY < *p->StutterPeriod) {
5079 			bool isInterlaceTiming = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.interlaced && !p->ProgressiveToInterlaceUnitInOPP;
5080 
5081 			FoundCriticalSurface = true;
5082 			*p->StutterPeriod = l->DETBufferingTimeY;
5083 			l->FrameTimeCriticalSurface = (isInterlaceTiming ? math_floor2((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total / 2.0, 1.0) : p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total) * (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
5084 			l->VActiveTimeCriticalSurface = (isInterlaceTiming ? math_floor2((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_active / 2.0, 1.0) : p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_active) * (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
5085 			l->BytePerPixelYCriticalSurface = p->BytePerPixelY[k];
5086 			l->SwathWidthYCriticalSurface = p->SwathWidthY[k];
5087 			l->SwathHeightYCriticalSurface = p->SwathHeightY[k];
5088 			l->BlockWidth256BytesYCriticalSurface = p->BlockWidth256BytesY[k];
5089 			l->DETBufferSizeYCriticalSurface = p->DETBufferSizeY[k];
5090 			l->MinTTUVBlankCriticalSurface = p->MinTTUVBlank[k];
5091 			l->SinglePlaneCriticalSurface = (p->ReadBandwidthSurfaceChroma[k] == 0);
5092 			l->SinglePipeCriticalSurface = (p->DPPPerSurface[k] == 1);
5093 
5094 			DML_LOG_VERBOSE("DML::%s: k=%u, FoundCriticalSurface = %u\n", __func__, k, FoundCriticalSurface);
5095 			DML_LOG_VERBOSE("DML::%s: k=%u, StutterPeriod = %f\n", __func__, k, *p->StutterPeriod);
5096 			DML_LOG_VERBOSE("DML::%s: k=%u, MinTTUVBlankCriticalSurface = %f\n", __func__, k, l->MinTTUVBlankCriticalSurface);
5097 			DML_LOG_VERBOSE("DML::%s: k=%u, FrameTimeCriticalSurface= %f\n", __func__, k, l->FrameTimeCriticalSurface);
5098 			DML_LOG_VERBOSE("DML::%s: k=%u, VActiveTimeCriticalSurface = %f\n", __func__, k, l->VActiveTimeCriticalSurface);
5099 			DML_LOG_VERBOSE("DML::%s: k=%u, BytePerPixelYCriticalSurface = %u\n", __func__, k, l->BytePerPixelYCriticalSurface);
5100 			DML_LOG_VERBOSE("DML::%s: k=%u, SwathWidthYCriticalSurface = %f\n", __func__, k, l->SwathWidthYCriticalSurface);
5101 			DML_LOG_VERBOSE("DML::%s: k=%u, SwathHeightYCriticalSurface = %f\n", __func__, k, l->SwathHeightYCriticalSurface);
5102 			DML_LOG_VERBOSE("DML::%s: k=%u, BlockWidth256BytesYCriticalSurface = %u\n", __func__, k, l->BlockWidth256BytesYCriticalSurface);
5103 			DML_LOG_VERBOSE("DML::%s: k=%u, SinglePlaneCriticalSurface = %u\n", __func__, k, l->SinglePlaneCriticalSurface);
5104 			DML_LOG_VERBOSE("DML::%s: k=%u, SinglePipeCriticalSurface = %u\n", __func__, k, l->SinglePipeCriticalSurface);
5105 		}
5106 	}
5107 
5108 	// for bounded req, the stutter period is calculated only based on DET size, but during burst there can be some return inside ROB/compressed buffer
5109 	// stutter period is calculated only on the det sizing
5110 	// if (cdb + rob >= det) the stutter burst will be absorbed by the cdb + rob which is before decompress
5111 	// else
5112 	// the cdb + rob part will be in compressed rate with urg bw (idea bw)
5113 	// the det part will be return at uncompressed rate with 64B/dcfclk
5114 	//
5115 	// for unbounded req, the stutter period should be calculated as total of CDB+ROB+DET, so the term "PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer"
5116 	// should be == EffectiveCompressedBufferSize which will returned a compressed rate, the rest of stutter period is from the DET will be returned at uncompressed rate with 64B/dcfclk
5117 
5118 	l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = math_min2(*p->StutterPeriod * p->TotalDataReadBandwidth, l->EffectiveCompressedBufferSize);
5119 	DML_LOG_VERBOSE("DML::%s: AverageDCCCompressionRate = %f\n", __func__, l->AverageDCCCompressionRate);
5120 	DML_LOG_VERBOSE("DML::%s: StutterPeriod*TotalDataReadBandwidth = %f (%f kbytes)\n", __func__, *p->StutterPeriod * p->TotalDataReadBandwidth, (*p->StutterPeriod * p->TotalDataReadBandwidth) / 1024.0);
5121 	DML_LOG_VERBOSE("DML::%s: EffectiveCompressedBufferSize = %f (%f kbytes)\n", __func__, l->EffectiveCompressedBufferSize, l->EffectiveCompressedBufferSize / 1024.0);
5122 	DML_LOG_VERBOSE("DML::%s: PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = %f (%f kbytes)\n", __func__, l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer, l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / 1024);
5123 	DML_LOG_VERBOSE("DML::%s: ReturnBW = %f\n", __func__, p->ReturnBW);
5124 	DML_LOG_VERBOSE("DML::%s: TotalDataReadBandwidth = %f\n", __func__, p->TotalDataReadBandwidth);
5125 	DML_LOG_VERBOSE("DML::%s: TotalRowReadBandwidth = %f\n", __func__, l->TotalRowReadBandwidth);
5126 	DML_LOG_VERBOSE("DML::%s: DCFCLK = %f\n", __func__, p->DCFCLK);
5127 
5128 	l->StutterBurstTime = l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer
5129 			/ (p->ReturnBW * (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate)) +
5130 			(*p->StutterPeriod * p->TotalDataReadBandwidth - l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer)
5131 			/ math_min2(p->DCFCLK * 64, p->ReturnBW * (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate)) +
5132 			*p->StutterPeriod * l->TotalRowReadBandwidth / p->ReturnBW;
5133 	DML_LOG_VERBOSE("DML::%s: Part 1 = %f\n", __func__, l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / p->ReturnBW / (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate));
5134 	DML_LOG_VERBOSE("DML::%s: Part 2 = %f\n", __func__, (*p->StutterPeriod * p->TotalDataReadBandwidth - l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (p->DCFCLK * 64));
5135 	DML_LOG_VERBOSE("DML::%s: Part 3 = %f\n", __func__, *p->StutterPeriod * l->TotalRowReadBandwidth / p->ReturnBW);
5136 	DML_LOG_VERBOSE("DML::%s: StutterBurstTime = %f\n", __func__, l->StutterBurstTime);
5137 	l->TotalActiveWriteback = 0;
5138 	memset(l->stream_visited, 0, DML2_MAX_PLANES * sizeof(bool));
5139 
5140 	for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
5141 		if (!l->stream_visited[p->display_cfg->plane_descriptors[k].stream_index]) {
5142 
5143 			for (unsigned int j = 0; j < p->display_cfg->stream_descriptors[k].writeback.active_writebacks_per_stream; j++)
5144 				l->TotalActiveWriteback = l->TotalActiveWriteback + 1;
5145 
5146 			if (TotalNumberOfActiveOTG == 0) { // first otg
5147 				SinglePixelClock = ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
5148 				SingleHTotal = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total;
5149 				SingleVTotal = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total;
5150 			} else if (SinglePixelClock != ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) ||
5151 					SingleHTotal != p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total ||
5152 					SingleVTotal != p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total) {
5153 				SameTiming = false;
5154 			}
5155 			TotalNumberOfActiveOTG = TotalNumberOfActiveOTG + 1;
5156 			l->stream_visited[p->display_cfg->plane_descriptors[k].stream_index] = 1;
5157 		}
5158 	}
5159 
5160 	if (l->TotalActiveWriteback == 0) {
5161 		DML_LOG_VERBOSE("DML::%s: SRExitTime = %f\n", __func__, p->SRExitTime);
5162 		DML_LOG_VERBOSE("DML::%s: SRExitZ8Time = %f\n", __func__, p->SRExitZ8Time);
5163 		DML_LOG_VERBOSE("DML::%s: StutterPeriod = %f\n", __func__, *p->StutterPeriod);
5164 		*p->StutterEfficiencyNotIncludingVBlank = math_max2(0., 1 - (p->SRExitTime + l->StutterBurstTime) / *p->StutterPeriod) * 100;
5165 		*p->Z8StutterEfficiencyNotIncludingVBlank = math_max2(0., 1 - (p->SRExitZ8Time + l->StutterBurstTime) / *p->StutterPeriod) * 100;
5166 		*p->NumberOfStutterBurstsPerFrame = (*p->StutterEfficiencyNotIncludingVBlank > 0 ? (unsigned int)(math_ceil2(l->VActiveTimeCriticalSurface / *p->StutterPeriod, 1)) : 0);
5167 		*p->Z8NumberOfStutterBurstsPerFrame = (*p->Z8StutterEfficiencyNotIncludingVBlank > 0 ? (unsigned int)(math_ceil2(l->VActiveTimeCriticalSurface / *p->StutterPeriod, 1)) : 0);
5168 	} else {
5169 		*p->StutterEfficiencyNotIncludingVBlank = 0.;
5170 		*p->Z8StutterEfficiencyNotIncludingVBlank = 0.;
5171 		*p->NumberOfStutterBurstsPerFrame = 0;
5172 		*p->Z8NumberOfStutterBurstsPerFrame = 0;
5173 	}
5174 	DML_LOG_VERBOSE("DML::%s: VActiveTimeCriticalSurface = %f\n", __func__, l->VActiveTimeCriticalSurface);
5175 	DML_LOG_VERBOSE("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->StutterEfficiencyNotIncludingVBlank);
5176 	DML_LOG_VERBOSE("DML::%s: Z8StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->Z8StutterEfficiencyNotIncludingVBlank);
5177 	DML_LOG_VERBOSE("DML::%s: NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->NumberOfStutterBurstsPerFrame);
5178 	DML_LOG_VERBOSE("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame);
5179 
5180 	if (*p->StutterEfficiencyNotIncludingVBlank > 0) {
5181 		if (!((p->SynchronizeTimings || TotalNumberOfActiveOTG == 1) && SameTiming)) {
5182 			*p->StutterEfficiency = *p->StutterEfficiencyNotIncludingVBlank;
5183 		} else {
5184 			*p->StutterEfficiency = (1 - (*p->NumberOfStutterBurstsPerFrame * p->SRExitTime + l->StutterBurstTime * l->VActiveTimeCriticalSurface / *p->StutterPeriod) / l->FrameTimeCriticalSurface) * 100;
5185 		}
5186 	} else {
5187 		*p->StutterEfficiency = 0;
5188 		*p->NumberOfStutterBurstsPerFrame = 0;
5189 	}
5190 
5191 	if (*p->Z8StutterEfficiencyNotIncludingVBlank > 0) {
5192 		if (!((p->SynchronizeTimings || TotalNumberOfActiveOTG == 1) && SameTiming)) {
5193 			*p->Z8StutterEfficiency = *p->Z8StutterEfficiencyNotIncludingVBlank;
5194 		} else {
5195 			*p->Z8StutterEfficiency = (1 - (*p->Z8NumberOfStutterBurstsPerFrame * p->SRExitZ8Time + l->StutterBurstTime * l->VActiveTimeCriticalSurface / *p->StutterPeriod) / l->FrameTimeCriticalSurface) * 100;
5196 		}
5197 	} else {
5198 		*p->Z8StutterEfficiency = 0.;
5199 		*p->Z8NumberOfStutterBurstsPerFrame = 0;
5200 	}
5201 
5202 	DML_LOG_VERBOSE("DML::%s: TotalNumberOfActiveOTG = %u\n", __func__, TotalNumberOfActiveOTG);
5203 	DML_LOG_VERBOSE("DML::%s: SameTiming = %u\n", __func__, SameTiming);
5204 	DML_LOG_VERBOSE("DML::%s: SynchronizeTimings = %u\n", __func__, p->SynchronizeTimings);
5205 	DML_LOG_VERBOSE("DML::%s: LastZ8StutterPeriod = %f\n", __func__, *p->Z8StutterEfficiencyNotIncludingVBlank > 0 ? l->VActiveTimeCriticalSurface - (*p->Z8NumberOfStutterBurstsPerFrame - 1) * *p->StutterPeriod : 0);
5206 	DML_LOG_VERBOSE("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, p->Z8StutterEnterPlusExitWatermark);
5207 	DML_LOG_VERBOSE("DML::%s: StutterBurstTime = %f\n", __func__, l->StutterBurstTime);
5208 	DML_LOG_VERBOSE("DML::%s: StutterPeriod = %f\n", __func__, *p->StutterPeriod);
5209 	DML_LOG_VERBOSE("DML::%s: StutterEfficiency = %f\n", __func__, *p->StutterEfficiency);
5210 	DML_LOG_VERBOSE("DML::%s: Z8StutterEfficiency = %f\n", __func__, *p->Z8StutterEfficiency);
5211 	DML_LOG_VERBOSE("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->StutterEfficiencyNotIncludingVBlank);
5212 	DML_LOG_VERBOSE("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame);
5213 
5214 	*p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = !(!p->UnboundedRequestEnabled && (TotalNumberOfActiveOTG == 1) && at_least_one_single_pipe_single_plane_surface);
5215 
5216 	DML_LOG_VERBOSE("DML::%s: DETBufferSizeYCriticalSurface = %u\n", __func__, l->DETBufferSizeYCriticalSurface);
5217 	DML_LOG_VERBOSE("DML::%s: PixelChunkSizeInKByte = %u\n", __func__, p->PixelChunkSizeInKByte);
5218 	DML_LOG_VERBOSE("DML::%s: DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = %u\n", __func__, *p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE);
5219 }
5220 
dcn5_check_urgent_bandwidth_support(double * frac_urg_bandwidth_nom,bool * bandwidth_support_ok,double non_urg_bandwidth_required,double urg_bandwidth_required,double urg_bandwidth_available)5221 void dcn5_check_urgent_bandwidth_support(
5222 		double *frac_urg_bandwidth_nom,
5223 		bool *bandwidth_support_ok,   // max of vm, prefetch, vactive all ok
5224 
5225 		double non_urg_bandwidth_required,
5226 		double urg_bandwidth_required,
5227 		double urg_bandwidth_available)
5228 {
5229 	*bandwidth_support_ok = urg_bandwidth_required <= urg_bandwidth_available;
5230 	*frac_urg_bandwidth_nom = non_urg_bandwidth_required / urg_bandwidth_available;
5231 	*bandwidth_support_ok &= (*frac_urg_bandwidth_nom <= 1.0);
5232 
5233 	DML_LOG_VERBOSE("DML::%s: frac_urg_bandwidth_nom = %f\n", __func__, *frac_urg_bandwidth_nom);
5234 	DML_LOG_VERBOSE("DML::%s: bandwidth_support_ok = %d\n", __func__, *bandwidth_support_ok);
5235 }
5236 
dcn5_get_bandwidth_available_for_immediate_flip(double urg_bandwidth_required,double urg_bandwidth_available)5237 double dcn5_get_bandwidth_available_for_immediate_flip(
5238 		double urg_bandwidth_required, // no flip
5239 		double urg_bandwidth_available)
5240 {
5241 	double flip_bw_available_mbps = urg_bandwidth_available - urg_bandwidth_required;
5242 
5243 	DML_LOG_VERBOSE("DML::%s: flip_bw_available_mbps = %f\n", __func__, flip_bw_available_mbps);
5244 
5245 	return flip_bw_available_mbps;
5246 }
5247 
dcn5_check_immediate_flip_bandwidth_support(double * frac_urg_bandwidth_flip,bool * flip_bandwidth_support_ok,double urg_bandwidth_required_flip,double non_urg_bandwidth_required_flip,double urg_bandwidth_available)5248 void dcn5_check_immediate_flip_bandwidth_support(
5249 		// Output
5250 		double *frac_urg_bandwidth_flip,
5251 		bool *flip_bandwidth_support_ok,
5252 
5253 		// Input
5254 		double urg_bandwidth_required_flip,
5255 		double non_urg_bandwidth_required_flip,
5256 		double urg_bandwidth_available)
5257 {
5258 	*frac_urg_bandwidth_flip = non_urg_bandwidth_required_flip / urg_bandwidth_available;
5259 	*flip_bandwidth_support_ok = urg_bandwidth_available >= urg_bandwidth_required_flip;
5260 	*flip_bandwidth_support_ok &= (*frac_urg_bandwidth_flip <= 1.0);
5261 
5262 	DML_LOG_VERBOSE("DML::%s: frac_urg_bandwidth_flip = %f\n", __func__, *frac_urg_bandwidth_flip);
5263 	DML_LOG_VERBOSE("DML::%s: flip_bandwidth_support_ok = %d\n", __func__, *flip_bandwidth_support_ok);
5264 	DML_LOG_VERBOSE("DML::%s: urg_bandwidth_available=%f %s urg_bandwidth_required=%f\n",
5265 					__func__, urg_bandwidth_available, (urg_bandwidth_available < urg_bandwidth_required_flip) ? "<" : ">=", urg_bandwidth_required_flip);
5266 }
5267 
dcn5_get_pipe_flip_bytes(double hostvm_inefficiency_factor,unsigned int vm_bytes,unsigned int dpte_row_bytes,unsigned int meta_row_bytes)5268 unsigned int dcn5_get_pipe_flip_bytes(
5269 		double hostvm_inefficiency_factor,
5270 		unsigned int vm_bytes,
5271 		unsigned int dpte_row_bytes,
5272 		unsigned int meta_row_bytes)
5273 {
5274 	unsigned int flip_bytes = 0;
5275 
5276 	flip_bytes += (unsigned int) ((vm_bytes * hostvm_inefficiency_factor) + 2*meta_row_bytes);
5277 	flip_bytes += (unsigned int) (2*dpte_row_bytes * hostvm_inefficiency_factor);
5278 
5279 	return flip_bytes;
5280 }
5281 
5282 struct dml2_core_internal_g6_temp_read_blackouts_table {
5283 	struct {
5284 		unsigned int uclk_khz;
5285 		unsigned int blackout_us;
5286 	} entries[DML_MAX_CLK_TABLE_SIZE];
5287 };
5288 
5289 struct dml2_core_internal_g6_temp_read_blackouts_table core_dcn5_g6_temp_read_blackout_table = {
5290 		.entries = {
5291 				{
5292 						.uclk_khz = 96000,
5293 						.blackout_us = 23,
5294 				},
5295 				{
5296 						.uclk_khz = 435000,
5297 						.blackout_us = 10,
5298 				},
5299 				{
5300 						.uclk_khz = 521000,
5301 						.blackout_us = 10,
5302 				},
5303 				{
5304 						.uclk_khz = 731000,
5305 						.blackout_us = 8,
5306 				},
5307 				{
5308 						.uclk_khz = 822000,
5309 						.blackout_us = 8,
5310 				},
5311 				{
5312 						.uclk_khz = 962000,
5313 						.blackout_us = 5,
5314 				},
5315 				{
5316 						.uclk_khz = 1069000,
5317 						.blackout_us = 5,
5318 				},
5319 				{
5320 						.uclk_khz = 1187000,
5321 						.blackout_us = 5,
5322 				},
5323 		},
5324 };
5325 
dcn5_adjust_pixel_clock_for_progressive_to_interlace_unit(const struct dml2_display_cfg * display_cfg,bool ptoi_supported,double * PixelClockBackEnd)5326 void dcn5_adjust_pixel_clock_for_progressive_to_interlace_unit(const struct dml2_display_cfg *display_cfg, bool ptoi_supported, double *PixelClockBackEnd)
5327 {
5328 	//unsigned int num_active_planes = display_cfg->num_planes;
5329 
5330 	//Progressive To Interlace Unit Effect
5331 	for (unsigned int k = 0; k < display_cfg->num_planes; ++k) {
5332 		PixelClockBackEnd[k] = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
5333 		if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced == 1 && ptoi_supported == true) {
5334 			// FIXME_STAGE2... can sw pass the pixel rate for interlaced directly
5335 			//display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz = 2 * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz;
5336 		}
5337 	}
5338 }
5339 
dcn5_rq_dlg_get_wm_regs(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_utm_soc_bb * utm_soc_bb,struct dml2_dchub_watermark_regs * wm_regs)5340 static void dcn5_rq_dlg_get_wm_regs(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, const struct dml2_utm_soc_bb *utm_soc_bb, struct dml2_dchub_watermark_regs *wm_regs)
5341 {
5342 	double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : utm_soc_bb->dchub_refclk_mhz;
5343 
5344 	wm_regs->fclk_pstate = (int unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz);
5345 	wm_regs->sr_enter = (int unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz);
5346 	wm_regs->sr_exit = (int unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz);
5347 	wm_regs->sr_enter_z8 = (int unsigned)(mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark * refclk_freq_in_mhz);
5348 	wm_regs->sr_exit_z8 = (int unsigned)(mode_lib->mp.Watermark.Z8StutterExitWatermark * refclk_freq_in_mhz);
5349 	wm_regs->temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * refclk_freq_in_mhz);
5350 	wm_regs->uclk_pstate = (int unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz);
5351 	wm_regs->urgent = (int unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz);
5352 	wm_regs->usr = (int unsigned)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz);
5353 	wm_regs->refcyc_per_trip_to_mem = (unsigned int)(mode_lib->mp.UrgentLatency * refclk_freq_in_mhz);
5354 	wm_regs->refcyc_per_meta_trip_to_mem = (unsigned int)(mode_lib->mp.MetaTripToMemory * refclk_freq_in_mhz);
5355 	wm_regs->frac_urg_bw_flip = (unsigned int)(mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip * 1000);
5356 	wm_regs->frac_urg_bw_nom = (unsigned int)(mode_lib->mp.FractionOfUrgentBandwidth * 1000);
5357 }
5358 
dcn5_get_mcif_arb_params(const struct dml2_core_internal_display_mode_lib * mode_lib,struct dml2_mcif_global_register_set * out)5359 void dcn5_get_mcif_arb_params(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_mcif_global_register_set *out)
5360 {
5361 	out->wm_regs[0].fclk_pstate = (unsigned int)(mode_lib->mp.Watermark.WritebackFCLKChangeWatermark * 1000.0);
5362 	out->wm_regs[0].uclk_pstate = (unsigned int)(mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark * 1000.0);
5363 	out->wm_regs[0].urgent = (unsigned int)(mode_lib->mp.Watermark.WritebackUrgentWatermark * 1000.0);
5364 	out->wm_regs[0].temp_read_or_ppt = (unsigned int)(mode_lib->mp.Watermark.writeback_temp_read_or_ppt_watermark_us * 1000.0);
5365 }
5366 
dml2_core_dcn5_calcs_cursor_dlg_reg(struct dml2_cursor_dlg_regs * cursor_dlg_regs,const struct dml2_get_cursor_dlg_reg * p)5367 void dml2_core_dcn5_calcs_cursor_dlg_reg(struct dml2_cursor_dlg_regs *cursor_dlg_regs, const struct dml2_get_cursor_dlg_reg *p)
5368 {
5369 	int dst_x_offset = (int) ((p->cursor_x_position + (p->cursor_stereo_en == 0 ? 0 : math_max2(p->cursor_primary_offset, p->cursor_secondary_offset)) -
5370 			(p->cursor_hotspot_x * (p->cursor_2x_magnify == 0 ? 1 : 2))) * p->dlg_refclk_mhz / p->pixel_rate_mhz / p->hratio);
5371 	cursor_dlg_regs->dst_x_offset = (unsigned int) ((dst_x_offset > 0) ? dst_x_offset : 0);
5372 
5373 	DML_LOG_VERBOSE("DML_DLG::%s: cursor_x_position=%d\n", __func__, p->cursor_x_position);
5374 	DML_LOG_VERBOSE("DML_DLG::%s: dlg_refclk_mhz=%f\n", __func__, p->dlg_refclk_mhz);
5375 	DML_LOG_VERBOSE("DML_DLG::%s: pixel_rate_mhz=%f\n", __func__, p->pixel_rate_mhz);
5376 	DML_LOG_VERBOSE("DML_DLG::%s: dst_x_offset=%d\n", __func__, dst_x_offset);
5377 	DML_LOG_VERBOSE("DML_DLG::%s: dst_x_offset=%d (reg)\n", __func__, cursor_dlg_regs->dst_x_offset);
5378 
5379 	cursor_dlg_regs->chunk_hdl_adjust = 3;
5380 	cursor_dlg_regs->dst_y_offset	 = 0;
5381 
5382 	cursor_dlg_regs->qos_level_fixed  = 8;
5383 	cursor_dlg_regs->qos_ramp_disable = 0;
5384 }
5385 
dcn5_rq_dlg_get_rq_reg(struct dml2_display_rq_regs * rq_regs,const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,unsigned int pipe_idx)5386 void dcn5_rq_dlg_get_rq_reg(struct dml2_display_rq_regs *rq_regs,
5387 		const struct dml2_display_cfg *display_cfg,
5388 		const struct dml2_core_internal_display_mode_lib *mode_lib,
5389 		unsigned int pipe_idx)
5390 {
5391 	unsigned int plane_idx = mode_lib->mp.pipe_plane[pipe_idx];
5392 	enum dml2_source_format_class source_format = display_cfg->plane_descriptors[plane_idx].pixel_format;
5393 	enum dml2_swizzle_mode sw_mode = display_cfg->plane_descriptors[plane_idx].surface.tiling;
5394 	bool dual_plane = dml2_core_utils_is_dual_plane((enum dml2_source_format_class)(source_format));
5395 
5396 	unsigned int pixel_chunk_bytes = 0;
5397 	unsigned int min_pixel_chunk_bytes = 0;
5398 	unsigned int dpte_group_bytes = 0;
5399 	unsigned int mpte_group_bytes = 0;
5400 
5401 	unsigned int p1_pixel_chunk_bytes = 0;
5402 	unsigned int p1_min_pixel_chunk_bytes = 0;
5403 	unsigned int p1_dpte_group_bytes = 0;
5404 	unsigned int p1_mpte_group_bytes = 0;
5405 
5406 	unsigned int detile_buf_plane1_addr = 0;
5407 	unsigned int detile_buf_size_in_bytes;
5408 	double stored_swath_l_bytes;
5409 	double stored_swath_c_bytes;
5410 
5411 	DML_LOG_VERBOSE("DML_DLG::%s: Calculation for pipe[%d] start\n", __func__, pipe_idx);
5412 
5413 	pixel_chunk_bytes = (unsigned int)(mode_lib->ip.pixel_chunk_size_kbytes * 1024);
5414 	min_pixel_chunk_bytes = (unsigned int)(mode_lib->ip.min_pixel_chunk_size_bytes);
5415 
5416 	if (pixel_chunk_bytes == 64 * 1024)
5417 		min_pixel_chunk_bytes = 0;
5418 
5419 	dpte_group_bytes = (unsigned int)(mode_lib->mp.dpte_group_bytes[mode_lib->mp.pipe_plane[pipe_idx]]);
5420 	mpte_group_bytes = (unsigned int)(mode_lib->mp.vm_group_bytes[mode_lib->mp.pipe_plane[pipe_idx]]);
5421 
5422 	p1_pixel_chunk_bytes = pixel_chunk_bytes;
5423 	p1_min_pixel_chunk_bytes = min_pixel_chunk_bytes;
5424 	p1_dpte_group_bytes = dpte_group_bytes;
5425 	p1_mpte_group_bytes = mpte_group_bytes;
5426 
5427 	if (source_format == dml2_rgbe_alpha)
5428 		p1_pixel_chunk_bytes = (unsigned int)(mode_lib->ip.alpha_pixel_chunk_size_kbytes * 1024);
5429 
5430 	rq_regs->unbounded_request_enabled = mode_lib->mp.UnboundedRequestEnabled;
5431 	rq_regs->pte_buffer_mode = mode_lib->mp.PTE_BUFFER_MODE[mode_lib->mp.pipe_plane[pipe_idx]];
5432 	rq_regs->force_one_row_for_frame = mode_lib->mp.use_one_row_for_frame[mode_lib->mp.pipe_plane[pipe_idx]];
5433 	rq_regs->rq_regs_l.chunk_size = dml2_core_utils_log_and_substract_if_non_zero(pixel_chunk_bytes, 10);
5434 	rq_regs->rq_regs_c.chunk_size = dml2_core_utils_log_and_substract_if_non_zero(p1_pixel_chunk_bytes, 10);
5435 
5436 	DML_LOG_VERBOSE("DML_DLG: %s: pte_buffer_mode = %u\n", __func__, rq_regs->pte_buffer_mode);
5437 	DML_LOG_VERBOSE("DML_DLG: %s: force_one_row_for_frame = %u\n", __func__, rq_regs->force_one_row_for_frame);
5438 
5439 	if (min_pixel_chunk_bytes == 0)
5440 		rq_regs->rq_regs_l.min_chunk_size = 0;
5441 	else
5442 		rq_regs->rq_regs_l.min_chunk_size = dml2_core_utils_log_and_substract_if_non_zero(min_pixel_chunk_bytes, 8 - 1);
5443 
5444 	if (p1_min_pixel_chunk_bytes == 0)
5445 		rq_regs->rq_regs_c.min_chunk_size = 0;
5446 	else
5447 		rq_regs->rq_regs_c.min_chunk_size = dml2_core_utils_log_and_substract_if_non_zero(p1_min_pixel_chunk_bytes, 8 - 1);
5448 
5449 	rq_regs->rq_regs_l.dpte_group_size = dml2_core_utils_log_and_substract_if_non_zero(dpte_group_bytes, 6);
5450 	rq_regs->rq_regs_l.mpte_group_size = dml2_core_utils_log_and_substract_if_non_zero(mpte_group_bytes, 6);
5451 	rq_regs->rq_regs_c.dpte_group_size = dml2_core_utils_log_and_substract_if_non_zero(p1_dpte_group_bytes, 6);
5452 	rq_regs->rq_regs_c.mpte_group_size = dml2_core_utils_log_and_substract_if_non_zero(p1_mpte_group_bytes, 6);
5453 
5454 	detile_buf_size_in_bytes = mode_lib->mp.DETBufferSizeInKByte[mode_lib->mp.pipe_plane[pipe_idx]] * 1024;
5455 
5456 	if (dml2_core_utils_is_linear(sw_mode) && display_cfg->gpuvm_enable) {
5457 		unsigned int p0_pte_row_height_linear = mode_lib->mp.dpte_row_height_linear[mode_lib->mp.pipe_plane[pipe_idx]];
5458 		DML_LOG_VERBOSE("DML_DLG: %s: p0_pte_row_height_linear = %u\n", __func__, p0_pte_row_height_linear);
5459 		DML_ASSERT(p0_pte_row_height_linear >= 8);
5460 
5461 		rq_regs->rq_regs_l.pte_row_height_linear = math_log2_approx(p0_pte_row_height_linear) - 3;
5462 		if (dual_plane) {
5463 			unsigned int p1_pte_row_height_linear = mode_lib->mp.dpte_row_height_linear_chroma[mode_lib->mp.pipe_plane[pipe_idx]];
5464 			DML_LOG_VERBOSE("DML_DLG: %s: p1_pte_row_height_linear = %u\n", __func__, p1_pte_row_height_linear);
5465 			if (sw_mode == dml2_sw_linear) {
5466 				DML_ASSERT(p1_pte_row_height_linear >= 8);
5467 			}
5468 			rq_regs->rq_regs_c.pte_row_height_linear = math_log2_approx(p1_pte_row_height_linear) - 3;
5469 		}
5470 	} else {
5471 		rq_regs->rq_regs_l.pte_row_height_linear = 0;
5472 		rq_regs->rq_regs_c.pte_row_height_linear = 0;
5473 	}
5474 
5475 	rq_regs->rq_regs_l.swath_height = dml2_core_utils_log_and_substract_if_non_zero(mode_lib->mp.SwathHeightY[mode_lib->mp.pipe_plane[pipe_idx]], 0);
5476 	rq_regs->rq_regs_c.swath_height = dml2_core_utils_log_and_substract_if_non_zero(mode_lib->mp.SwathHeightC[mode_lib->mp.pipe_plane[pipe_idx]], 0);
5477 
5478 	// FIXME_DCN4, programming guide has dGPU condition
5479 	if (pixel_chunk_bytes >= 32 * 1024 || (dual_plane && p1_pixel_chunk_bytes >= 32 * 1024)) { //32kb
5480 		rq_regs->drq_expansion_mode = 0;
5481 	} else {
5482 		rq_regs->drq_expansion_mode = 2;
5483 	}
5484 	rq_regs->prq_expansion_mode = 1;
5485 	rq_regs->crq_expansion_mode = 1;
5486 	rq_regs->mrq_expansion_mode = 1;
5487 
5488 	stored_swath_l_bytes = mode_lib->mp.DETBufferSizeY[mode_lib->mp.pipe_plane[pipe_idx]];
5489 	stored_swath_c_bytes = mode_lib->mp.DETBufferSizeC[mode_lib->mp.pipe_plane[pipe_idx]];
5490 
5491 	// Note: detile_buf_plane1_addr is in unit of 1KB
5492 	if (dual_plane) {
5493 		if (stored_swath_l_bytes / stored_swath_c_bytes <= 1.5) {
5494 			detile_buf_plane1_addr = (unsigned int)(detile_buf_size_in_bytes / 2.0 / 1024.0); // half to chroma
5495 			DML_LOG_VERBOSE("DML_DLG: %s: detile_buf_plane1_addr = %d (1/2 to chroma)\n", __func__, detile_buf_plane1_addr);
5496 		} else {
5497 			detile_buf_plane1_addr = (unsigned int)(dml2_core_utils_round_to_multiple((unsigned int)((2.0 * detile_buf_size_in_bytes) / 3.0), 1024, 0) / 1024.0); // 2/3 to luma
5498 			DML_LOG_VERBOSE("DML_DLG: %s: detile_buf_plane1_addr = %d (1/3 chroma)\n", __func__, detile_buf_plane1_addr);
5499 		}
5500 	}
5501 	rq_regs->plane1_base_address = detile_buf_plane1_addr;
5502 
5503 	DML_LOG_VERBOSE("DML_DLG: %s: stored_swath_l_bytes = %f\n", __func__, stored_swath_l_bytes);
5504 	DML_LOG_VERBOSE("DML_DLG: %s: stored_swath_c_bytes = %f\n", __func__, stored_swath_c_bytes);
5505 	DML_LOG_VERBOSE("DML_DLG: %s: detile_buf_size_in_bytes = %d\n", __func__, detile_buf_size_in_bytes);
5506 	DML_LOG_VERBOSE("DML_DLG: %s: detile_buf_plane1_addr = %d\n", __func__, detile_buf_plane1_addr);
5507 	DML_LOG_VERBOSE("DML_DLG: %s: plane1_base_address = %d\n", __func__, rq_regs->plane1_base_address);
5508 	DML_LOG_VERBOSE("DML_DLG::%s: Calculation for pipe[%d] done\n", __func__, pipe_idx);
5509 }
5510 
dcn5_rq_dlg_get_dlg_reg(struct dml2_core_internal_scratch * s,struct dml2_display_dlg_regs * disp_dlg_regs,struct dml2_display_ttu_regs * disp_ttu_regs,const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,const unsigned int pipe_idx,const struct dml2_utm_soc_bb * utm_soc_bb)5511 static void dcn5_rq_dlg_get_dlg_reg(
5512 		struct dml2_core_internal_scratch *s,
5513 		struct dml2_display_dlg_regs *disp_dlg_regs,
5514 		struct dml2_display_ttu_regs *disp_ttu_regs,
5515 		const struct dml2_display_cfg *display_cfg,
5516 		const struct dml2_core_internal_display_mode_lib *mode_lib,
5517 		const unsigned int pipe_idx,
5518 		const struct dml2_utm_soc_bb *utm_soc_bb)
5519 {
5520 	struct dml2_core_shared_rq_dlg_get_dlg_reg_locals *l = &s->rq_dlg_get_dlg_reg_locals;
5521 
5522 	memset(l, 0, sizeof(struct dml2_core_shared_rq_dlg_get_dlg_reg_locals));
5523 
5524 	DML_LOG_VERBOSE("DML_DLG::%s: Calculation for pipe_idx=%d\n", __func__, pipe_idx);
5525 
5526 	l->plane_idx = mode_lib->mp.pipe_plane[pipe_idx];
5527 	DML_ASSERT(l->plane_idx < DML2_MAX_PLANES);
5528 
5529 	l->source_format = dml2_444_8;
5530 	l->odm_mode = dml2_odm_mode_bypass;
5531 	l->dual_plane = false;
5532 	l->htotal = 0;
5533 	l->hactive = 0;
5534 	l->hblank_end = 0;
5535 	l->vblank_end = 0;
5536 	l->interlaced = false;
5537 	l->pclk_freq_in_mhz = 0.0;
5538 	l->refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : utm_soc_bb->dchub_refclk_mhz;
5539 	l->ref_freq_to_pix_freq = 0.0;
5540 
5541 	if (l->plane_idx < DML2_MAX_PLANES) {
5542 
5543 		l->timing = &display_cfg->stream_descriptors[display_cfg->plane_descriptors[l->plane_idx].stream_index].timing;
5544 		l->source_format = display_cfg->plane_descriptors[l->plane_idx].pixel_format;
5545 		l->odm_mode = mode_lib->mp.ODMMode[l->plane_idx];
5546 
5547 		l->dual_plane = dml2_core_utils_is_dual_plane(l->source_format);
5548 
5549 		l->htotal = l->timing->h_total;
5550 		l->hactive = l->timing->h_active;
5551 		l->hblank_end = l->timing->h_blank_end;
5552 		l->vblank_end = l->timing->v_blank_end;
5553 		l->interlaced = l->timing->interlaced;
5554 		l->pclk_freq_in_mhz = (double)l->timing->pixel_clock_khz / 1000;
5555 		l->ref_freq_to_pix_freq = l->refclk_freq_in_mhz / l->pclk_freq_in_mhz;
5556 
5557 		DML_LOG_VERBOSE("DML_DLG::%s: plane_idx = %d\n", __func__, l->plane_idx);
5558 		DML_LOG_VERBOSE("DML_DLG: %s: htotal = %d\n", __func__, l->htotal);
5559 		DML_LOG_VERBOSE("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, l->refclk_freq_in_mhz);
5560 		DML_LOG_VERBOSE("DML_DLG: %s: dlg_ref_clk_mhz = %3.2f\n", __func__, display_cfg->overrides.hw.dlg_ref_clk_mhz);
5561 		DML_LOG_VERBOSE("DML_DLG: %s: soc.refclk_mhz = %u\n", __func__, utm_soc_bb->dchub_refclk_mhz);
5562 		DML_LOG_VERBOSE("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, l->pclk_freq_in_mhz);
5563 		DML_LOG_VERBOSE("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, l->ref_freq_to_pix_freq);
5564 		DML_LOG_VERBOSE("DML_DLG: %s: interlaced = %d\n", __func__, l->interlaced);
5565 
5566 		DML_ASSERT(l->refclk_freq_in_mhz != 0);
5567 		DML_ASSERT(l->pclk_freq_in_mhz != 0);
5568 		DML_ASSERT(l->ref_freq_to_pix_freq < 4.0);
5569 
5570 		// Need to figure out which side of odm combine we're in
5571 		// Assume the pipe instance under the same plane is in order
5572 
5573 		if (l->odm_mode == dml2_odm_mode_bypass) {
5574 			disp_dlg_regs->refcyc_h_blank_end = (unsigned int)((double)l->hblank_end * l->ref_freq_to_pix_freq);
5575 		} else if (l->odm_mode == dml2_odm_mode_combine_2to1 || l->odm_mode == dml2_odm_mode_combine_3to1 || l->odm_mode == dml2_odm_mode_combine_4to1) {
5576 			// find out how many pipe are in this plane
5577 			l->num_active_pipes = mode_lib->mp.num_active_pipes;
5578 			l->first_pipe_idx_in_plane = DML2_MAX_PLANES;
5579 			l->pipe_idx_in_combine = 0; // pipe index within the plane
5580 			l->odm_combine_factor = 2;
5581 
5582 			if (l->odm_mode == dml2_odm_mode_combine_3to1)
5583 				l->odm_combine_factor = 3;
5584 			else if (l->odm_mode == dml2_odm_mode_combine_4to1)
5585 				l->odm_combine_factor = 4;
5586 
5587 			for (unsigned int i = 0; i < l->num_active_pipes; i++) {
5588 				if (mode_lib->mp.pipe_plane[i] == l->plane_idx) {
5589 					if (i < l->first_pipe_idx_in_plane) {
5590 						l->first_pipe_idx_in_plane = i;
5591 					}
5592 				}
5593 			}
5594 			l->pipe_idx_in_combine = pipe_idx - l->first_pipe_idx_in_plane; // DML assumes the pipes in the same plane will have continuous indexing (i.e. plane 0 use pipe 0, 1, and plane 1 uses pipe 2, 3, etc.)
5595 
5596 			disp_dlg_regs->refcyc_h_blank_end = (unsigned int)(((double)l->hblank_end + (double)l->pipe_idx_in_combine * (double)l->hactive / (double)l->odm_combine_factor) * l->ref_freq_to_pix_freq);
5597 			DML_LOG_VERBOSE("DML_DLG: %s: pipe_idx = %d\n", __func__, pipe_idx);
5598 			DML_LOG_VERBOSE("DML_DLG: %s: first_pipe_idx_in_plane = %d\n", __func__, l->first_pipe_idx_in_plane);
5599 			DML_LOG_VERBOSE("DML_DLG: %s: pipe_idx_in_combine = %d\n", __func__, l->pipe_idx_in_combine);
5600 			DML_LOG_VERBOSE("DML_DLG: %s: odm_combine_factor = %d\n", __func__, l->odm_combine_factor);
5601 		}
5602 		DML_LOG_VERBOSE("DML_DLG: %s: refcyc_h_blank_end = %d\n", __func__, disp_dlg_regs->refcyc_h_blank_end);
5603 
5604 		DML_ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int)math_pow(2, 13));
5605 
5606 		disp_dlg_regs->ref_freq_to_pix_freq = (unsigned int)(l->ref_freq_to_pix_freq * math_pow(2, 19));
5607 		disp_dlg_regs->refcyc_per_htotal = (unsigned int)(l->ref_freq_to_pix_freq * (double)l->htotal * math_pow(2, 8));
5608 		disp_dlg_regs->dlg_vblank_end = l->interlaced ? (l->vblank_end / 2) : l->vblank_end; // 15 bits
5609 
5610 		l->min_ttu_vblank = mode_lib->mp.MinTTUVBlank[mode_lib->mp.pipe_plane[pipe_idx]];
5611 		l->min_dst_y_next_start = (unsigned int)(mode_lib->mp.MIN_DST_Y_NEXT_START[mode_lib->mp.pipe_plane[pipe_idx]]);
5612 
5613 		DML_LOG_VERBOSE("DML_DLG: %s: min_ttu_vblank (us) = %3.2f\n", __func__, l->min_ttu_vblank);
5614 		DML_LOG_VERBOSE("DML_DLG: %s: min_dst_y_next_start = %d\n", __func__, l->min_dst_y_next_start);
5615 		DML_LOG_VERBOSE("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, l->ref_freq_to_pix_freq);
5616 
5617 		l->vready_after_vcount0 = (unsigned int)(mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[mode_lib->mp.pipe_plane[pipe_idx]]);
5618 		disp_dlg_regs->vready_after_vcount0 = l->vready_after_vcount0;
5619 
5620 		DML_LOG_VERBOSE("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, disp_dlg_regs->vready_after_vcount0);
5621 
5622 		l->dst_x_after_scaler = (unsigned int)(mode_lib->mp.DSTXAfterScaler[mode_lib->mp.pipe_plane[pipe_idx]]);
5623 		l->dst_y_after_scaler = (unsigned int)(mode_lib->mp.DSTYAfterScaler[mode_lib->mp.pipe_plane[pipe_idx]]);
5624 
5625 		DML_LOG_VERBOSE("DML_DLG: %s: dst_x_after_scaler = %d\n", __func__, l->dst_x_after_scaler);
5626 		DML_LOG_VERBOSE("DML_DLG: %s: dst_y_after_scaler = %d\n", __func__, l->dst_y_after_scaler);
5627 
5628 		l->dst_y_prefetch = mode_lib->mp.dst_y_prefetch[mode_lib->mp.pipe_plane[pipe_idx]];
5629 		l->dst_y_per_vm_vblank = mode_lib->mp.dst_y_per_vm_vblank[mode_lib->mp.pipe_plane[pipe_idx]];
5630 		l->dst_y_per_row_vblank = mode_lib->mp.dst_y_per_row_vblank[mode_lib->mp.pipe_plane[pipe_idx]];
5631 		l->dst_y_per_vm_flip = mode_lib->mp.dst_y_per_vm_flip[mode_lib->mp.pipe_plane[pipe_idx]];
5632 		l->dst_y_per_row_flip = mode_lib->mp.dst_y_per_row_flip[mode_lib->mp.pipe_plane[pipe_idx]];
5633 
5634 		DML_LOG_VERBOSE("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, l->dst_y_prefetch);
5635 		DML_LOG_VERBOSE("DML_DLG: %s: dst_y_per_vm_flip = %3.2f\n", __func__, l->dst_y_per_vm_flip);
5636 		DML_LOG_VERBOSE("DML_DLG: %s: dst_y_per_row_flip = %3.2f\n", __func__, l->dst_y_per_row_flip);
5637 		DML_LOG_VERBOSE("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, l->dst_y_per_vm_vblank);
5638 		DML_LOG_VERBOSE("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, l->dst_y_per_row_vblank);
5639 
5640 		if (l->dst_y_prefetch > 0 && l->dst_y_per_vm_vblank > 0 && l->dst_y_per_row_vblank > 0) {
5641 			DML_ASSERT(l->dst_y_prefetch > (l->dst_y_per_vm_vblank + l->dst_y_per_row_vblank));
5642 		}
5643 
5644 		l->vratio_pre_l = mode_lib->mp.VRatioPrefetchY[mode_lib->mp.pipe_plane[pipe_idx]];
5645 		l->vratio_pre_c = mode_lib->mp.VRatioPrefetchC[mode_lib->mp.pipe_plane[pipe_idx]];
5646 
5647 		DML_LOG_VERBOSE("DML_DLG: %s: vratio_pre_l = %3.2f\n", __func__, l->vratio_pre_l);
5648 		DML_LOG_VERBOSE("DML_DLG: %s: vratio_pre_c = %3.2f\n", __func__, l->vratio_pre_c);
5649 
5650 		// Active
5651 		l->refcyc_per_line_delivery_pre_l = mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5652 		l->refcyc_per_line_delivery_l = mode_lib->mp.DisplayPipeLineDeliveryTimeLuma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5653 
5654 		DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", __func__, l->refcyc_per_line_delivery_pre_l);
5655 		DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n", __func__, l->refcyc_per_line_delivery_l);
5656 
5657 		l->refcyc_per_line_delivery_pre_c = 0.0;
5658 		l->refcyc_per_line_delivery_c = 0.0;
5659 
5660 		if (l->dual_plane) {
5661 			l->refcyc_per_line_delivery_pre_c = mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5662 			l->refcyc_per_line_delivery_c = mode_lib->mp.DisplayPipeLineDeliveryTimeChroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5663 
5664 			DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n", __func__, l->refcyc_per_line_delivery_pre_c);
5665 			DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n", __func__, l->refcyc_per_line_delivery_c);
5666 		}
5667 
5668 		disp_dlg_regs->refcyc_per_vm_dmdata = (unsigned int)(mode_lib->mp.Tdmdl_vm[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz);
5669 		disp_dlg_regs->dmdata_dl_delta = (unsigned int)(mode_lib->mp.Tdmdl[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz);
5670 
5671 		l->refcyc_per_req_delivery_pre_l = mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5672 		l->refcyc_per_req_delivery_l = mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5673 
5674 		DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", __func__, l->refcyc_per_req_delivery_pre_l);
5675 		DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n", __func__, l->refcyc_per_req_delivery_l);
5676 
5677 		l->refcyc_per_req_delivery_pre_c = 0.0;
5678 		l->refcyc_per_req_delivery_c = 0.0;
5679 		if (l->dual_plane) {
5680 			l->refcyc_per_req_delivery_pre_c = mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5681 			l->refcyc_per_req_delivery_c = mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5682 
5683 			DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n", __func__, l->refcyc_per_req_delivery_pre_c);
5684 			DML_LOG_VERBOSE("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n", __func__, l->refcyc_per_req_delivery_c);
5685 		}
5686 
5687 		// TTU - Cursor
5688 		DML_ASSERT(display_cfg->plane_descriptors[l->plane_idx].cursor.num_cursors <= 1);
5689 
5690 		// Assign to register structures
5691 		disp_dlg_regs->min_dst_y_next_start = (unsigned int)((double)l->min_dst_y_next_start * math_pow(2, 2));
5692 		DML_ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int)math_pow(2, 18));
5693 
5694 		disp_dlg_regs->dst_y_after_scaler = l->dst_y_after_scaler; // in terms of line
5695 		disp_dlg_regs->refcyc_x_after_scaler = (unsigned int)((double)l->dst_x_after_scaler * l->ref_freq_to_pix_freq); // in terms of refclk
5696 		disp_dlg_regs->dst_y_prefetch = (unsigned int)(l->dst_y_prefetch * math_pow(2, 2));
5697 		disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int)(l->dst_y_per_vm_vblank * math_pow(2, 2));
5698 		disp_dlg_regs->dst_y_per_row_vblank = (unsigned int)(l->dst_y_per_row_vblank * math_pow(2, 2));
5699 		disp_dlg_regs->dst_y_per_vm_flip = (unsigned int)(l->dst_y_per_vm_flip * math_pow(2, 2));
5700 		disp_dlg_regs->dst_y_per_row_flip = (unsigned int)(l->dst_y_per_row_flip * math_pow(2, 2));
5701 
5702 		disp_dlg_regs->vratio_prefetch = (unsigned int)(l->vratio_pre_l * math_pow(2, 19));
5703 		disp_dlg_regs->vratio_prefetch_c = (unsigned int)(l->vratio_pre_c * math_pow(2, 19));
5704 
5705 		DML_LOG_VERBOSE("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_vblank);
5706 		DML_LOG_VERBOSE("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_vblank);
5707 		DML_LOG_VERBOSE("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_flip = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_flip);
5708 		DML_LOG_VERBOSE("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_flip = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_flip);
5709 
5710 		disp_dlg_regs->refcyc_per_vm_group_vblank = (unsigned int)(mode_lib->mp.TimePerVMGroupVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz);
5711 		disp_dlg_regs->refcyc_per_vm_group_flip = (unsigned int)(mode_lib->mp.TimePerVMGroupFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz);
5712 		disp_dlg_regs->refcyc_per_vm_req_vblank = (unsigned int)(mode_lib->mp.TimePerVMRequestVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz * math_pow(2, 10));
5713 		disp_dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(mode_lib->mp.TimePerVMRequestFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz * math_pow(2, 10));
5714 
5715 		l->dst_y_per_pte_row_nom_l = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L[mode_lib->mp.pipe_plane[pipe_idx]];
5716 		l->dst_y_per_pte_row_nom_c = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C[mode_lib->mp.pipe_plane[pipe_idx]];
5717 		l->refcyc_per_pte_group_nom_l = mode_lib->mp.time_per_pte_group_nom_luma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5718 		l->refcyc_per_pte_group_nom_c = mode_lib->mp.time_per_pte_group_nom_chroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5719 		l->refcyc_per_pte_group_vblank_l = mode_lib->mp.time_per_pte_group_vblank_luma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5720 		l->refcyc_per_pte_group_vblank_c = mode_lib->mp.time_per_pte_group_vblank_chroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5721 		l->refcyc_per_pte_group_flip_l = mode_lib->mp.time_per_pte_group_flip_luma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5722 		l->refcyc_per_pte_group_flip_c = mode_lib->mp.time_per_pte_group_flip_chroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5723 		l->refcyc_per_tdlut_group = mode_lib->mp.time_per_tdlut_group[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5724 
5725 		disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int)(l->dst_y_per_pte_row_nom_l * math_pow(2, 2));
5726 		disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int)(l->dst_y_per_pte_row_nom_c * math_pow(2, 2));
5727 
5728 		disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)(l->refcyc_per_pte_group_nom_l);
5729 		disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int)(l->refcyc_per_pte_group_nom_c);
5730 		disp_dlg_regs->refcyc_per_pte_group_vblank_l = (unsigned int)(l->refcyc_per_pte_group_vblank_l);
5731 		disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int)(l->refcyc_per_pte_group_vblank_c);
5732 		disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int)(l->refcyc_per_pte_group_flip_l);
5733 		disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int)(l->refcyc_per_pte_group_flip_c);
5734 		disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int)math_floor2(l->refcyc_per_line_delivery_pre_l, 1);
5735 		disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int)math_floor2(l->refcyc_per_line_delivery_l, 1);
5736 		disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int)math_floor2(l->refcyc_per_line_delivery_pre_c, 1);
5737 		disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int)math_floor2(l->refcyc_per_line_delivery_c, 1);
5738 
5739 		l->dst_y_per_meta_row_nom_l = mode_lib->mp.DST_Y_PER_META_ROW_NOM_L[mode_lib->mp.pipe_plane[pipe_idx]];
5740 		l->dst_y_per_meta_row_nom_c = mode_lib->mp.DST_Y_PER_META_ROW_NOM_C[mode_lib->mp.pipe_plane[pipe_idx]];
5741 		l->refcyc_per_meta_chunk_nom_l = mode_lib->mp.TimePerMetaChunkNominal[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5742 		l->refcyc_per_meta_chunk_nom_c = mode_lib->mp.TimePerChromaMetaChunkNominal[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5743 		l->refcyc_per_meta_chunk_vblank_l = mode_lib->mp.TimePerMetaChunkVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5744 		l->refcyc_per_meta_chunk_vblank_c = mode_lib->mp.TimePerChromaMetaChunkVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5745 		l->refcyc_per_meta_chunk_flip_l = mode_lib->mp.TimePerMetaChunkFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5746 		l->refcyc_per_meta_chunk_flip_c = mode_lib->mp.TimePerChromaMetaChunkFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz;
5747 
5748 		disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int)(l->dst_y_per_meta_row_nom_l * math_pow(2, 2));
5749 		disp_dlg_regs->dst_y_per_meta_row_nom_c = (unsigned int)(l->dst_y_per_meta_row_nom_c * math_pow(2, 2));
5750 		disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int)(l->refcyc_per_meta_chunk_nom_l);
5751 		disp_dlg_regs->refcyc_per_meta_chunk_nom_c = (unsigned int)(l->refcyc_per_meta_chunk_nom_c);
5752 		disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = (unsigned int)(l->refcyc_per_meta_chunk_vblank_l);
5753 		disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = (unsigned int)(l->refcyc_per_meta_chunk_vblank_c);
5754 		disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int)(l->refcyc_per_meta_chunk_flip_l);
5755 		disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int)(l->refcyc_per_meta_chunk_flip_c);
5756 
5757 		disp_dlg_regs->refcyc_per_tdlut_group = (unsigned int)(l->refcyc_per_tdlut_group);
5758 		disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
5759 
5760 		disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int)(l->refcyc_per_req_delivery_pre_l * math_pow(2, 10));
5761 		disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int)(l->refcyc_per_req_delivery_l * math_pow(2, 10));
5762 		disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int)(l->refcyc_per_req_delivery_pre_c * math_pow(2, 10));
5763 		disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int)(l->refcyc_per_req_delivery_c * math_pow(2, 10));
5764 		disp_ttu_regs->qos_level_low_wm = 0;
5765 
5766 		disp_ttu_regs->qos_level_high_wm = (unsigned int)(4.0 * (double)l->htotal * l->ref_freq_to_pix_freq);
5767 
5768 		disp_ttu_regs->qos_level_flip = 14;
5769 		disp_ttu_regs->qos_level_fixed_l = 8;
5770 		disp_ttu_regs->qos_level_fixed_c = 8;
5771 		disp_ttu_regs->qos_ramp_disable_l = 0;
5772 		disp_ttu_regs->qos_ramp_disable_c = 0;
5773 		disp_ttu_regs->min_ttu_vblank = (unsigned int)(l->min_ttu_vblank * l->refclk_freq_in_mhz);
5774 
5775 		// CHECK for HW registers' range, DML_ASSERT or clamp
5776 		DML_ASSERT(l->refcyc_per_req_delivery_pre_l < math_pow(2, 13));
5777 		DML_ASSERT(l->refcyc_per_req_delivery_l < math_pow(2, 13));
5778 		DML_ASSERT(l->refcyc_per_req_delivery_pre_c < math_pow(2, 13));
5779 		DML_ASSERT(l->refcyc_per_req_delivery_c < math_pow(2, 13));
5780 		if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int)math_pow(2, 23))
5781 			disp_dlg_regs->refcyc_per_vm_group_vblank = (unsigned int)(math_pow(2, 23) - 1);
5782 
5783 		if (disp_dlg_regs->refcyc_per_vm_group_flip >= (unsigned int)math_pow(2, 23))
5784 			disp_dlg_regs->refcyc_per_vm_group_flip = (unsigned int)(math_pow(2, 23) - 1);
5785 
5786 		if (disp_dlg_regs->refcyc_per_vm_req_vblank >= (unsigned int)math_pow(2, 23))
5787 			disp_dlg_regs->refcyc_per_vm_req_vblank = (unsigned int)(math_pow(2, 23) - 1);
5788 
5789 		if (disp_dlg_regs->refcyc_per_vm_req_flip >= (unsigned int)math_pow(2, 23))
5790 			disp_dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(math_pow(2, 23) - 1);
5791 
5792 
5793 		DML_ASSERT(disp_dlg_regs->dst_y_after_scaler < (unsigned int)8);
5794 		DML_ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int)math_pow(2, 13));
5795 
5796 		if (disp_dlg_regs->dst_y_per_pte_row_nom_l >= (unsigned int)math_pow(2, 17)) {
5797 			DML_LOG_VERBOSE("DML_DLG: %s: Warning DST_Y_PER_PTE_ROW_NOM_L %u > register max U15.2 %u, clamp to max\n", __func__, disp_dlg_regs->dst_y_per_pte_row_nom_l, (unsigned int)math_pow(2, 17) - 1);
5798 			l->dst_y_per_pte_row_nom_l = (unsigned int)math_pow(2, 17) - 1;
5799 		}
5800 		if (l->dual_plane) {
5801 			if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int)math_pow(2, 17)) {
5802 				DML_LOG_VERBOSE("DML_DLG: %s: Warning DST_Y_PER_PTE_ROW_NOM_C %u > register max U15.2 %u, clamp to max\n", __func__, disp_dlg_regs->dst_y_per_pte_row_nom_c, (unsigned int)math_pow(2, 17) - 1);
5803 				l->dst_y_per_pte_row_nom_c = (unsigned int)math_pow(2, 17) - 1;
5804 			}
5805 		}
5806 
5807 		if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int)math_pow(2, 23))
5808 			disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)(math_pow(2, 23) - 1);
5809 		if (l->dual_plane) {
5810 			if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int)math_pow(2, 23))
5811 				disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int)(math_pow(2, 23) - 1);
5812 		}
5813 		DML_ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int)math_pow(2, 13));
5814 		if (l->dual_plane) {
5815 			DML_ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int)math_pow(2, 13));
5816 		}
5817 
5818 		DML_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int)math_pow(2, 13));
5819 		DML_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int)math_pow(2, 13));
5820 		DML_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int)math_pow(2, 13));
5821 		DML_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int)math_pow(2, 13));
5822 		DML_ASSERT(disp_ttu_regs->qos_level_low_wm < (unsigned int)math_pow(2, 14));
5823 		DML_ASSERT(disp_ttu_regs->qos_level_high_wm < (unsigned int)math_pow(2, 14));
5824 		DML_ASSERT(disp_ttu_regs->min_ttu_vblank < (unsigned int)math_pow(2, 24));
5825 		DML_LOG_VERBOSE("DML_DLG::%s: Calculation for pipe[%d] done\n", __func__, pipe_idx);
5826 	}
5827 }
5828 
dcn5_rq_dlg_get_arb_params(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_utm_soc_bb * utm_soc_bb,struct dml2_display_arb_regs * arb_param)5829 static void dcn5_rq_dlg_get_arb_params(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, const struct dml2_utm_soc_bb *utm_soc_bb, struct dml2_display_arb_regs *arb_param)
5830 {
5831 	double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : utm_soc_bb->dchub_refclk_mhz;
5832 
5833 	arb_param->max_req_outstanding = utm_soc_bb->max_outstanding_reqs;
5834 	arb_param->min_req_outstanding = utm_soc_bb->max_outstanding_reqs; // turn off the sat level feature if this set to max
5835 	arb_param->sdpif_request_rate_limit = (3 * mode_lib->ip.words_per_channel * utm_soc_bb->dram_config.channel_count) / 4;
5836 	arb_param->sdpif_request_rate_limit = arb_param->sdpif_request_rate_limit < 96 ? 96 : arb_param->sdpif_request_rate_limit;
5837 	arb_param->sat_level_us = 60;
5838 	arb_param->hvm_max_qos_commit_threshold = 0xf;
5839 	arb_param->hvm_min_req_outstand_commit_threshold = 0xa;
5840 	arb_param->compbuf_reserved_space_kbytes = mode_lib->mp.compbuf_reserved_space_64b * 64 / 1024;
5841 	arb_param->compbuf_size = mode_lib->mp.CompressedBufferSizeInkByte / mode_lib->ip.compressed_buffer_segment_size_in_kbytes;
5842 	arb_param->allow_sdpif_rate_limit_when_cstate_req = mode_lib->mp.hw_debug5;
5843 	arb_param->dcfclk_deep_sleep_hysteresis = mode_lib->mp.dcfclk_deep_sleep_hysteresis;
5844 	arb_param->pstate_stall_threshold = (unsigned int)(mode_lib->ip_caps.fams2.max_allow_delay_us * refclk_freq_in_mhz);
5845 
5846 	DML_LOG_VERBOSE("DML::%s: max_req_outstanding = %d\n", __func__, arb_param->max_req_outstanding);
5847 	DML_LOG_VERBOSE("DML::%s: sdpif_request_rate_limit = %d\n", __func__, arb_param->sdpif_request_rate_limit);
5848 	DML_LOG_VERBOSE("DML::%s: compbuf_reserved_space_kbytes = %d\n", __func__, arb_param->compbuf_reserved_space_kbytes);
5849 	DML_LOG_VERBOSE("DML::%s: allow_sdpif_rate_limit_when_cstate_req = %d\n", __func__, arb_param->allow_sdpif_rate_limit_when_cstate_req);
5850 	DML_LOG_VERBOSE("DML::%s: dcfclk_deep_sleep_hysteresis = %d\n", __func__, arb_param->dcfclk_deep_sleep_hysteresis);
5851 }
5852 
dcn5_get_watermarks(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_utm_soc_bb * utm_soc_bb,struct dml2_dchub_watermark_regs * out)5853 void dcn5_get_watermarks(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, const struct dml2_utm_soc_bb *utm_soc_bb, struct dml2_dchub_watermark_regs *out)
5854 {
5855 	dcn5_rq_dlg_get_wm_regs(display_cfg, mode_lib, utm_soc_bb, out);
5856 }
5857 
dcn5_get_arb_params(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_utm_soc_bb * utm_soc_bb,struct dml2_display_arb_regs * out)5858 void dcn5_get_arb_params(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, const struct dml2_utm_soc_bb *utm_soc_bb, struct dml2_display_arb_regs *out)
5859 {
5860 	dcn5_rq_dlg_get_arb_params(display_cfg, mode_lib, utm_soc_bb, out);
5861 }
5862 
dcn5_get_pipe_regs(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,struct dml2_dchub_per_pipe_register_set * out,int pipe_index,const struct dml2_utm_soc_bb * utm_soc_bb,struct dml2_core_internal_scratch * s)5863 void dcn5_get_pipe_regs(const struct dml2_display_cfg *display_cfg,
5864 		const struct dml2_core_internal_display_mode_lib *mode_lib,
5865 		struct dml2_dchub_per_pipe_register_set *out, int pipe_index,
5866 		const struct dml2_utm_soc_bb *utm_soc_bb,
5867 		struct dml2_core_internal_scratch *s)
5868 {
5869 	dcn5_rq_dlg_get_rq_reg(&out->rq_regs, display_cfg, mode_lib, pipe_index);
5870 	dcn5_rq_dlg_get_dlg_reg(s, &out->dlg_regs, &out->ttu_regs, display_cfg, mode_lib, pipe_index, utm_soc_bb);
5871 	out->det_size = mode_lib->mp.DETBufferSizeInKByte[mode_lib->mp.pipe_plane[pipe_index]] / mode_lib->ip.config_return_buffer_segment_size_in_kbytes;
5872 }
5873 
dcn5_get_per_dwb_params(const struct dml2_display_cfg * display_cfg,const struct dml2_core_internal_display_mode_lib * mode_lib,struct dml2_mcif_per_pipe_register_set * out,int stream_index,int dwb_index)5874 void dcn5_get_per_dwb_params(const struct dml2_display_cfg *display_cfg,
5875 		const struct dml2_core_internal_display_mode_lib *mode_lib,
5876 		struct dml2_mcif_per_pipe_register_set *out,
5877 		int stream_index,
5878 		int dwb_index)
5879 {
5880 	double writeback_latency_hiding_us = dcn5_calculate_writeback_latency_hiding_us(display_cfg,
5881 					mode_lib->ip.writeback_interface_buffer_size_kbytes * 1024,
5882 					stream_index,
5883 					dwb_index);
5884 
5885 	out->max_scaled_time_ns = (unsigned int)math_max2(
5886 			(writeback_latency_hiding_us - mode_lib->mp.Watermark.WritebackUrgentWatermark) * 1000.0,
5887 			0.0);
5888 
5889 	/* 1024ps units in U6.6 format */
5890 	out->time_per_pixel = (unsigned int)((1000000.0 * math_pow(2, 6)) /
5891 			(double)display_cfg->stream_descriptors[stream_index].timing.pixel_clock_khz);
5892 
5893 	out->slice_lines = 31;
5894 	out->arbitration_slice = 2;
5895 }
5896