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.DCCFractionOfZeroSizeRequestsLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_luma;
601 		mode_lib->vba.DCCFractionOfZeroSizeRequestsChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_chroma;
602 		mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
603 				src->dcc_use_global ?
604 						ip->dcc_supported : src->dcc && ip->dcc_supported;
605 		mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
606 		/* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
607 		mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
608 		mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
609 		mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format);
610 		mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
611 		mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
612 		mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
613 				(enum dm_swizzle_mode) (src->sw_mode);
614 		mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
615 				dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
616 		mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
617 				dst->odm_combine;
618 		mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
619 				(enum output_format_class) (dout->output_format);
620 		mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
621 				dout->output_bpp;
622 		mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
623 				(enum output_encoder_class) (dout->output_type);
624 		mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
625 				dout->is_virtual;
626 
627 		if (!dout->dsc_enable)
628 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
629 		else
630 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
631 
632 		mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
633 				dout->dp_lanes;
634 		/* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
635 		mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
636 			dout->max_audio_sample_rate;
637 		mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
638 			1;
639 		mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
640 		mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
641 		mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
642 		mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
643 				dout->dsc_slices;
644 		if (!dout->dsc_input_bpc) {
645 			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
646 				ip->maximum_dsc_bits_per_component;
647 		} else {
648 			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
649 				dout->dsc_input_bpc;
650 		}
651 		mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
652 		mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
653 				dout->num_active_wb;
654 		mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
655 				dout->wb.wb_src_height;
656 		mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
657 				dout->wb.wb_src_width;
658 		mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
659 				dout->wb.wb_dst_width;
660 		mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
661 				dout->wb.wb_dst_height;
662 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
663 				dout->wb.wb_hratio;
664 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
665 				dout->wb.wb_vratio;
666 		mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
667 				(enum source_format_class) (dout->wb.wb_pixel_format);
668 		mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
669 				dout->wb.wb_htaps_luma;
670 		mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
671 				dout->wb.wb_vtaps_luma;
672 		mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
673 				dout->wb.wb_htaps_luma;
674 		mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
675 				dout->wb.wb_vtaps_luma;
676 		mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
677 				dout->wb.wb_htaps_chroma;
678 		mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
679 				dout->wb.wb_vtaps_chroma;
680 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
681 				dout->wb.wb_hratio;
682 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
683 				dout->wb.wb_vratio;
684 
685 		mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
686 				src->dynamic_metadata_enable;
687 		mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
688 				src->dynamic_metadata_lines_before_active;
689 		mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
690 				src->dynamic_metadata_xmit_bytes;
691 
692 		mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
693 				&& ip->xfc_supported;
694 		mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
695 		mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
696 		mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
697 		mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
698 		mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
699 		mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
700 		mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
701 		mode_lib->vba.DRRDisplay[mode_lib->vba.NumberOfActiveSurfaces] = dst->drr_display;
702 		if (ip->is_line_buffer_bpp_fixed)
703 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
704 					ip->line_buffer_fixed_bpp;
705 		else {
706 			unsigned int lb_depth;
707 
708 			switch (scl->lb_depth) {
709 			case dm_lb_6:
710 				lb_depth = 18;
711 				break;
712 			case dm_lb_8:
713 				lb_depth = 24;
714 				break;
715 			case dm_lb_10:
716 				lb_depth = 30;
717 				break;
718 			case dm_lb_12:
719 				lb_depth = 36;
720 				break;
721 			case dm_lb_16:
722 				lb_depth = 48;
723 				break;
724 			case dm_lb_19:
725 				lb_depth = 57;
726 				break;
727 			default:
728 				lb_depth = 36;
729 			}
730 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
731 		}
732 		mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
733 		// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
734 		// calculate things a little more accurately
735 		for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
736 			switch (k) {
737 			case 0:
738 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
739 						CursorBppEnumToBits(
740 								(enum cursor_bpp) (src->cur0_bpp));
741 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
742 						src->cur0_src_width;
743 				if (src->cur0_src_width > 0)
744 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
745 				break;
746 			case 1:
747 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
748 						CursorBppEnumToBits(
749 								(enum cursor_bpp) (src->cur1_bpp));
750 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
751 						src->cur1_src_width;
752 				if (src->cur1_src_width > 0)
753 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
754 				break;
755 			default:
756 				dml_print(
757 						"ERROR: Number of cursors specified exceeds supported maximum\n")
758 				;
759 			}
760 		}
761 
762 		OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
763 
764 		if (j == 0)
765 			mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
766 		else
767 			mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
768 									|| dst->use_maximum_vstartup;
769 
770 		if (dst->odm_combine && !src->is_hsplit)
771 			dml_print(
772 					"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
773 					j);
774 
775 		if (src->is_hsplit) {
776 			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
777 				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
778 				display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
779 
780 				if (src_k->is_hsplit && !visited[k]
781 						&& src->hsplit_grp == src_k->hsplit_grp) {
782 					mode_lib->vba.pipe_plane[k] =
783 							mode_lib->vba.NumberOfActivePlanes;
784 					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
785 					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
786 							== dm_horz) {
787 						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
788 								src_k->viewport_width;
789 						mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
790 								src_k->viewport_width_c;
791 						mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
792 								dst_k->recout_width;
793 					} else {
794 						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
795 								src_k->viewport_height;
796 						mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
797 								src_k->viewport_height_c;
798 					}
799 
800 					visited[k] = true;
801 				}
802 			}
803 		}
804 		if (src->viewport_width_max) {
805 			int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
806 			int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
807 
808 			if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
809 				mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
810 			if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
811 				mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
812 			if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
813 				mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
814 			if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
815 				mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
816 		}
817 
818 		if (pipes[j].pipe.src.immediate_flip) {
819 			mode_lib->vba.ImmediateFlipSupport = true;
820 			mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_required;
821 		}
822 
823 		mode_lib->vba.NumberOfActivePlanes++;
824 		mode_lib->vba.NumberOfActiveSurfaces++;
825 	}
826 
827 	// handle overlays through BlendingAndTiming
828 	// BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
829 
830 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
831 		PlaneVisited[j] = false;
832 
833 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
834 		for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
835 			if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
836 				// doesn't matter, so choose the smaller one
837 				mode_lib->vba.BlendingAndTiming[j] = j;
838 				PlaneVisited[j] = true;
839 				mode_lib->vba.BlendingAndTiming[k] = j;
840 				PlaneVisited[k] = true;
841 			}
842 		}
843 
844 		if (!PlaneVisited[j]) {
845 			mode_lib->vba.BlendingAndTiming[j] = j;
846 			PlaneVisited[j] = true;
847 		}
848 	}
849 
850 	mode_lib->vba.SynchronizeTimingsFinal = pipes[0].pipe.dest.synchronize_timings;
851 	mode_lib->vba.DCCProgrammingAssumesScanDirectionUnknownFinal = false;
852 
853 	mode_lib->vba.DisableUnboundRequestIfCompBufReservedSpaceNeedAdjustment = 0;
854 
855 	mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting;
856 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
857 		if (pipes[k].pipe.src.unbounded_req_mode == 0)
858 			mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting_disable;
859 	}
860 	// TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
861 	// Do we want the dscclk to automatically be halved? Guess not since the value is specified
862 	mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
863 	for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
864 		ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
865 	}
866 
867 	mode_lib->vba.GPUVMEnable = false;
868 	mode_lib->vba.HostVMEnable = false;
869 	mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
870 	mode_lib->vba.OverrideHostVMPageTableLevels = 0;
871 
872 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
873 		mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
874 		mode_lib->vba.OverrideGPUVMPageTableLevels =
875 				(pipes[k].pipe.src.gpuvm_levels_force_en
876 						&& mode_lib->vba.OverrideGPUVMPageTableLevels
877 								< pipes[k].pipe.src.gpuvm_levels_force) ?
878 						pipes[k].pipe.src.gpuvm_levels_force :
879 						mode_lib->vba.OverrideGPUVMPageTableLevels;
880 
881 		mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
882 		mode_lib->vba.OverrideHostVMPageTableLevels =
883 				(pipes[k].pipe.src.hostvm_levels_force_en
884 						&& mode_lib->vba.OverrideHostVMPageTableLevels
885 								< pipes[k].pipe.src.hostvm_levels_force) ?
886 						pipes[k].pipe.src.hostvm_levels_force :
887 						mode_lib->vba.OverrideHostVMPageTableLevels;
888 	}
889 
890 	if (mode_lib->vba.OverrideGPUVMPageTableLevels)
891 		mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
892 
893 	if (mode_lib->vba.OverrideHostVMPageTableLevels)
894 		mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
895 
896 	mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
897 	mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
898 
899 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
900 		mode_lib->vba.ForceOneRowForFrame[k] = pipes[k].pipe.src.force_one_row_for_frame;
901 		mode_lib->vba.PteBufferMode[k] = pipes[k].pipe.src.pte_buffer_mode;
902 
903 		if (mode_lib->vba.PteBufferMode[k] == 0 && mode_lib->vba.GPUVMEnable) {
904 			if (mode_lib->vba.ForceOneRowForFrame[k] ||
905 				(mode_lib->vba.GPUVMMinPageSizeKBytes[k] > 64*1024) ||
906 				(mode_lib->vba.UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_disable) ||
907 				(mode_lib->vba.UseMALLForStaticScreen[k] != dm_use_mall_static_screen_disable)) {
908 #ifdef __DML_VBA_DEBUG__
909 				dml_print("DML::%s: ERROR: Invalid PteBufferMode=%d for plane %0d!\n",
910 						__func__, mode_lib->vba.PteBufferMode[k], k);
911 				dml_print("DML::%s:  -  ForceOneRowForFrame     = %d\n",
912 						__func__, mode_lib->vba.ForceOneRowForFrame[k]);
913 				dml_print("DML::%s:  -  GPUVMMinPageSizeKBytes  = %d\n",
914 						__func__, mode_lib->vba.GPUVMMinPageSizeKBytes[k]);
915 				dml_print("DML::%s:  -  UseMALLForPStateChange  = %d\n",
916 						__func__, (int) mode_lib->vba.UsesMALLForPStateChange[k]);
917 				dml_print("DML::%s:  -  UseMALLForStaticScreen  = %d\n",
918 						__func__, (int) mode_lib->vba.UseMALLForStaticScreen[k]);
919 #endif
920 				ASSERT(0);
921 			}
922 		}
923 	}
924 }
925 
926 /**
927  * ********************************************************************************************
928  * cache_debug_params: Cache any params that needed to be maintained from the initial validation
929  * for debug purposes.
930  *
931  * The DML getters can modify some of the VBA params that we are interested in (for example when
932  * calculating with dummy p-state latency), so cache any params here that we want for debugging
933  *
934  * @param [in] mode_lib: mode_lib input/output of validate call
935  *
936  * @return: void
937  *
938  * ********************************************************************************************
939  */
940 static void cache_debug_params(struct display_mode_lib *mode_lib)
941 {
942 	int k = 0;
943 
944 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
945 		mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
946 }
947 
948 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
949 // rather than working them out as in recalculate_ms
950 static void recalculate_params(
951 		struct display_mode_lib *mode_lib,
952 		const display_e2e_pipe_params_st *pipes,
953 		unsigned int num_pipes)
954 {
955 	// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
956 	if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
957 			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
958 			|| num_pipes != mode_lib->vba.cache_num_pipes
959 			|| memcmp(
960 					pipes,
961 					mode_lib->vba.cache_pipes,
962 					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
963 		mode_lib->vba.soc = mode_lib->soc;
964 		mode_lib->vba.ip = mode_lib->ip;
965 		memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
966 		mode_lib->vba.cache_num_pipes = num_pipes;
967 		mode_lib->funcs.recalculate(mode_lib);
968 	}
969 }
970 
971 void Calculate256BBlockSizes(
972 		enum source_format_class SourcePixelFormat,
973 		enum dm_swizzle_mode SurfaceTiling,
974 		unsigned int BytePerPixelY,
975 		unsigned int BytePerPixelC,
976 		unsigned int *BlockHeight256BytesY,
977 		unsigned int *BlockHeight256BytesC,
978 		unsigned int *BlockWidth256BytesY,
979 		unsigned int *BlockWidth256BytesC)
980 {
981 	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
982 			|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
983 		if (SurfaceTiling == dm_sw_linear) {
984 			*BlockHeight256BytesY = 1;
985 		} else if (SourcePixelFormat == dm_444_64) {
986 			*BlockHeight256BytesY = 4;
987 		} else if (SourcePixelFormat == dm_444_8) {
988 			*BlockHeight256BytesY = 16;
989 		} else {
990 			*BlockHeight256BytesY = 8;
991 		}
992 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
993 		*BlockHeight256BytesC = 0;
994 		*BlockWidth256BytesC = 0;
995 	} else {
996 		if (SurfaceTiling == dm_sw_linear) {
997 			*BlockHeight256BytesY = 1;
998 			*BlockHeight256BytesC = 1;
999 		} else if (SourcePixelFormat == dm_420_8) {
1000 			*BlockHeight256BytesY = 16;
1001 			*BlockHeight256BytesC = 8;
1002 		} else {
1003 			*BlockHeight256BytesY = 8;
1004 			*BlockHeight256BytesC = 8;
1005 		}
1006 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
1007 		*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
1008 	}
1009 }
1010 
1011 bool CalculateMinAndMaxPrefetchMode(
1012 		enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
1013 		unsigned int *MinPrefetchMode,
1014 		unsigned int *MaxPrefetchMode)
1015 {
1016 	if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1017 			== dm_neither_self_refresh_nor_mclk_switch) {
1018 		*MinPrefetchMode = 2;
1019 		*MaxPrefetchMode = 2;
1020 		return false;
1021 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
1022 		*MinPrefetchMode = 1;
1023 		*MaxPrefetchMode = 1;
1024 		return false;
1025 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1026 			== dm_allow_self_refresh_and_mclk_switch) {
1027 		*MinPrefetchMode = 0;
1028 		*MaxPrefetchMode = 0;
1029 		return false;
1030 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1031 			== dm_try_to_allow_self_refresh_and_mclk_switch) {
1032 		*MinPrefetchMode = 0;
1033 		*MaxPrefetchMode = 2;
1034 		return false;
1035 	}
1036 	*MinPrefetchMode = 0;
1037 	*MaxPrefetchMode = 2;
1038 	return true;
1039 }
1040 
1041 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
1042 {
1043 	unsigned int k;
1044 
1045 	//Progressive To Interlace Unit Effect
1046 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1047 		mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
1048 		if (mode_lib->vba.Interlace[k] == 1
1049 				&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
1050 			mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
1051 		}
1052 	}
1053 }
1054 
1055 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
1056 {
1057 	switch (ebpp) {
1058 	case dm_cur_2bit:
1059 		return 2;
1060 	case dm_cur_32bit:
1061 		return 32;
1062 	case dm_cur_64bit:
1063 		return 64;
1064 	default:
1065 		return 0;
1066 	}
1067 }
1068 
1069 void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
1070 {
1071 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
1072 	unsigned int k;
1073 	unsigned int total_pipes = 0;
1074 	unsigned int pipe_idx = 0;
1075 
1076 	mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
1077 	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
1078 	if (mode_lib->vba.ReturnBW == 0)
1079 		mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
1080 	mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
1081 
1082 	fetch_socbb_params(mode_lib);
1083 	fetch_ip_params(mode_lib);
1084 	fetch_pipe_params(mode_lib);
1085 
1086 	mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
1087 	mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
1088 	if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
1089 		mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
1090 	else
1091 		mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
1092 
1093 	// Total Available Pipes Support Check
1094 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1095 		total_pipes += mode_lib->vba.DPPPerPlane[k];
1096 		pipe_idx = get_pipe_idx(mode_lib, k);
1097 		if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0)
1098 			mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz;
1099 		else
1100 			mode_lib->vba.DPPCLK[k] = soc->clock_limits[mode_lib->vba.VoltageLevel].dppclk_mhz;
1101 	}
1102 	ASSERT(total_pipes <= DC__NUM_DPP__MAX);
1103 }
1104 
1105 double CalculateWriteBackDISPCLK(
1106 		enum source_format_class WritebackPixelFormat,
1107 		double PixelClock,
1108 		double WritebackHRatio,
1109 		double WritebackVRatio,
1110 		unsigned int WritebackLumaHTaps,
1111 		unsigned int WritebackLumaVTaps,
1112 		unsigned int WritebackChromaHTaps,
1113 		unsigned int WritebackChromaVTaps,
1114 		double WritebackDestinationWidth,
1115 		unsigned int HTotal,
1116 		unsigned int WritebackChromaLineBufferWidth)
1117 {
1118 	double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
1119 		dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
1120 		dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
1121 			+ dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
1122 			* (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
1123 			dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
1124 	if (WritebackPixelFormat != dm_444_32) {
1125 		CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
1126 			dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
1127 			dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
1128 				+ dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
1129 				+ dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
1130 				dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
1131 	}
1132 	return CalculateWriteBackDISPCLK;
1133 }
1134 
1135