1 /*
2  * Copyright 2017 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 
27 #include "display_mode_lib.h"
28 #include "display_mode_vba.h"
29 #include "dml_inline_defs.h"
30 
31 /*
32  * NOTE:
33  *   This file is gcc-parsable HW gospel, coming straight from HW engineers.
34  *
35  * It doesn't adhere to Linux kernel style and sometimes will do things in odd
36  * ways. Unless there is something clearly wrong with it the code should
37  * remain as-is as it provides us with a guarantee from HW that it is correct.
38  */
39 
40 
41 static void fetch_socbb_params(struct display_mode_lib *mode_lib);
42 static void fetch_ip_params(struct display_mode_lib *mode_lib);
43 static void fetch_pipe_params(struct display_mode_lib *mode_lib);
44 static void recalculate_params(
45 		struct display_mode_lib *mode_lib,
46 		const display_e2e_pipe_params_st *pipes,
47 		unsigned int num_pipes);
48 
49 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
50 static void cache_debug_params(struct display_mode_lib *mode_lib);
51 
52 unsigned int dml_get_voltage_level(
53 		struct display_mode_lib *mode_lib,
54 		const display_e2e_pipe_params_st *pipes,
55 		unsigned int num_pipes)
56 {
57 	bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
58 			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
59 			|| num_pipes != mode_lib->vba.cache_num_pipes
60 			|| memcmp(pipes, mode_lib->vba.cache_pipes,
61 					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
62 
63 	mode_lib->vba.soc = mode_lib->soc;
64 	mode_lib->vba.ip = mode_lib->ip;
65 	memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
66 	mode_lib->vba.cache_num_pipes = num_pipes;
67 
68 	if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
69 		mode_lib->funcs.recalculate(mode_lib);
70 	else {
71 		fetch_socbb_params(mode_lib);
72 		fetch_ip_params(mode_lib);
73 		fetch_pipe_params(mode_lib);
74 		PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
75 	}
76 	mode_lib->funcs.validate(mode_lib);
77 	cache_debug_params(mode_lib);
78 
79 	return mode_lib->vba.VoltageLevel;
80 }
81 
82 #define dml_get_attr_func(attr, var)  double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \
83 { \
84 	recalculate_params(mode_lib, pipes, num_pipes); \
85 	return var; \
86 }
87 
88 dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFCLKDeepSleep);
89 dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
90 dml_get_attr_func(wm_memory_trip, mode_lib->vba.UrgentLatency);
91 dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
92 dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
93 dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
94 dml_get_attr_func(wm_z8_stutter_exit, mode_lib->vba.Z8StutterExitWatermark);
95 dml_get_attr_func(wm_z8_stutter_enter_exit, mode_lib->vba.Z8StutterEnterPlusExitWatermark);
96 dml_get_attr_func(stutter_efficiency_z8, mode_lib->vba.Z8StutterEfficiency);
97 dml_get_attr_func(stutter_num_bursts_z8, mode_lib->vba.Z8NumberOfStutterBurstsPerFrame);
98 dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
99 dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
100 dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
101 dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
102 dml_get_attr_func(stutter_period, mode_lib->vba.StutterPeriod);
103 dml_get_attr_func(urgent_latency, mode_lib->vba.UrgentLatency);
104 dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
105 dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
106 dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
107 dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
108 dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
109 dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
110 dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
111 dml_get_attr_func(fraction_of_urgent_bandwidth, mode_lib->vba.FractionOfUrgentBandwidth);
112 dml_get_attr_func(fraction_of_urgent_bandwidth_imm_flip, mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip);
113 
114 
115 dml_get_attr_func(cstate_max_cap_mode, mode_lib->vba.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE);
116 dml_get_attr_func(comp_buffer_size_kbytes, mode_lib->vba.CompressedBufferSizeInkByte);
117 dml_get_attr_func(pixel_chunk_size_in_kbyte, mode_lib->vba.PixelChunkSizeInKByte);
118 dml_get_attr_func(alpha_pixel_chunk_size_in_kbyte, mode_lib->vba.AlphaPixelChunkSizeInKByte);
119 dml_get_attr_func(meta_chunk_size_in_kbyte, mode_lib->vba.MetaChunkSize);
120 dml_get_attr_func(min_pixel_chunk_size_in_byte, mode_lib->vba.MinPixelChunkSizeBytes);
121 dml_get_attr_func(min_meta_chunk_size_in_byte, mode_lib->vba.MinMetaChunkSizeBytes);
122 dml_get_attr_func(fclk_watermark, mode_lib->vba.Watermark.FCLKChangeWatermark);
123 dml_get_attr_func(usr_retraining_watermark, mode_lib->vba.Watermark.USRRetrainingWatermark);
124 
125 dml_get_attr_func(comp_buffer_reserved_space_kbytes, mode_lib->vba.CompBufReservedSpaceKBytes);
126 dml_get_attr_func(comp_buffer_reserved_space_64bytes, mode_lib->vba.CompBufReservedSpace64B);
127 dml_get_attr_func(comp_buffer_reserved_space_zs, mode_lib->vba.CompBufReservedSpaceZs);
128 dml_get_attr_func(unbounded_request_enabled, mode_lib->vba.UnboundedRequestEnabled);
129 
130 #define dml_get_pipe_attr_func(attr, var)  double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) \
131 {\
132 	unsigned int which_plane; \
133 	recalculate_params(mode_lib, pipes, num_pipes); \
134 	which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
135 	return var[which_plane]; \
136 }
137 
138 dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
139 dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
140 dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
141 dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
142 dml_get_pipe_attr_func(min_ttu_vblank_in_us, mode_lib->vba.MinTTUVBlank);
143 dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
144 dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
145 dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
146 dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
147 dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
148 dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
149 dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
150 dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
151 dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
152 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank, mode_lib->vba.TimePerVMGroupVBlank);
153 dml_get_pipe_attr_func(refcyc_per_vm_group_flip, mode_lib->vba.TimePerVMGroupFlip);
154 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank, mode_lib->vba.TimePerVMRequestVBlank);
155 dml_get_pipe_attr_func(refcyc_per_vm_req_flip, mode_lib->vba.TimePerVMRequestFlip);
156 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank_in_us, mode_lib->vba.TimePerVMGroupVBlank);
157 dml_get_pipe_attr_func(refcyc_per_vm_group_flip_in_us, mode_lib->vba.TimePerVMGroupFlip);
158 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank_in_us, mode_lib->vba.TimePerVMRequestVBlank);
159 dml_get_pipe_attr_func(refcyc_per_vm_req_flip_in_us, mode_lib->vba.TimePerVMRequestFlip);
160 dml_get_pipe_attr_func(refcyc_per_vm_dmdata_in_us, mode_lib->vba.Tdmdl_vm);
161 dml_get_pipe_attr_func(dmdata_dl_delta_in_us, mode_lib->vba.Tdmdl);
162 dml_get_pipe_attr_func(refcyc_per_line_delivery_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLuma);
163 dml_get_pipe_attr_func(refcyc_per_line_delivery_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChroma);
164 dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch);
165 dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch);
166 dml_get_pipe_attr_func(refcyc_per_req_delivery_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLuma);
167 dml_get_pipe_attr_func(refcyc_per_req_delivery_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChroma);
168 dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLumaPrefetch);
169 dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChromaPrefetch);
170 dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_in_us, mode_lib->vba.CursorRequestDeliveryTime);
171 dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_pre_in_us, mode_lib->vba.CursorRequestDeliveryTimePrefetch);
172 dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_l_in_us, mode_lib->vba.TimePerMetaChunkNominal);
173 dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_c_in_us, mode_lib->vba.TimePerChromaMetaChunkNominal);
174 dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_l_in_us, mode_lib->vba.TimePerMetaChunkVBlank);
175 dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_c_in_us, mode_lib->vba.TimePerChromaMetaChunkVBlank);
176 dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_l_in_us, mode_lib->vba.TimePerMetaChunkFlip);
177 dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_c_in_us, mode_lib->vba.TimePerChromaMetaChunkFlip);
178 dml_get_pipe_attr_func(vstartup, mode_lib->vba.VStartup);
179 dml_get_pipe_attr_func(vupdate_offset, mode_lib->vba.VUpdateOffsetPix);
180 dml_get_pipe_attr_func(vupdate_width, mode_lib->vba.VUpdateWidthPix);
181 dml_get_pipe_attr_func(vready_offset, mode_lib->vba.VReadyOffsetPix);
182 dml_get_pipe_attr_func(vready_at_or_after_vsync, mode_lib->vba.VREADY_AT_OR_AFTER_VSYNC);
183 dml_get_pipe_attr_func(min_dst_y_next_start, mode_lib->vba.MIN_DST_Y_NEXT_START);
184 dml_get_pipe_attr_func(dst_y_per_pte_row_nom_l, mode_lib->vba.DST_Y_PER_PTE_ROW_NOM_L);
185 dml_get_pipe_attr_func(dst_y_per_pte_row_nom_c, mode_lib->vba.DST_Y_PER_PTE_ROW_NOM_C);
186 dml_get_pipe_attr_func(dst_y_per_meta_row_nom_l, mode_lib->vba.DST_Y_PER_META_ROW_NOM_L);
187 dml_get_pipe_attr_func(dst_y_per_meta_row_nom_c, mode_lib->vba.DST_Y_PER_META_ROW_NOM_C);
188 dml_get_pipe_attr_func(refcyc_per_pte_group_nom_l_in_us, mode_lib->vba.time_per_pte_group_nom_luma);
189 dml_get_pipe_attr_func(refcyc_per_pte_group_nom_c_in_us, mode_lib->vba.time_per_pte_group_nom_chroma);
190 dml_get_pipe_attr_func(refcyc_per_pte_group_vblank_l_in_us, mode_lib->vba.time_per_pte_group_vblank_luma);
191 dml_get_pipe_attr_func(refcyc_per_pte_group_vblank_c_in_us, mode_lib->vba.time_per_pte_group_vblank_chroma);
192 dml_get_pipe_attr_func(refcyc_per_pte_group_flip_l_in_us, mode_lib->vba.time_per_pte_group_flip_luma);
193 dml_get_pipe_attr_func(refcyc_per_pte_group_flip_c_in_us, mode_lib->vba.time_per_pte_group_flip_chroma);
194 dml_get_pipe_attr_func(vstartup_calculated, mode_lib->vba.VStartup);
195 dml_get_pipe_attr_func(dpte_row_height_linear_c, mode_lib->vba.dpte_row_height_linear_chroma);
196 dml_get_pipe_attr_func(swath_height_l, mode_lib->vba.SwathHeightY);
197 dml_get_pipe_attr_func(swath_height_c, mode_lib->vba.SwathHeightC);
198 dml_get_pipe_attr_func(det_stored_buffer_size_l_bytes, mode_lib->vba.DETBufferSizeY);
199 dml_get_pipe_attr_func(det_stored_buffer_size_c_bytes, mode_lib->vba.DETBufferSizeC);
200 dml_get_pipe_attr_func(dpte_group_size_in_bytes, mode_lib->vba.dpte_group_bytes);
201 dml_get_pipe_attr_func(vm_group_size_in_bytes, mode_lib->vba.vm_group_bytes);
202 dml_get_pipe_attr_func(dpte_row_height_linear_l, mode_lib->vba.dpte_row_height_linear);
203 dml_get_pipe_attr_func(pte_buffer_mode, mode_lib->vba.PTE_BUFFER_MODE);
204 dml_get_pipe_attr_func(subviewport_lines_needed_in_mall, mode_lib->vba.SubViewportLinesNeededInMALL);
205 
206 double get_total_immediate_flip_bytes(
207 		struct display_mode_lib *mode_lib,
208 		const display_e2e_pipe_params_st *pipes,
209 		unsigned int num_pipes)
210 {
211 	recalculate_params(mode_lib, pipes, num_pipes);
212 	return mode_lib->vba.TotImmediateFlipBytes;
213 }
214 
215 double get_total_immediate_flip_bw(
216 		struct display_mode_lib *mode_lib,
217 		const display_e2e_pipe_params_st *pipes,
218 		unsigned int num_pipes)
219 {
220 	unsigned int k;
221 	double immediate_flip_bw = 0.0;
222 	recalculate_params(mode_lib, pipes, num_pipes);
223 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
224 		immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k];
225 	return immediate_flip_bw;
226 }
227 
228 double get_total_prefetch_bw(
229 		struct display_mode_lib *mode_lib,
230 		const display_e2e_pipe_params_st *pipes,
231 		unsigned int num_pipes)
232 {
233 	unsigned int k;
234 	double total_prefetch_bw = 0.0;
235 
236 	recalculate_params(mode_lib, pipes, num_pipes);
237 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
238 		total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
239 	return total_prefetch_bw;
240 }
241 
242 unsigned int get_total_surface_size_in_mall_bytes(
243 		struct display_mode_lib *mode_lib,
244 		const display_e2e_pipe_params_st *pipes,
245 		unsigned int num_pipes)
246 {
247 	unsigned int k;
248 	unsigned int size = 0.0;
249 	recalculate_params(mode_lib, pipes, num_pipes);
250 	for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k)
251 		size += mode_lib->vba.SurfaceSizeInMALL[k];
252 	return size;
253 }
254 
255 static unsigned int get_pipe_idx(struct display_mode_lib *mode_lib, unsigned int plane_idx)
256 {
257 	int pipe_idx = -1;
258 	int i;
259 
260 	ASSERT(plane_idx < DC__NUM_DPP__MAX);
261 
262 	for (i = 0; i < DC__NUM_DPP__MAX ; i++) {
263 		if (plane_idx == mode_lib->vba.pipe_plane[i]) {
264 			pipe_idx = i;
265 			break;
266 		}
267 	}
268 	ASSERT(pipe_idx >= 0);
269 
270 	return pipe_idx;
271 }
272 
273 
274 double get_det_buffer_size_kbytes(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes,
275 		unsigned int num_pipes, unsigned int pipe_idx)
276 {
277 	unsigned int plane_idx;
278 	double det_buf_size_kbytes;
279 
280 	recalculate_params(mode_lib, pipes, num_pipes);
281 	plane_idx = mode_lib->vba.pipe_plane[pipe_idx];
282 
283 	dml_print("DML::%s: num_pipes=%d pipe_idx=%d plane_idx=%0d\n", __func__, num_pipes, pipe_idx, plane_idx);
284 	det_buf_size_kbytes = mode_lib->vba.DETBufferSizeInKByte[plane_idx]; // per hubp DET buffer size
285 
286 	dml_print("DML::%s: det_buf_size_kbytes=%3.2f\n", __func__, det_buf_size_kbytes);
287 
288 	return det_buf_size_kbytes;
289 }
290 
291 bool get_is_phantom_pipe(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes,
292 		unsigned int num_pipes, unsigned int pipe_idx)
293 {
294 	unsigned int plane_idx;
295 
296 	recalculate_params(mode_lib, pipes, num_pipes);
297 	plane_idx = mode_lib->vba.pipe_plane[pipe_idx];
298 	dml_print("DML::%s: num_pipes=%d pipe_idx=%d UseMALLForPStateChange=%0d\n", __func__, num_pipes, pipe_idx,
299 			mode_lib->vba.UsesMALLForPStateChange[plane_idx]);
300 	return (mode_lib->vba.UsesMALLForPStateChange[plane_idx] == dm_use_mall_pstate_change_phantom_pipe);
301 }
302 
303 static void fetch_socbb_params(struct display_mode_lib *mode_lib)
304 {
305 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
306 	int i;
307 
308 	// SOC Bounding Box Parameters
309 	mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
310 	mode_lib->vba.NumberOfChannels = soc->num_chans;
311 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly =
312 			soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only; // there's always that one bastard variable that's so long it throws everything out of alignment!
313 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData =
314 			soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
315 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly =
316 			soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
317 	mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation =
318 			soc->max_avg_sdp_bw_use_normal_percent;
319 	mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation =
320 			soc->max_avg_dram_bw_use_normal_percent;
321 	mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us;
322 	mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us;
323 	mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us;
324 	mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
325 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly =
326 			soc->urgent_out_of_order_return_per_channel_pixel_only_bytes;
327 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData =
328 			soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
329 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly =
330 			soc->urgent_out_of_order_return_per_channel_vm_only_bytes;
331 	mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
332 	mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
333 	mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
334 	mode_lib->vba.PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = soc->pct_ideal_sdp_bw_after_urgent;
335 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
336 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only;
337 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
338 	mode_lib->vba.MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation =
339 			soc->max_avg_sdp_bw_use_normal_percent;
340 	mode_lib->vba.SRExitZ8Time = soc->sr_exit_z8_time_us;
341 	mode_lib->vba.SREnterPlusExitZ8Time = soc->sr_enter_plus_exit_z8_time_us;
342 	mode_lib->vba.FCLKChangeLatency = soc->fclk_change_latency_us;
343 	mode_lib->vba.USRRetrainingLatency = soc->usr_retraining_latency_us;
344 	mode_lib->vba.SMNLatency = soc->smn_latency_us;
345 	mode_lib->vba.MALLAllocatedForDCNFinal = soc->mall_allocated_for_dcn_mbytes;
346 
347 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencySTROBE = soc->pct_ideal_dram_bw_after_urgent_strobe;
348 	mode_lib->vba.MaxAveragePercentOfIdealFabricBWDisplayCanUseInNormalSystemOperation =
349 			soc->max_avg_fabric_bw_use_normal_percent;
350 	mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperationSTROBE =
351 			soc->max_avg_dram_bw_use_normal_strobe_percent;
352 
353 	mode_lib->vba.DRAMClockChangeRequirementFinal = soc->dram_clock_change_requirement_final;
354 	mode_lib->vba.FCLKChangeRequirementFinal = 1;
355 	mode_lib->vba.USRRetrainingRequiredFinal = 1;
356 	mode_lib->vba.AllowForPStateChangeOrStutterInVBlankFinal = soc->allow_for_pstate_or_stutter_in_vblank_final;
357 	mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
358 	mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
359 	mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
360 			mode_lib->vba.DummyPStateCheck;
361 	mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive;
362 	mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank =
363 		soc->allow_dram_self_refresh_or_dram_clock_change_in_vblank;
364 
365 	mode_lib->vba.Downspreading = soc->downspread_percent;
366 	mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes;   // new!
367 	mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
368 	mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent;   // new
369 	mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz;   // new
370 	mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
371 	mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024;
372 	mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024;
373 	// Set the voltage scaling clocks as the defaults. Most of these will
374 	// be set to different values by the test
375 	for (i = 0; i < mode_lib->vba.soc.num_states; i++)
376 		if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
377 			break;
378 
379 	mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
380 	mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
381 	mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts;
382 	mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
383 
384 	mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
385 	mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
386 	mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw;
387 
388 	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
389 	mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
390 	mode_lib->vba.MaxHSCLRatio = 4;
391 	mode_lib->vba.MaxVSCLRatio = 4;
392 	mode_lib->vba.Cursor64BppSupport = true;
393 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
394 		mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
395 		mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
396 		mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
397 		mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
398 		mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz;
399 		mode_lib->vba.PHYCLKD32PerState[i] = soc->clock_limits[i].phyclk_d32_mhz;
400 		mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
401 		mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
402 		mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts;
403 		//mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
404 		mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
405 		mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz;
406 	}
407 
408 	mode_lib->vba.DoUrgentLatencyAdjustment =
409 		soc->do_urgent_latency_adjustment;
410 	mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent =
411 		soc->urgent_latency_adjustment_fabric_clock_component_us;
412 	mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
413 		soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
414 }
415 
416 static void fetch_ip_params(struct display_mode_lib *mode_lib)
417 {
418 	ip_params_st *ip = &mode_lib->vba.ip;
419 
420 	// IP Parameters
421 	mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
422 	mode_lib->vba.ClampMinDCFCLK = ip->clamp_min_dcfclk;
423 	mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
424 	mode_lib->vba.MaxNumOTG = ip->max_num_otg;
425 	mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
426 	mode_lib->vba.MaxNumWriteback = ip->max_num_wb;
427 	mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
428 	mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
429 
430 	mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
431 	mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
432 	mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
433 	mode_lib->vba.DETBufferSizeInKByte[0] = ip->det_buffer_size_kbytes;
434 	mode_lib->vba.ConfigReturnBufferSizeInKByte = ip->config_return_buffer_size_in_kbytes;
435 	mode_lib->vba.CompressedBufferSegmentSizeInkByte = ip->compressed_buffer_segment_size_in_kbytes;
436 	mode_lib->vba.MetaFIFOSizeInKEntries = ip->meta_fifo_size_in_kentries;
437 	mode_lib->vba.ZeroSizeBufferEntries = ip->zero_size_buffer_entries;
438 	mode_lib->vba.COMPBUF_RESERVED_SPACE_64B = ip->compbuf_reserved_space_64b;
439 	mode_lib->vba.COMPBUF_RESERVED_SPACE_ZS = ip->compbuf_reserved_space_zs;
440 	mode_lib->vba.MaximumDSCBitsPerComponent = ip->maximum_dsc_bits_per_component;
441 	mode_lib->vba.DSC422NativeSupport = ip->dsc422_native_support;
442     /* In DCN3.2, nomDETInKByte should be initialized correctly. */
443 	mode_lib->vba.nomDETInKByte = ip->det_buffer_size_kbytes;
444 	mode_lib->vba.CompbufReservedSpace64B  = ip->compbuf_reserved_space_64b;
445 	mode_lib->vba.CompbufReservedSpaceZs = ip->compbuf_reserved_space_zs;
446 	mode_lib->vba.CompressedBufferSegmentSizeInkByteFinal = ip->compressed_buffer_segment_size_in_kbytes;
447 	mode_lib->vba.LineBufferSizeFinal = ip->line_buffer_size_bits;
448 	mode_lib->vba.AlphaPixelChunkSizeInKByte = ip->alpha_pixel_chunk_size_kbytes; // not ysed
449 	mode_lib->vba.MinPixelChunkSizeBytes = ip->min_pixel_chunk_size_bytes; // not used
450 	mode_lib->vba.MaximumPixelsPerLinePerDSCUnit = ip->maximum_pixels_per_line_per_dsc_unit;
451 	mode_lib->vba.MaxNumDP2p0Outputs = ip->max_num_dp2p0_outputs;
452 	mode_lib->vba.MaxNumDP2p0Streams = ip->max_num_dp2p0_streams;
453 	mode_lib->vba.DCCMetaBufferSizeBytes = ip->dcc_meta_buffer_size_bytes;
454 
455 	mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
456 	mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
457 	mode_lib->vba.MinMetaChunkSizeBytes = ip->min_meta_chunk_size_bytes;
458 	mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
459 	mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
460 	mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
461 	mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma;
462 	mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma;
463 	mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
464 	mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
465 	mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio;
466 	mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio;
467 	mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024;
468 	mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024;
469 
470 	mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes;
471 	mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size;
472 
473 	mode_lib->vba.WritebackChromaLineBufferWidth =
474 			ip->writeback_chroma_line_buffer_width_pixels;
475 	mode_lib->vba.WritebackLineBufferLumaBufferSize =
476 			ip->writeback_line_buffer_luma_buffer_size;
477 	mode_lib->vba.WritebackLineBufferChromaBufferSize =
478 			ip->writeback_line_buffer_chroma_buffer_size;
479 	mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported;
480 	mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio;
481 	mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio;
482 	mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio;
483 	mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio;
484 	mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps;
485 	mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps;
486 	mode_lib->vba.WritebackConfiguration = dm_normal;
487 	mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels;
488 	mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels;
489 	mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels;
490 	mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels;
491 	mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
492 	mode_lib->vba.NumberOfDSC = ip->num_dsc;
493 	mode_lib->vba.ODMCapability = ip->odm_capable;
494 	mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
495 
496 	mode_lib->vba.XFCSupported = ip->xfc_supported;
497 	mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
498 	mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
499 	mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
500 	mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
501 	mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
502 	mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
503 	mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
504 	mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
505 	mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled;
506 	mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported;
507 	mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
508 	mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
509 	mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes;
510 	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported;
511 }
512 
513 static void fetch_pipe_params(struct display_mode_lib *mode_lib)
514 {
515 	display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
516 	ip_params_st *ip = &mode_lib->vba.ip;
517 
518 	unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
519 	unsigned int j, k;
520 	bool PlaneVisited[DC__NUM_DPP__MAX];
521 	bool visited[DC__NUM_DPP__MAX];
522 
523 	// Convert Pipes to Planes
524 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
525 		visited[k] = false;
526 
527 	mode_lib->vba.NumberOfActivePlanes = 0;
528 	mode_lib->vba.NumberOfActiveSurfaces = 0;
529 	mode_lib->vba.ImmediateFlipSupport = false;
530 	for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
531 		display_pipe_source_params_st *src = &pipes[j].pipe.src;
532 		display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
533 		scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
534 		scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
535 		display_output_params_st *dout = &pipes[j].dout;
536 		display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
537 
538 		if (visited[j])
539 			continue;
540 		visited[j] = true;
541 
542 		mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_not_required;
543 		mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
544 		mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
545 		mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
546 				(enum scan_direction_class) (src->source_scan);
547 		mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
548 				src->viewport_width;
549 		mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] =
550 				src->viewport_width_c;
551 		mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
552 				src->viewport_height;
553 		mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] =
554 				src->viewport_height_c;
555 		mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
556 				src->viewport_y_y;
557 		mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
558 				src->viewport_y_c;
559 		mode_lib->vba.SourceRotation[mode_lib->vba.NumberOfActiveSurfaces] = src->source_rotation;
560 		mode_lib->vba.ViewportXStartY[mode_lib->vba.NumberOfActiveSurfaces] = src->viewport_x_y;
561 		mode_lib->vba.ViewportXStartC[mode_lib->vba.NumberOfActiveSurfaces] = src->viewport_x_c;
562 		// TODO: Assign correct value to viewport_stationary
563 		mode_lib->vba.ViewportStationary[mode_lib->vba.NumberOfActivePlanes] =
564 				src->viewport_stationary;
565 		mode_lib->vba.UsesMALLForPStateChange[mode_lib->vba.NumberOfActivePlanes] = src->use_mall_for_pstate_change;
566 		mode_lib->vba.UseMALLForStaticScreen[mode_lib->vba.NumberOfActivePlanes] = src->use_mall_for_static_screen;
567 		mode_lib->vba.GPUVMMinPageSizeKBytes[mode_lib->vba.NumberOfActivePlanes] = src->gpuvm_min_page_size_kbytes;
568 		mode_lib->vba.RefreshRate[mode_lib->vba.NumberOfActivePlanes] = dst->refresh_rate; //todo remove this
569 		mode_lib->vba.OutputLinkDPRate[mode_lib->vba.NumberOfActivePlanes] = dout->dp_rate;
570 		mode_lib->vba.ODMUse[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine_policy;
571 		mode_lib->vba.DETSizeOverride[mode_lib->vba.NumberOfActivePlanes] = src->det_size_override;
572 		//TODO: Need to assign correct values to dp_multistream vars
573 		mode_lib->vba.OutputMultistreamEn[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_en;
574 		mode_lib->vba.OutputMultistreamId[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_id;
575 		mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
576 		mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_y;
577 		mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_y;
578 		mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
579 		mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_c;
580 		mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_c;
581 		mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
582 		mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c;
583 		mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
584 		mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c;
585 		mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
586 		mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c;
587 		mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
588 		mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
589 		if (dst->interlaced && !ip->ptoi_supported) {
590 			mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
591 			mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
592 		}
593 		mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
594 		mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
595 		mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
596 		mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
597 		mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
598 		mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
599 		mode_lib->vba.VFrontPorch[mode_lib->vba.NumberOfActivePlanes] = dst->vfront_porch;
600 		mode_lib->vba.VBlankNom[mode_lib->vba.NumberOfActivePlanes] = dst->vblank_nom;
601 		mode_lib->vba.DCCFractionOfZeroSizeRequestsLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_luma;
602 		mode_lib->vba.DCCFractionOfZeroSizeRequestsChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_chroma;
603 		mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
604 				src->dcc_use_global ?
605 						ip->dcc_supported : src->dcc && ip->dcc_supported;
606 		mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
607 		/* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
608 		mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
609 		mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
610 		mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format);
611 		mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
612 		mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
613 		mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
614 				(enum dm_swizzle_mode) (src->sw_mode);
615 		mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
616 				dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
617 		mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
618 				dst->odm_combine;
619 		mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
620 				(enum output_format_class) (dout->output_format);
621 		mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
622 				dout->output_bpp;
623 		mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
624 				(enum output_encoder_class) (dout->output_type);
625 		mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
626 				dout->is_virtual;
627 
628 		if (!dout->dsc_enable)
629 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
630 		else
631 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
632 
633 		mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
634 				dout->dp_lanes;
635 		/* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
636 		mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
637 			dout->max_audio_sample_rate;
638 		mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
639 			1;
640 		mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
641 		mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
642 		mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
643 		mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
644 				dout->dsc_slices;
645 		if (!dout->dsc_input_bpc) {
646 			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
647 				ip->maximum_dsc_bits_per_component;
648 		} else {
649 			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
650 				dout->dsc_input_bpc;
651 		}
652 		mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
653 		mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
654 				dout->num_active_wb;
655 		mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
656 				dout->wb.wb_src_height;
657 		mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
658 				dout->wb.wb_src_width;
659 		mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
660 				dout->wb.wb_dst_width;
661 		mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
662 				dout->wb.wb_dst_height;
663 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
664 				dout->wb.wb_hratio;
665 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
666 				dout->wb.wb_vratio;
667 		mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
668 				(enum source_format_class) (dout->wb.wb_pixel_format);
669 		mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
670 				dout->wb.wb_htaps_luma;
671 		mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
672 				dout->wb.wb_vtaps_luma;
673 		mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
674 				dout->wb.wb_htaps_luma;
675 		mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
676 				dout->wb.wb_vtaps_luma;
677 		mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
678 				dout->wb.wb_htaps_chroma;
679 		mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
680 				dout->wb.wb_vtaps_chroma;
681 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
682 				dout->wb.wb_hratio;
683 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
684 				dout->wb.wb_vratio;
685 
686 		mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
687 				src->dynamic_metadata_enable;
688 		mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
689 				src->dynamic_metadata_lines_before_active;
690 		mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
691 				src->dynamic_metadata_xmit_bytes;
692 
693 		mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
694 				&& ip->xfc_supported;
695 		mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
696 		mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
697 		mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
698 		mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
699 		mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
700 		mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
701 		mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
702 		mode_lib->vba.DRRDisplay[mode_lib->vba.NumberOfActiveSurfaces] = dst->drr_display;
703 		if (ip->is_line_buffer_bpp_fixed)
704 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
705 					ip->line_buffer_fixed_bpp;
706 		else {
707 			unsigned int lb_depth;
708 
709 			switch (scl->lb_depth) {
710 			case dm_lb_6:
711 				lb_depth = 18;
712 				break;
713 			case dm_lb_8:
714 				lb_depth = 24;
715 				break;
716 			case dm_lb_10:
717 				lb_depth = 30;
718 				break;
719 			case dm_lb_12:
720 				lb_depth = 36;
721 				break;
722 			case dm_lb_16:
723 				lb_depth = 48;
724 				break;
725 			case dm_lb_19:
726 				lb_depth = 57;
727 				break;
728 			default:
729 				lb_depth = 36;
730 			}
731 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
732 		}
733 		mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
734 		// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
735 		// calculate things a little more accurately
736 		for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
737 			switch (k) {
738 			case 0:
739 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
740 						CursorBppEnumToBits(
741 								(enum cursor_bpp) (src->cur0_bpp));
742 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
743 						src->cur0_src_width;
744 				if (src->cur0_src_width > 0)
745 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
746 				break;
747 			case 1:
748 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
749 						CursorBppEnumToBits(
750 								(enum cursor_bpp) (src->cur1_bpp));
751 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
752 						src->cur1_src_width;
753 				if (src->cur1_src_width > 0)
754 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
755 				break;
756 			default:
757 				dml_print(
758 						"ERROR: Number of cursors specified exceeds supported maximum\n")
759 				;
760 			}
761 		}
762 
763 		OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
764 
765 		if (j == 0)
766 			mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
767 		else
768 			mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
769 									|| dst->use_maximum_vstartup;
770 
771 		if (dst->odm_combine && !src->is_hsplit)
772 			dml_print(
773 					"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
774 					j);
775 
776 		if (src->is_hsplit) {
777 			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
778 				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
779 				display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
780 
781 				if (src_k->is_hsplit && !visited[k]
782 						&& src->hsplit_grp == src_k->hsplit_grp) {
783 					mode_lib->vba.pipe_plane[k] =
784 							mode_lib->vba.NumberOfActivePlanes;
785 					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
786 					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
787 							== dm_horz) {
788 						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
789 								src_k->viewport_width;
790 						mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
791 								src_k->viewport_width_c;
792 						mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
793 								dst_k->recout_width;
794 					} else {
795 						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
796 								src_k->viewport_height;
797 						mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
798 								src_k->viewport_height_c;
799 					}
800 
801 					visited[k] = true;
802 				}
803 			}
804 		}
805 		if (src->viewport_width_max) {
806 			int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
807 			int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
808 
809 			if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
810 				mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
811 			if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
812 				mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
813 			if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
814 				mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
815 			if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
816 				mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
817 		}
818 
819 		if (pipes[j].pipe.src.immediate_flip) {
820 			mode_lib->vba.ImmediateFlipSupport = true;
821 			mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_required;
822 		}
823 
824 		mode_lib->vba.NumberOfActivePlanes++;
825 		mode_lib->vba.NumberOfActiveSurfaces++;
826 	}
827 
828 	// handle overlays through BlendingAndTiming
829 	// BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
830 
831 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
832 		PlaneVisited[j] = false;
833 
834 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
835 		for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
836 			if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
837 				// doesn't matter, so choose the smaller one
838 				mode_lib->vba.BlendingAndTiming[j] = j;
839 				PlaneVisited[j] = true;
840 				mode_lib->vba.BlendingAndTiming[k] = j;
841 				PlaneVisited[k] = true;
842 			}
843 		}
844 
845 		if (!PlaneVisited[j]) {
846 			mode_lib->vba.BlendingAndTiming[j] = j;
847 			PlaneVisited[j] = true;
848 		}
849 	}
850 
851 	mode_lib->vba.SynchronizeTimingsFinal = pipes[0].pipe.dest.synchronize_timings;
852 	mode_lib->vba.DCCProgrammingAssumesScanDirectionUnknownFinal = false;
853 
854 	mode_lib->vba.DisableUnboundRequestIfCompBufReservedSpaceNeedAdjustment = 0;
855 
856 	mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting;
857 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
858 		if (pipes[k].pipe.src.unbounded_req_mode == 0)
859 			mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting_disable;
860 	}
861 	// TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
862 	// Do we want the dscclk to automatically be halved? Guess not since the value is specified
863 	mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
864 	for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
865 		ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
866 	}
867 
868 	mode_lib->vba.GPUVMEnable = false;
869 	mode_lib->vba.HostVMEnable = false;
870 	mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
871 	mode_lib->vba.OverrideHostVMPageTableLevels = 0;
872 
873 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
874 		mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
875 		mode_lib->vba.OverrideGPUVMPageTableLevels =
876 				(pipes[k].pipe.src.gpuvm_levels_force_en
877 						&& mode_lib->vba.OverrideGPUVMPageTableLevels
878 								< pipes[k].pipe.src.gpuvm_levels_force) ?
879 						pipes[k].pipe.src.gpuvm_levels_force :
880 						mode_lib->vba.OverrideGPUVMPageTableLevels;
881 
882 		mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
883 		mode_lib->vba.OverrideHostVMPageTableLevels =
884 				(pipes[k].pipe.src.hostvm_levels_force_en
885 						&& mode_lib->vba.OverrideHostVMPageTableLevels
886 								< pipes[k].pipe.src.hostvm_levels_force) ?
887 						pipes[k].pipe.src.hostvm_levels_force :
888 						mode_lib->vba.OverrideHostVMPageTableLevels;
889 	}
890 
891 	if (mode_lib->vba.OverrideGPUVMPageTableLevels)
892 		mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
893 
894 	if (mode_lib->vba.OverrideHostVMPageTableLevels)
895 		mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
896 
897 	mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
898 	mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
899 
900 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
901 		mode_lib->vba.ForceOneRowForFrame[k] = pipes[k].pipe.src.force_one_row_for_frame;
902 		mode_lib->vba.PteBufferMode[k] = pipes[k].pipe.src.pte_buffer_mode;
903 
904 		if (mode_lib->vba.PteBufferMode[k] == 0 && mode_lib->vba.GPUVMEnable) {
905 			if (mode_lib->vba.ForceOneRowForFrame[k] ||
906 				(mode_lib->vba.GPUVMMinPageSizeKBytes[k] > 64*1024) ||
907 				(mode_lib->vba.UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_disable) ||
908 				(mode_lib->vba.UseMALLForStaticScreen[k] != dm_use_mall_static_screen_disable)) {
909 #ifdef __DML_VBA_DEBUG__
910 				dml_print("DML::%s: ERROR: Invalid PteBufferMode=%d for plane %0d!\n",
911 						__func__, mode_lib->vba.PteBufferMode[k], k);
912 				dml_print("DML::%s:  -  ForceOneRowForFrame     = %d\n",
913 						__func__, mode_lib->vba.ForceOneRowForFrame[k]);
914 				dml_print("DML::%s:  -  GPUVMMinPageSizeKBytes  = %d\n",
915 						__func__, mode_lib->vba.GPUVMMinPageSizeKBytes[k]);
916 				dml_print("DML::%s:  -  UseMALLForPStateChange  = %d\n",
917 						__func__, (int) mode_lib->vba.UsesMALLForPStateChange[k]);
918 				dml_print("DML::%s:  -  UseMALLForStaticScreen  = %d\n",
919 						__func__, (int) mode_lib->vba.UseMALLForStaticScreen[k]);
920 #endif
921 				ASSERT(0);
922 			}
923 		}
924 	}
925 }
926 
927 /**
928  * ********************************************************************************************
929  * cache_debug_params: Cache any params that needed to be maintained from the initial validation
930  * for debug purposes.
931  *
932  * The DML getters can modify some of the VBA params that we are interested in (for example when
933  * calculating with dummy p-state latency), so cache any params here that we want for debugging
934  *
935  * @param [in] mode_lib: mode_lib input/output of validate call
936  *
937  * @return: void
938  *
939  * ********************************************************************************************
940  */
941 static void cache_debug_params(struct display_mode_lib *mode_lib)
942 {
943 	int k = 0;
944 
945 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
946 		mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
947 }
948 
949 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
950 // rather than working them out as in recalculate_ms
951 static void recalculate_params(
952 		struct display_mode_lib *mode_lib,
953 		const display_e2e_pipe_params_st *pipes,
954 		unsigned int num_pipes)
955 {
956 	// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
957 	if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
958 			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
959 			|| num_pipes != mode_lib->vba.cache_num_pipes
960 			|| memcmp(
961 					pipes,
962 					mode_lib->vba.cache_pipes,
963 					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
964 		mode_lib->vba.soc = mode_lib->soc;
965 		mode_lib->vba.ip = mode_lib->ip;
966 		memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
967 		mode_lib->vba.cache_num_pipes = num_pipes;
968 		mode_lib->funcs.recalculate(mode_lib);
969 	}
970 }
971 
972 void Calculate256BBlockSizes(
973 		enum source_format_class SourcePixelFormat,
974 		enum dm_swizzle_mode SurfaceTiling,
975 		unsigned int BytePerPixelY,
976 		unsigned int BytePerPixelC,
977 		unsigned int *BlockHeight256BytesY,
978 		unsigned int *BlockHeight256BytesC,
979 		unsigned int *BlockWidth256BytesY,
980 		unsigned int *BlockWidth256BytesC)
981 {
982 	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
983 			|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
984 		if (SurfaceTiling == dm_sw_linear) {
985 			*BlockHeight256BytesY = 1;
986 		} else if (SourcePixelFormat == dm_444_64) {
987 			*BlockHeight256BytesY = 4;
988 		} else if (SourcePixelFormat == dm_444_8) {
989 			*BlockHeight256BytesY = 16;
990 		} else {
991 			*BlockHeight256BytesY = 8;
992 		}
993 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
994 		*BlockHeight256BytesC = 0;
995 		*BlockWidth256BytesC = 0;
996 	} else {
997 		if (SurfaceTiling == dm_sw_linear) {
998 			*BlockHeight256BytesY = 1;
999 			*BlockHeight256BytesC = 1;
1000 		} else if (SourcePixelFormat == dm_420_8) {
1001 			*BlockHeight256BytesY = 16;
1002 			*BlockHeight256BytesC = 8;
1003 		} else {
1004 			*BlockHeight256BytesY = 8;
1005 			*BlockHeight256BytesC = 8;
1006 		}
1007 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
1008 		*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
1009 	}
1010 }
1011 
1012 bool CalculateMinAndMaxPrefetchMode(
1013 		enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
1014 		unsigned int *MinPrefetchMode,
1015 		unsigned int *MaxPrefetchMode)
1016 {
1017 	if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1018 			== dm_neither_self_refresh_nor_mclk_switch) {
1019 		*MinPrefetchMode = 2;
1020 		*MaxPrefetchMode = 2;
1021 		return false;
1022 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
1023 		*MinPrefetchMode = 1;
1024 		*MaxPrefetchMode = 1;
1025 		return false;
1026 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1027 			== dm_allow_self_refresh_and_mclk_switch) {
1028 		*MinPrefetchMode = 0;
1029 		*MaxPrefetchMode = 0;
1030 		return false;
1031 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1032 			== dm_try_to_allow_self_refresh_and_mclk_switch) {
1033 		*MinPrefetchMode = 0;
1034 		*MaxPrefetchMode = 2;
1035 		return false;
1036 	}
1037 	*MinPrefetchMode = 0;
1038 	*MaxPrefetchMode = 2;
1039 	return true;
1040 }
1041 
1042 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
1043 {
1044 	unsigned int k;
1045 
1046 	//Progressive To Interlace Unit Effect
1047 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1048 		mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
1049 		if (mode_lib->vba.Interlace[k] == 1
1050 				&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
1051 			mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
1052 		}
1053 	}
1054 }
1055 
1056 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
1057 {
1058 	switch (ebpp) {
1059 	case dm_cur_2bit:
1060 		return 2;
1061 	case dm_cur_32bit:
1062 		return 32;
1063 	case dm_cur_64bit:
1064 		return 64;
1065 	default:
1066 		return 0;
1067 	}
1068 }
1069 
1070 void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
1071 {
1072 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
1073 	unsigned int k;
1074 	unsigned int total_pipes = 0;
1075 	unsigned int pipe_idx = 0;
1076 
1077 	mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
1078 	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
1079 	if (mode_lib->vba.ReturnBW == 0)
1080 		mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
1081 	mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
1082 
1083 	fetch_socbb_params(mode_lib);
1084 	fetch_ip_params(mode_lib);
1085 	fetch_pipe_params(mode_lib);
1086 
1087 	mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
1088 	mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
1089 	if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
1090 		mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
1091 	else
1092 		mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
1093 
1094 	// Total Available Pipes Support Check
1095 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1096 		total_pipes += mode_lib->vba.DPPPerPlane[k];
1097 		pipe_idx = get_pipe_idx(mode_lib, k);
1098 		if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0)
1099 			mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz;
1100 		else
1101 			mode_lib->vba.DPPCLK[k] = soc->clock_limits[mode_lib->vba.VoltageLevel].dppclk_mhz;
1102 	}
1103 	ASSERT(total_pipes <= DC__NUM_DPP__MAX);
1104 }
1105 
1106 double CalculateWriteBackDISPCLK(
1107 		enum source_format_class WritebackPixelFormat,
1108 		double PixelClock,
1109 		double WritebackHRatio,
1110 		double WritebackVRatio,
1111 		unsigned int WritebackLumaHTaps,
1112 		unsigned int WritebackLumaVTaps,
1113 		unsigned int WritebackChromaHTaps,
1114 		unsigned int WritebackChromaVTaps,
1115 		double WritebackDestinationWidth,
1116 		unsigned int HTotal,
1117 		unsigned int WritebackChromaLineBufferWidth)
1118 {
1119 	double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
1120 		dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
1121 		dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
1122 			+ dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
1123 			* (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
1124 			dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
1125 	if (WritebackPixelFormat != dm_444_32) {
1126 		CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
1127 			dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
1128 			dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
1129 				+ dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
1130 				+ dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
1131 				dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
1132 	}
1133 	return CalculateWriteBackDISPCLK;
1134 }
1135 
1136