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