1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4
5 #include "dml2_core_utils.h"
6
dml2_core_utils_div_rem(double dividend,unsigned int divisor,unsigned int * remainder)7 double dml2_core_utils_div_rem(double dividend, unsigned int divisor, unsigned int *remainder)
8 {
9 *remainder = ((dividend / divisor) - (int)(dividend / divisor) > 0);
10 return dividend / divisor;
11
12 }
13
dml2_core_utils_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type)14 const char *dml2_core_utils_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type)
15 {
16 switch (bw_type) {
17 case (dml2_core_internal_bw_sdp):
18 return("dml2_core_internal_bw_sdp");
19 case (dml2_core_internal_bw_dram):
20 return("dml2_core_internal_bw_dram");
21 case (dml2_core_internal_bw_max):
22 return("dml2_core_internal_bw_max");
23 default:
24 return("dml2_core_internal_bw_unknown");
25 }
26 }
27
dml2_core_utils_is_420(enum dml2_source_format_class source_format)28 bool dml2_core_utils_is_420(enum dml2_source_format_class source_format)
29 {
30 bool val = false;
31
32 switch (source_format) {
33 case dml2_444_8:
34 val = 0;
35 break;
36 case dml2_444_16:
37 val = 0;
38 break;
39 case dml2_444_32:
40 val = 0;
41 break;
42 case dml2_444_64:
43 val = 0;
44 break;
45 case dml2_420_8:
46 val = 1;
47 break;
48 case dml2_420_10:
49 val = 1;
50 break;
51 case dml2_420_12:
52 val = 1;
53 break;
54 case dml2_rgbe_alpha:
55 val = 0;
56 break;
57 case dml2_rgbe:
58 val = 0;
59 break;
60 case dml2_mono_8:
61 val = 0;
62 break;
63 case dml2_mono_16:
64 val = 0;
65 break;
66 case dml2_422_planar_8:
67 val = 0;
68 break;
69 case dml2_422_planar_10:
70 val = 0;
71 break;
72 case dml2_422_planar_12:
73 val = 0;
74 break;
75 case dml2_422_packed_8:
76 val = 0;
77 break;
78 case dml2_422_packed_10:
79 val = 0;
80 break;
81 case dml2_422_packed_12:
82 val = 0;
83 break;
84 default:
85 DML_ASSERT(0);
86 break;
87 }
88 return val;
89 }
90
dml2_core_utils_is_422_planar(enum dml2_source_format_class source_format)91 bool dml2_core_utils_is_422_planar(enum dml2_source_format_class source_format)
92 {
93 bool val = false;
94
95 switch (source_format) {
96 case dml2_444_8:
97 val = 0;
98 break;
99 case dml2_444_16:
100 val = 0;
101 break;
102 case dml2_444_32:
103 val = 0;
104 break;
105 case dml2_444_64:
106 val = 0;
107 break;
108 case dml2_420_8:
109 val = 0;
110 break;
111 case dml2_420_10:
112 val = 0;
113 break;
114 case dml2_420_12:
115 val = 0;
116 break;
117 case dml2_rgbe_alpha:
118 val = 0;
119 break;
120 case dml2_rgbe:
121 val = 0;
122 break;
123 case dml2_mono_8:
124 val = 0;
125 break;
126 case dml2_mono_16:
127 val = 0;
128 break;
129 case dml2_422_planar_8:
130 val = 1;
131 break;
132 case dml2_422_planar_10:
133 val = 1;
134 break;
135 case dml2_422_planar_12:
136 val = 1;
137 break;
138 case dml2_422_packed_8:
139 val = 0;
140 break;
141 case dml2_422_packed_10:
142 val = 0;
143 break;
144 case dml2_422_packed_12:
145 val = 0;
146 break;
147 default:
148 DML_ASSERT(0);
149 break;
150 }
151 return val;
152 }
153
dml2_core_utils_is_422_packed(enum dml2_source_format_class source_format)154 bool dml2_core_utils_is_422_packed(enum dml2_source_format_class source_format)
155 {
156 bool val = false;
157
158 switch (source_format) {
159 case dml2_444_8:
160 val = 0;
161 break;
162 case dml2_444_16:
163 val = 0;
164 break;
165 case dml2_444_32:
166 val = 0;
167 break;
168 case dml2_444_64:
169 val = 0;
170 break;
171 case dml2_420_8:
172 val = 0;
173 break;
174 case dml2_420_10:
175 val = 0;
176 break;
177 case dml2_420_12:
178 val = 0;
179 break;
180 case dml2_rgbe_alpha:
181 val = 0;
182 break;
183 case dml2_rgbe:
184 val = 0;
185 break;
186 case dml2_mono_8:
187 val = 0;
188 break;
189 case dml2_mono_16:
190 val = 0;
191 break;
192 case dml2_422_planar_8:
193 val = 0;
194 break;
195 case dml2_422_planar_10:
196 val = 0;
197 break;
198 case dml2_422_planar_12:
199 val = 0;
200 break;
201 case dml2_422_packed_8:
202 val = 1;
203 break;
204 case dml2_422_packed_10:
205 val = 1;
206 break;
207 case dml2_422_packed_12:
208 val = 1;
209 break;
210 default:
211 DML_ASSERT(0);
212 break;
213 }
214 return val;
215 }
216
dml2_core_utils_print_mode_support_info(const struct dml2_core_internal_mode_support_info * support,bool fail_only)217 void dml2_core_utils_print_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only)
218 {
219 DML_LOG_VERBOSE("DML: ===================================== \n");
220 DML_LOG_VERBOSE("DML: DML_MODE_SUPPORT_INFO_ST\n");
221 if (!fail_only || support->ScaleRatioAndTapsSupport == 0)
222 DML_LOG_VERBOSE("DML: support: ScaleRatioAndTapsSupport = %d\n", support->ScaleRatioAndTapsSupport);
223 if (!fail_only || support->SourceFormatPixelAndScanSupport == 0)
224 DML_LOG_VERBOSE("DML: support: SourceFormatPixelAndScanSupport = %d\n", support->SourceFormatPixelAndScanSupport);
225 if (!fail_only || support->ViewportSizeSupport == 0)
226 DML_LOG_VERBOSE("DML: support: ViewportSizeSupport = %d\n", support->ViewportSizeSupport);
227 if (!fail_only || support->LinkRateDoesNotMatchDPVersion == 1)
228 DML_LOG_VERBOSE("DML: support: LinkRateDoesNotMatchDPVersion = %d\n", support->LinkRateDoesNotMatchDPVersion);
229 if (!fail_only || support->LinkRateForMultistreamNotIndicated == 1)
230 DML_LOG_VERBOSE("DML: support: LinkRateForMultistreamNotIndicated = %d\n", support->LinkRateForMultistreamNotIndicated);
231 if (!fail_only || support->BPPForMultistreamNotIndicated == 1)
232 DML_LOG_VERBOSE("DML: support: BPPForMultistreamNotIndicated = %d\n", support->BPPForMultistreamNotIndicated);
233 if (!fail_only || support->MultistreamWithHDMIOreDP == 1)
234 DML_LOG_VERBOSE("DML: support: MultistreamWithHDMIOreDP = %d\n", support->MultistreamWithHDMIOreDP);
235 if (!fail_only || support->ExceededMultistreamSlots == 1)
236 DML_LOG_VERBOSE("DML: support: ExceededMultistreamSlots = %d\n", support->ExceededMultistreamSlots);
237 if (!fail_only || support->MSOOrODMSplitWithNonDPLink == 1)
238 DML_LOG_VERBOSE("DML: support: MSOOrODMSplitWithNonDPLink = %d\n", support->MSOOrODMSplitWithNonDPLink);
239 if (!fail_only || support->NotEnoughLanesForMSO == 1)
240 DML_LOG_VERBOSE("DML: support: NotEnoughLanesForMSO = %d\n", support->NotEnoughLanesForMSO);
241 if (!fail_only || support->P2IWith420 == 1)
242 DML_LOG_VERBOSE("DML: support: P2IWith420 = %d\n", support->P2IWith420);
243 if (!fail_only || support->DSC422NativeNotSupported == 1)
244 DML_LOG_VERBOSE("DML: support: DSC422NativeNotSupported = %d\n", support->DSC422NativeNotSupported);
245 if (!fail_only || support->DSCSlicesODMModeSupported == 0)
246 DML_LOG_VERBOSE("DML: support: DSCSlicesODMModeSupported = %d\n", support->DSCSlicesODMModeSupported);
247 if (!fail_only || support->NotEnoughDSCUnits == 1)
248 DML_LOG_VERBOSE("DML: support: NotEnoughDSCUnits = %d\n", support->NotEnoughDSCUnits);
249 if (!fail_only || support->NotEnoughDSCSlices == 1)
250 DML_LOG_VERBOSE("DML: support: NotEnoughDSCSlices = %d\n", support->NotEnoughDSCSlices);
251 if (!fail_only || support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe == 1)
252 DML_LOG_VERBOSE("DML: support: ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = %d\n", support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe);
253 if (!fail_only || support->InvalidCombinationOfMALLUseForPStateAndStaticScreen == 1)
254 DML_LOG_VERBOSE("DML: support: InvalidCombinationOfMALLUseForPStateAndStaticScreen = %d\n", support->InvalidCombinationOfMALLUseForPStateAndStaticScreen);
255 if (!fail_only || support->DSCCLKRequiredMoreThanSupported == 1)
256 DML_LOG_VERBOSE("DML: support: DSCCLKRequiredMoreThanSupported = %d\n", support->DSCCLKRequiredMoreThanSupported);
257 if (!fail_only || support->PixelsPerLinePerDSCUnitSupport == 0)
258 DML_LOG_VERBOSE("DML: support: PixelsPerLinePerDSCUnitSupport = %d\n", support->PixelsPerLinePerDSCUnitSupport);
259 if (!fail_only || support->DTBCLKRequiredMoreThanSupported == 1)
260 DML_LOG_VERBOSE("DML: support: DTBCLKRequiredMoreThanSupported = %d\n", support->DTBCLKRequiredMoreThanSupported);
261 if (!fail_only || support->InvalidCombinationOfMALLUseForPState == 1)
262 DML_LOG_VERBOSE("DML: support: InvalidCombinationOfMALLUseForPState = %d\n", support->InvalidCombinationOfMALLUseForPState);
263 if (!fail_only || support->ROBSupport == 0)
264 DML_LOG_VERBOSE("DML: support: ROBSupport = %d\n", support->ROBSupport);
265 if (!fail_only || support->OutstandingRequestsSupport == 0)
266 DML_LOG_VERBOSE("DML: support: OutstandingRequestsSupport = %d\n", support->OutstandingRequestsSupport);
267 if (!fail_only || support->OutstandingRequestsUrgencyAvoidance == 0)
268 DML_LOG_VERBOSE("DML: support: OutstandingRequestsUrgencyAvoidance = %d\n", support->OutstandingRequestsUrgencyAvoidance);
269 if (!fail_only || support->DISPCLK_DPPCLK_Support == 0)
270 DML_LOG_VERBOSE("DML: support: DISPCLK_DPPCLK_Support = %d\n", support->DISPCLK_DPPCLK_Support);
271 if (!fail_only || support->TotalAvailablePipesSupport == 0)
272 DML_LOG_VERBOSE("DML: support: TotalAvailablePipesSupport = %d\n", support->TotalAvailablePipesSupport);
273 if (!fail_only || support->NumberOfOTGSupport == 0)
274 DML_LOG_VERBOSE("DML: support: NumberOfOTGSupport = %d\n", support->NumberOfOTGSupport);
275 if (!fail_only || support->NumberOfHDMIFRLSupport == 0)
276 DML_LOG_VERBOSE("DML: support: NumberOfHDMIFRLSupport = %d\n", support->NumberOfHDMIFRLSupport);
277 if (!fail_only || support->NumberOfDP2p0Support == 0)
278 DML_LOG_VERBOSE("DML: support: NumberOfDP2p0Support = %d\n", support->NumberOfDP2p0Support);
279 if (!fail_only || support->EnoughWritebackUnits == 0)
280 DML_LOG_VERBOSE("DML: support: EnoughWritebackUnits = %d\n", support->EnoughWritebackUnits);
281 if (!fail_only || support->WritebackScaleRatioAndTapsSupport == 0)
282 DML_LOG_VERBOSE("DML: support: WritebackScaleRatioAndTapsSupport = %d\n", support->WritebackScaleRatioAndTapsSupport);
283 if (!fail_only || support->WritebackLatencySupport == 0)
284 DML_LOG_VERBOSE("DML: support: WritebackLatencySupport = %d\n", support->WritebackLatencySupport);
285 if (!fail_only || support->CursorSupport == 0)
286 DML_LOG_VERBOSE("DML: support: CursorSupport = %d\n", support->CursorSupport);
287 if (!fail_only || support->PitchSupport == 0)
288 DML_LOG_VERBOSE("DML: support: PitchSupport = %d\n", support->PitchSupport);
289 if (!fail_only || support->ViewportExceedsSurface == 1)
290 DML_LOG_VERBOSE("DML: support: ViewportExceedsSurface = %d\n", support->ViewportExceedsSurface);
291 if (!fail_only || support->PrefetchSupported == 0)
292 DML_LOG_VERBOSE("DML: support: PrefetchSupported = %d\n", support->PrefetchSupported);
293 if (!fail_only || support->EnoughUrgentLatencyHidingSupport == 0)
294 DML_LOG_VERBOSE("DML: support: EnoughUrgentLatencyHidingSupport = %d\n", support->EnoughUrgentLatencyHidingSupport);
295 if (!fail_only || support->AvgBandwidthSupport == 0)
296 DML_LOG_VERBOSE("DML: support: AvgBandwidthSupport = %d\n", support->AvgBandwidthSupport);
297 if (!fail_only || support->DynamicMetadataSupported == 0)
298 DML_LOG_VERBOSE("DML: support: DynamicMetadataSupported = %d\n", support->DynamicMetadataSupported);
299 if (!fail_only || support->VRatioInPrefetchSupported == 0)
300 DML_LOG_VERBOSE("DML: support: VRatioInPrefetchSupported = %d\n", support->VRatioInPrefetchSupported);
301 if (!fail_only || support->PTEBufferSizeNotExceeded == 0)
302 DML_LOG_VERBOSE("DML: support: PTEBufferSizeNotExceeded = %d\n", support->PTEBufferSizeNotExceeded);
303 if (!fail_only || support->DCCMetaBufferSizeNotExceeded == 0)
304 DML_LOG_VERBOSE("DML: support: DCCMetaBufferSizeNotExceeded = %d\n", support->DCCMetaBufferSizeNotExceeded);
305 if (!fail_only || support->ExceededMALLSize == 1)
306 DML_LOG_VERBOSE("DML: support: ExceededMALLSize = %d\n", support->ExceededMALLSize);
307 if (!fail_only || support->g6_temp_read_support == 0)
308 DML_LOG_VERBOSE("DML: support: g6_temp_read_support = %d\n", support->g6_temp_read_support);
309 if (!fail_only || (support->global_dram_clock_change_supported == 0 && support->global_dram_clock_change_support_required))
310 DML_LOG_VERBOSE("DML: support: dram_clock_change_support = %d\n", support->global_dram_clock_change_supported);
311 if (!fail_only || support->ImmediateFlipSupport == 0)
312 DML_LOG_VERBOSE("DML: support: ImmediateFlipSupport = %d\n", support->ImmediateFlipSupport);
313 if (!fail_only || support->LinkCapacitySupport == 0)
314 DML_LOG_VERBOSE("DML: support: LinkCapacitySupport = %d\n", support->LinkCapacitySupport);
315
316 if (!fail_only || support->ModeSupport == 0)
317 DML_LOG_VERBOSE("DML: support: ModeSupport = %d\n", support->ModeSupport);
318 DML_LOG_VERBOSE("DML: ===================================== \n");
319 }
320
dml2_core_utils_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type)321 const char *dml2_core_utils_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type)
322 {
323 switch (dml2_core_internal_soc_state_type) {
324 case (dml2_core_internal_soc_state_sys_idle):
325 return("dml2_core_internal_soc_state_sys_idle");
326 case (dml2_core_internal_soc_state_sys_active):
327 return("dml2_core_internal_soc_state_sys_active");
328 case (dml2_core_internal_soc_state_svp_prefetch):
329 return("dml2_core_internal_soc_state_svp_prefetch");
330 case dml2_core_internal_soc_state_max:
331 default:
332 return("dml2_core_internal_soc_state_unknown");
333 }
334 }
335
336
dml2_core_utils_get_stream_output_bpp(double * out_bpp,const struct dml2_display_cfg * display_cfg)337 void dml2_core_utils_get_stream_output_bpp(double *out_bpp, const struct dml2_display_cfg *display_cfg)
338 {
339 for (unsigned int k = 0; k < display_cfg->num_planes; k++) {
340 double bpc = (double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.bpc;
341 if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_disable) {
342 switch (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format) {
343 case dml2_444:
344 out_bpp[k] = bpc * 3;
345 break;
346 case dml2_s422:
347 out_bpp[k] = bpc * 2;
348 break;
349 case dml2_n422:
350 out_bpp[k] = bpc * 2;
351 break;
352 case dml2_420:
353 default:
354 out_bpp[k] = bpc * 1.5;
355 break;
356 }
357 } else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_enable) {
358 out_bpp[k] = (double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.dsc_compressed_bpp_x16 / 16;
359 } else {
360 out_bpp[k] = 0;
361 }
362 #ifdef __DML_VBA_DEBUG__
363 DML_LOG_VERBOSE("DML::%s: k=%d bpc=%f\n", __func__, k, bpc);
364 DML_LOG_VERBOSE("DML::%s: k=%d dsc.enable=%d\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable);
365 DML_LOG_VERBOSE("DML::%s: k=%d out_bpp=%f\n", __func__, k, out_bpp[k]);
366 #endif
367 }
368 }
369
dml2_core_utils_round_to_multiple(unsigned int num,unsigned int multiple,bool up)370 unsigned int dml2_core_utils_round_to_multiple(unsigned int num, unsigned int multiple, bool up)
371 {
372 unsigned int remainder;
373
374 if (multiple == 0)
375 return num;
376
377 remainder = num % multiple;
378 if (remainder == 0)
379 return num;
380
381 if (up)
382 return (num + multiple - remainder);
383 else
384 return (num - remainder);
385 }
386
dml2_core_util_get_num_active_pipes(int unsigned num_planes,const struct core_display_cfg_support_info * cfg_support_info)387 unsigned int dml2_core_util_get_num_active_pipes(int unsigned num_planes, const struct core_display_cfg_support_info *cfg_support_info)
388 {
389 unsigned int num_active_pipes = 0;
390
391 for (unsigned int k = 0; k < num_planes; k++) {
392 num_active_pipes = num_active_pipes + (unsigned int)cfg_support_info->plane_support_info[k].dpps_used;
393 }
394
395 #ifdef __DML_VBA_DEBUG__
396 DML_LOG_VERBOSE("DML::%s: num_active_pipes = %d\n", __func__, num_active_pipes);
397 #endif
398 return num_active_pipes;
399 }
400
dml2_core_utils_pipe_plane_mapping(const struct core_display_cfg_support_info * cfg_support_info,unsigned int * pipe_plane)401 void dml2_core_utils_pipe_plane_mapping(const struct core_display_cfg_support_info *cfg_support_info, unsigned int *pipe_plane)
402 {
403 unsigned int pipe_idx = 0;
404
405 for (unsigned int k = 0; k < DML2_MAX_PLANES; ++k) {
406 pipe_plane[k] = __DML2_CALCS_PIPE_NO_PLANE__;
407 }
408
409 for (unsigned int plane_idx = 0; plane_idx < DML2_MAX_PLANES; plane_idx++) {
410 for (int i = 0; i < cfg_support_info->plane_support_info[plane_idx].dpps_used; i++) {
411 pipe_plane[pipe_idx] = plane_idx;
412 pipe_idx++;
413 }
414 }
415 }
416
dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters * plane_cfg)417 bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg)
418 {
419 bool is_phantom = false;
420
421 if (plane_cfg->overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe ||
422 plane_cfg->overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe_no_data_return) {
423 is_phantom = true;
424 }
425
426 return is_phantom;
427 }
428
dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode,unsigned int byte_per_pixel)429 unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
430 {
431 if (sw_mode == dml2_sw_linear)
432 return 256;
433 else if (sw_mode == dml2_sw_256b_2d)
434 return 256;
435 else if (sw_mode == dml2_sw_4kb_2d)
436 return 4096;
437 else if (sw_mode == dml2_sw_64kb_2d)
438 return 65536;
439 else if (sw_mode == dml2_sw_256kb_2d)
440 return 262144;
441 else if (sw_mode == dml2_gfx11_sw_linear)
442 return 256;
443 else if (sw_mode == dml2_gfx11_sw_64kb_d)
444 return 65536;
445 else if (sw_mode == dml2_gfx11_sw_64kb_d_t)
446 return 65536;
447 else if (sw_mode == dml2_gfx11_sw_64kb_d_x)
448 return 65536;
449 else if (sw_mode == dml2_gfx11_sw_64kb_r_x)
450 return 65536;
451 else if (sw_mode == dml2_gfx11_sw_256kb_d_x)
452 return 262144;
453 else if (sw_mode == dml2_gfx11_sw_256kb_r_x)
454 return 262144;
455 else {
456 DML_ASSERT(0);
457 return 256;
458 };
459 }
460
dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode,unsigned int byte_per_pixel)461 bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
462 {
463 return (byte_per_pixel != 2);
464 }
465
dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode)466 bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode)
467 {
468 return sw_mode == dml2_sw_linear;
469 };
470
471
dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan)472 bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan)
473 {
474 bool is_vert = false;
475 if (Scan == dml2_rotation_90 || Scan == dml2_rotation_270) {
476 is_vert = true;
477 } else {
478 is_vert = false;
479 }
480 return is_vert;
481 }
482
dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode)483 int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode)
484 {
485 int unsigned version = 0;
486
487 if (sw_mode == dml2_sw_linear ||
488 sw_mode == dml2_sw_256b_2d ||
489 sw_mode == dml2_sw_4kb_2d ||
490 sw_mode == dml2_sw_64kb_2d ||
491 sw_mode == dml2_sw_256kb_2d)
492 version = 12;
493 else if (sw_mode == dml2_gfx11_sw_linear ||
494 sw_mode == dml2_gfx11_sw_64kb_d ||
495 sw_mode == dml2_gfx11_sw_64kb_d_t ||
496 sw_mode == dml2_gfx11_sw_64kb_d_x ||
497 sw_mode == dml2_gfx11_sw_64kb_r_x ||
498 sw_mode == dml2_gfx11_sw_256kb_d_x ||
499 sw_mode == dml2_gfx11_sw_256kb_r_x)
500 version = 11;
501 else {
502 DML_LOG_VERBOSE("ERROR: Invalid sw_mode setting! val=%u\n", sw_mode);
503 DML_ASSERT(0);
504 }
505
506 return version;
507 }
508
dml2_core_utils_get_qos_param_index(unsigned long uclk_freq_khz,const struct dml2_dcn4_uclk_dpm_dependent_qos_params * per_uclk_dpm_params)509 unsigned int dml2_core_utils_get_qos_param_index(unsigned long uclk_freq_khz, const struct dml2_dcn4_uclk_dpm_dependent_qos_params *per_uclk_dpm_params)
510 {
511 unsigned int i;
512 unsigned int index = 0;
513
514 for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) {
515 DML_LOG_VERBOSE("DML::%s: per_uclk_dpm_params[%d].minimum_uclk_khz = %ld\n", __func__, i, per_uclk_dpm_params[i].minimum_uclk_khz);
516
517 if (i == 0)
518 index = 0;
519 else
520 index = i - 1;
521
522 if (uclk_freq_khz < per_uclk_dpm_params[i].minimum_uclk_khz ||
523 per_uclk_dpm_params[i].minimum_uclk_khz == 0) {
524 break;
525 }
526 }
527 #if defined(__DML_VBA_DEBUG__)
528 DML_LOG_VERBOSE("DML::%s: uclk_freq_khz = %ld\n", __func__, uclk_freq_khz);
529 DML_LOG_VERBOSE("DML::%s: index = %d\n", __func__, index);
530 #endif
531 return index;
532 }
533
dml2_core_utils_get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz,const struct dml2_soc_state_table * clk_table)534 unsigned int dml2_core_utils_get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz, const struct dml2_soc_state_table *clk_table)
535 {
536 unsigned int i;
537 bool clk_entry_found = false;
538
539 for (i = 0; i < clk_table->uclk.num_clk_values; i++) {
540 DML_LOG_VERBOSE("DML::%s: clk_table.uclk.clk_values_khz[%d] = %ld\n", __func__, i, clk_table->uclk.clk_values_khz[i]);
541
542 if (uclk_freq_khz == clk_table->uclk.clk_values_khz[i]) {
543 clk_entry_found = true;
544 break;
545 }
546 }
547
548 if (!clk_entry_found)
549 DML_ASSERT(clk_entry_found);
550 #if defined(__DML_VBA_DEBUG__)
551 DML_LOG_VERBOSE("DML::%s: uclk_freq_khz = %ld\n", __func__, uclk_freq_khz);
552 DML_LOG_VERBOSE("DML::%s: index = %d\n", __func__, i);
553 #endif
554 return i;
555 }
556
dml2_core_utils_is_dual_plane(enum dml2_source_format_class source_format)557 bool dml2_core_utils_is_dual_plane(enum dml2_source_format_class source_format)
558 {
559 bool ret_val = false;
560
561 if (dml2_core_utils_is_420(source_format) || dml2_core_utils_is_422_planar(source_format) || (source_format == dml2_rgbe_alpha))
562 ret_val = true;
563
564 return ret_val;
565 }
566
dml2_core_utils_log_and_substract_if_non_zero(unsigned int a,unsigned int subtrahend)567 unsigned int dml2_core_utils_log_and_substract_if_non_zero(unsigned int a, unsigned int subtrahend)
568 {
569 if (a == 0)
570 return 0;
571
572 return (math_log2_approx(a) - subtrahend);
573 }
574
create_phantom_stream_from_main_stream(struct dml2_stream_parameters * phantom,const struct dml2_stream_parameters * main,const struct dml2_implicit_svp_meta * meta)575 static void create_phantom_stream_from_main_stream(struct dml2_stream_parameters *phantom, const struct dml2_stream_parameters *main,
576 const struct dml2_implicit_svp_meta *meta)
577 {
578 memcpy(phantom, main, sizeof(struct dml2_stream_parameters));
579
580 phantom->timing.v_total = meta->v_total;
581 phantom->timing.v_active = meta->v_active;
582 phantom->timing.v_front_porch = meta->v_front_porch;
583 phantom->timing.v_blank_end = phantom->timing.v_total - phantom->timing.v_front_porch - phantom->timing.v_active;
584 phantom->timing.vblank_nom = phantom->timing.v_total - phantom->timing.v_active;
585 phantom->timing.drr_config.enabled = false;
586 }
587
create_phantom_plane_from_main_plane(struct dml2_plane_parameters * phantom,const struct dml2_plane_parameters * main,const struct dml2_stream_parameters * phantom_stream,int phantom_stream_index,const struct dml2_stream_parameters * main_stream)588 static void create_phantom_plane_from_main_plane(struct dml2_plane_parameters *phantom, const struct dml2_plane_parameters *main,
589 const struct dml2_stream_parameters *phantom_stream, int phantom_stream_index, const struct dml2_stream_parameters *main_stream)
590 {
591 (void)main_stream;
592 memcpy(phantom, main, sizeof(struct dml2_plane_parameters));
593
594 phantom->stream_index = phantom_stream_index;
595 phantom->overrides.refresh_from_mall = dml2_refresh_from_mall_mode_override_force_disable;
596 phantom->overrides.legacy_svp_config = dml2_svp_mode_override_phantom_pipe_no_data_return;
597 phantom->composition.viewport.plane0.height = (long int unsigned) math_min2(math_ceil2(
598 (double)main->composition.scaler_info.plane0.v_ratio * (double)phantom_stream->timing.v_active, 16.0),
599 (double)main->composition.viewport.plane0.height);
600 phantom->composition.viewport.plane1.height = (long int unsigned) math_min2(math_ceil2(
601 (double)main->composition.scaler_info.plane1.v_ratio * (double)phantom_stream->timing.v_active, 16.0),
602 (double)main->composition.viewport.plane1.height);
603 phantom->immediate_flip = false;
604 phantom->dynamic_meta_data.enable = false;
605 phantom->cursor.num_cursors = 0;
606 phantom->cursor.cursor_width = 0;
607 phantom->tdlut.setup_for_tdlut = false;
608 }
609
dml2_core_utils_expand_implict_subvp(const struct display_configuation_with_meta * display_cfg,struct dml2_display_cfg * svp_expanded_display_cfg,struct dml2_core_scratch * scratch)610 void dml2_core_utils_expand_implict_subvp(const struct display_configuation_with_meta *display_cfg, struct dml2_display_cfg *svp_expanded_display_cfg,
611 struct dml2_core_scratch *scratch)
612 {
613 unsigned int stream_index, plane_index;
614 const struct dml2_plane_parameters *main_plane;
615 const struct dml2_stream_parameters *main_stream;
616 const struct dml2_stream_parameters *phantom_stream;
617
618 memcpy(svp_expanded_display_cfg, &display_cfg->display_config, sizeof(struct dml2_display_cfg));
619 memset(scratch->main_stream_index_from_svp_stream_index, 0, sizeof(int) * DML2_MAX_PLANES);
620 memset(scratch->svp_stream_index_from_main_stream_index, 0, sizeof(int) * DML2_MAX_PLANES);
621 memset(scratch->main_plane_index_to_phantom_plane_index, 0, sizeof(int) * DML2_MAX_PLANES);
622
623 if (!display_cfg->display_config.overrides.enable_subvp_implicit_pmo)
624 return;
625
626 /* disable unbounded requesting for all planes until stage 3 has been performed */
627 if (!display_cfg->stage3.performed) {
628 svp_expanded_display_cfg->overrides.hw.force_unbounded_requesting.enable = true;
629 svp_expanded_display_cfg->overrides.hw.force_unbounded_requesting.value = false;
630 }
631 // Create the phantom streams
632 for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
633 main_stream = &display_cfg->display_config.stream_descriptors[stream_index];
634 scratch->main_stream_index_from_svp_stream_index[stream_index] = stream_index;
635 scratch->svp_stream_index_from_main_stream_index[stream_index] = stream_index;
636
637 if (display_cfg->stage3.stream_svp_meta[stream_index].valid) {
638 // Create the phantom stream
639 create_phantom_stream_from_main_stream(&svp_expanded_display_cfg->stream_descriptors[svp_expanded_display_cfg->num_streams],
640 main_stream, &display_cfg->stage3.stream_svp_meta[stream_index]);
641
642 // Associate this phantom stream to the main stream
643 scratch->main_stream_index_from_svp_stream_index[svp_expanded_display_cfg->num_streams] = stream_index;
644 scratch->svp_stream_index_from_main_stream_index[stream_index] = svp_expanded_display_cfg->num_streams;
645
646 // Increment num streams
647 svp_expanded_display_cfg->num_streams++;
648 }
649 }
650
651 // Create the phantom planes
652 for (plane_index = 0; plane_index < display_cfg->display_config.num_planes; plane_index++) {
653 main_plane = &display_cfg->display_config.plane_descriptors[plane_index];
654
655 if (display_cfg->stage3.stream_svp_meta[main_plane->stream_index].valid) {
656 main_stream = &display_cfg->display_config.stream_descriptors[main_plane->stream_index];
657 phantom_stream = &svp_expanded_display_cfg->stream_descriptors[scratch->svp_stream_index_from_main_stream_index[main_plane->stream_index]];
658 create_phantom_plane_from_main_plane(&svp_expanded_display_cfg->plane_descriptors[svp_expanded_display_cfg->num_planes],
659 main_plane, phantom_stream, scratch->svp_stream_index_from_main_stream_index[main_plane->stream_index], main_stream);
660
661 // Associate this phantom plane to the main plane
662 scratch->phantom_plane_index_to_main_plane_index[svp_expanded_display_cfg->num_planes] = plane_index;
663 scratch->main_plane_index_to_phantom_plane_index[plane_index] = svp_expanded_display_cfg->num_planes;
664
665 // Increment num planes
666 svp_expanded_display_cfg->num_planes++;
667
668 // Adjust the main plane settings
669 svp_expanded_display_cfg->plane_descriptors[plane_index].overrides.legacy_svp_config = dml2_svp_mode_override_main_pipe;
670 }
671 }
672 }
673
dml2_core_utils_is_stream_encoder_required(const struct dml2_stream_parameters * stream_descriptor)674 bool dml2_core_utils_is_stream_encoder_required(const struct dml2_stream_parameters *stream_descriptor)
675 {
676 switch (stream_descriptor->output.output_encoder) {
677 case dml2_dp:
678 case dml2_dp2p0:
679 case dml2_edp:
680 case dml2_hdmi:
681 case dml2_hdmifrl:
682 return true;
683 case dml2_none:
684 default:
685 return false;
686 }
687 }
dml2_core_utils_is_encoder_dsc_capable(const struct dml2_stream_parameters * stream_descriptor)688 bool dml2_core_utils_is_encoder_dsc_capable(const struct dml2_stream_parameters *stream_descriptor)
689 {
690 switch (stream_descriptor->output.output_encoder) {
691 case dml2_dp:
692 case dml2_dp2p0:
693 case dml2_edp:
694 case dml2_hdmifrl:
695 return true;
696 case dml2_hdmi:
697 case dml2_none:
698 default:
699 return false;
700 }
701 }
702
703
dml2_core_utils_is_dio_dp_encoder(const struct dml2_stream_parameters * stream_descriptor)704 bool dml2_core_utils_is_dio_dp_encoder(const struct dml2_stream_parameters *stream_descriptor)
705 {
706 switch (stream_descriptor->output.output_encoder) {
707 case dml2_dp:
708 case dml2_edp:
709 return true;
710 case dml2_dp2p0:
711 case dml2_hdmi:
712 case dml2_hdmifrl:
713 case dml2_none:
714 default:
715 return false;
716 }
717 }
718
dml2_core_utils_is_hpo_dp_encoder(const struct dml2_stream_parameters * stream_descriptor)719 bool dml2_core_utils_is_hpo_dp_encoder(const struct dml2_stream_parameters *stream_descriptor)
720 {
721 switch (stream_descriptor->output.output_encoder) {
722 case dml2_dp2p0:
723 return true;
724 case dml2_dp:
725 case dml2_edp:
726 case dml2_hdmi:
727 case dml2_hdmifrl:
728 case dml2_none:
729 default:
730 return false;
731 }
732 }
733
dml2_core_utils_is_dp_encoder(const struct dml2_stream_parameters * stream_descriptor)734 bool dml2_core_utils_is_dp_encoder(const struct dml2_stream_parameters *stream_descriptor)
735 {
736 return dml2_core_utils_is_dio_dp_encoder(stream_descriptor)
737 || dml2_core_utils_is_hpo_dp_encoder(stream_descriptor);
738 }
739
740
dml2_core_utils_is_dp_8b_10b_link_rate(enum dml2_output_link_dp_rate rate)741 bool dml2_core_utils_is_dp_8b_10b_link_rate(enum dml2_output_link_dp_rate rate)
742 {
743 switch (rate) {
744 case dml2_dp_rate_hbr:
745 case dml2_dp_rate_hbr2:
746 case dml2_dp_rate_hbr3:
747 return true;
748 case dml2_dp_rate_na:
749 case dml2_dp_rate_uhbr10:
750 case dml2_dp_rate_uhbr13p5:
751 case dml2_dp_rate_uhbr20:
752 default:
753 return false;
754 }
755 }
756
dml2_core_utils_is_dp_128b_132b_link_rate(enum dml2_output_link_dp_rate rate)757 bool dml2_core_utils_is_dp_128b_132b_link_rate(enum dml2_output_link_dp_rate rate)
758 {
759 switch (rate) {
760 case dml2_dp_rate_uhbr10:
761 case dml2_dp_rate_uhbr13p5:
762 case dml2_dp_rate_uhbr20:
763 return true;
764 case dml2_dp_rate_hbr:
765 case dml2_dp_rate_hbr2:
766 case dml2_dp_rate_hbr3:
767 case dml2_dp_rate_na:
768 default:
769 return false;
770 }
771 }
772
dml2_core_utils_is_odm_split(enum dml2_odm_mode odm_mode)773 bool dml2_core_utils_is_odm_split(enum dml2_odm_mode odm_mode)
774 {
775 switch (odm_mode) {
776 case dml2_odm_mode_split_1to2:
777 case dml2_odm_mode_mso_1to2:
778 case dml2_odm_mode_mso_1to4:
779 return true;
780 case dml2_odm_mode_auto:
781 case dml2_odm_mode_bypass:
782 case dml2_odm_mode_combine_2to1:
783 case dml2_odm_mode_combine_3to1:
784 case dml2_odm_mode_combine_4to1:
785 default:
786 return false;
787 }
788 }
789
dml2_core_utils_get_frame_time_us(const struct dml2_stream_parameters * stream)790 double dml2_core_utils_get_frame_time_us(const struct dml2_stream_parameters *stream)
791 {
792 double otg_vline_time_us = (double)stream->timing.h_total / (double)stream->timing.pixel_clock_khz * 1000.0;
793 double non_vtotal = stream->timing.vblank_nom + stream->timing.v_active;
794 double frame_time_us = non_vtotal * otg_vline_time_us;
795 return frame_time_us;
796 }
797