xref: /linux/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c (revision 92c4c9fdc838d3b41a996bb700ea64b9e78fc7ea)
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