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 dml_get_pipe_attr_func(surface_size_in_mall, mode_lib->vba.SurfaceSizeInMALL)
206 
207 double get_total_immediate_flip_bytes(
208 		struct display_mode_lib *mode_lib,
209 		const display_e2e_pipe_params_st *pipes,
210 		unsigned int num_pipes)
211 {
212 	recalculate_params(mode_lib, pipes, num_pipes);
213 	return mode_lib->vba.TotImmediateFlipBytes;
214 }
215 
216 double get_total_immediate_flip_bw(
217 		struct display_mode_lib *mode_lib,
218 		const display_e2e_pipe_params_st *pipes,
219 		unsigned int num_pipes)
220 {
221 	unsigned int k;
222 	double immediate_flip_bw = 0.0;
223 	recalculate_params(mode_lib, pipes, num_pipes);
224 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
225 		immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k];
226 	return immediate_flip_bw;
227 }
228 
229 double get_total_prefetch_bw(
230 		struct display_mode_lib *mode_lib,
231 		const display_e2e_pipe_params_st *pipes,
232 		unsigned int num_pipes)
233 {
234 	unsigned int k;
235 	double total_prefetch_bw = 0.0;
236 
237 	recalculate_params(mode_lib, pipes, num_pipes);
238 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
239 		total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
240 	return total_prefetch_bw;
241 }
242 
243 unsigned int get_total_surface_size_in_mall_bytes(
244 		struct display_mode_lib *mode_lib,
245 		const display_e2e_pipe_params_st *pipes,
246 		unsigned int num_pipes)
247 {
248 	unsigned int k;
249 	unsigned int size = 0.0;
250 	recalculate_params(mode_lib, pipes, num_pipes);
251 	for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k)
252 		size += mode_lib->vba.SurfaceSizeInMALL[k];
253 	return size;
254 }
255 
256 static unsigned int get_pipe_idx(struct display_mode_lib *mode_lib, unsigned int plane_idx)
257 {
258 	int pipe_idx = -1;
259 	int i;
260 
261 	ASSERT(plane_idx < DC__NUM_DPP__MAX);
262 
263 	for (i = 0; i < DC__NUM_DPP__MAX ; i++) {
264 		if (plane_idx == mode_lib->vba.pipe_plane[i]) {
265 			pipe_idx = i;
266 			break;
267 		}
268 	}
269 	ASSERT(pipe_idx >= 0);
270 
271 	return pipe_idx;
272 }
273 
274 
275 double get_det_buffer_size_kbytes(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes,
276 		unsigned int num_pipes, unsigned int pipe_idx)
277 {
278 	unsigned int plane_idx;
279 	double det_buf_size_kbytes;
280 
281 	recalculate_params(mode_lib, pipes, num_pipes);
282 	plane_idx = mode_lib->vba.pipe_plane[pipe_idx];
283 
284 	dml_print("DML::%s: num_pipes=%d pipe_idx=%d plane_idx=%0d\n", __func__, num_pipes, pipe_idx, plane_idx);
285 	det_buf_size_kbytes = mode_lib->vba.DETBufferSizeInKByte[plane_idx]; // per hubp DET buffer size
286 
287 	dml_print("DML::%s: det_buf_size_kbytes=%3.2f\n", __func__, det_buf_size_kbytes);
288 
289 	return det_buf_size_kbytes;
290 }
291 
292 bool get_is_phantom_pipe(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes,
293 		unsigned int num_pipes, unsigned int pipe_idx)
294 {
295 	unsigned int plane_idx;
296 
297 	recalculate_params(mode_lib, pipes, num_pipes);
298 	plane_idx = mode_lib->vba.pipe_plane[pipe_idx];
299 	dml_print("DML::%s: num_pipes=%d pipe_idx=%d UseMALLForPStateChange=%0d\n", __func__, num_pipes, pipe_idx,
300 			mode_lib->vba.UsesMALLForPStateChange[plane_idx]);
301 	return (mode_lib->vba.UsesMALLForPStateChange[plane_idx] == dm_use_mall_pstate_change_phantom_pipe);
302 }
303 
304 static void fetch_socbb_params(struct display_mode_lib *mode_lib)
305 {
306 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
307 	int i;
308 
309 	// SOC Bounding Box Parameters
310 	mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
311 	mode_lib->vba.NumberOfChannels = soc->num_chans;
312 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly =
313 			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!
314 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData =
315 			soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
316 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly =
317 			soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
318 	mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation =
319 			soc->max_avg_sdp_bw_use_normal_percent;
320 	mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation =
321 			soc->max_avg_dram_bw_use_normal_percent;
322 	mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us;
323 	mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us;
324 	mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us;
325 	mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
326 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly =
327 			soc->urgent_out_of_order_return_per_channel_pixel_only_bytes;
328 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData =
329 			soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
330 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly =
331 			soc->urgent_out_of_order_return_per_channel_vm_only_bytes;
332 	mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
333 	mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
334 	mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
335 	mode_lib->vba.PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = soc->pct_ideal_sdp_bw_after_urgent;
336 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
337 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only;
338 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
339 	mode_lib->vba.MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation =
340 			soc->max_avg_sdp_bw_use_normal_percent;
341 	mode_lib->vba.SRExitZ8Time = soc->sr_exit_z8_time_us;
342 	mode_lib->vba.SREnterPlusExitZ8Time = soc->sr_enter_plus_exit_z8_time_us;
343 	mode_lib->vba.FCLKChangeLatency = soc->fclk_change_latency_us;
344 	mode_lib->vba.USRRetrainingLatency = soc->usr_retraining_latency_us;
345 	mode_lib->vba.SMNLatency = soc->smn_latency_us;
346 	mode_lib->vba.MALLAllocatedForDCNFinal = soc->mall_allocated_for_dcn_mbytes;
347 
348 	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencySTROBE = soc->pct_ideal_dram_bw_after_urgent_strobe;
349 	mode_lib->vba.MaxAveragePercentOfIdealFabricBWDisplayCanUseInNormalSystemOperation =
350 			soc->max_avg_fabric_bw_use_normal_percent;
351 	mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperationSTROBE =
352 			soc->max_avg_dram_bw_use_normal_strobe_percent;
353 
354 	mode_lib->vba.DRAMClockChangeRequirementFinal = soc->dram_clock_change_requirement_final;
355 	mode_lib->vba.FCLKChangeRequirementFinal = 1;
356 	mode_lib->vba.USRRetrainingRequiredFinal = 1;
357 	mode_lib->vba.AllowForPStateChangeOrStutterInVBlankFinal = soc->allow_for_pstate_or_stutter_in_vblank_final;
358 	mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
359 	mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
360 	mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
361 			mode_lib->vba.DummyPStateCheck;
362 	mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive;
363 	mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank =
364 		soc->allow_dram_self_refresh_or_dram_clock_change_in_vblank;
365 
366 	mode_lib->vba.Downspreading = soc->downspread_percent;
367 	mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes;   // new!
368 	mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
369 	mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent;   // new
370 	mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz;   // new
371 	mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
372 	mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024;
373 	mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024;
374 	// Set the voltage scaling clocks as the defaults. Most of these will
375 	// be set to different values by the test
376 	for (i = 0; i < mode_lib->vba.soc.num_states; i++)
377 		if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
378 			break;
379 
380 	mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
381 	mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
382 	mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts;
383 	mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
384 
385 	mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
386 	mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
387 	mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw;
388 
389 	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
390 	mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
391 	mode_lib->vba.MaxHSCLRatio = 4;
392 	mode_lib->vba.MaxVSCLRatio = 4;
393 	mode_lib->vba.Cursor64BppSupport = true;
394 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
395 		mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
396 		mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
397 		mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
398 		mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
399 		mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz;
400 		mode_lib->vba.PHYCLKD32PerState[i] = soc->clock_limits[i].phyclk_d32_mhz;
401 		mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
402 		mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
403 		mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts;
404 		//mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
405 		mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
406 		mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz;
407 	}
408 
409 	mode_lib->vba.DoUrgentLatencyAdjustment =
410 		soc->do_urgent_latency_adjustment;
411 	mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent =
412 		soc->urgent_latency_adjustment_fabric_clock_component_us;
413 	mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
414 		soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
415 	mode_lib->vba.MaxVRatioPre = soc->max_vratio_pre;
416 }
417 
418 static void fetch_ip_params(struct display_mode_lib *mode_lib)
419 {
420 	ip_params_st *ip = &mode_lib->vba.ip;
421 
422 	// IP Parameters
423 	mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
424 	mode_lib->vba.ClampMinDCFCLK = ip->clamp_min_dcfclk;
425 	mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
426 	mode_lib->vba.MaxNumOTG = ip->max_num_otg;
427 	mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
428 	mode_lib->vba.MaxNumWriteback = ip->max_num_wb;
429 	mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
430 	mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
431 
432 	mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
433 	mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
434 	mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
435 	mode_lib->vba.DETBufferSizeInKByte[0] = ip->det_buffer_size_kbytes;
436 	mode_lib->vba.ConfigReturnBufferSizeInKByte = ip->config_return_buffer_size_in_kbytes;
437 	mode_lib->vba.CompressedBufferSegmentSizeInkByte = ip->compressed_buffer_segment_size_in_kbytes;
438 	mode_lib->vba.MetaFIFOSizeInKEntries = ip->meta_fifo_size_in_kentries;
439 	mode_lib->vba.ZeroSizeBufferEntries = ip->zero_size_buffer_entries;
440 	mode_lib->vba.COMPBUF_RESERVED_SPACE_64B = ip->compbuf_reserved_space_64b;
441 	mode_lib->vba.COMPBUF_RESERVED_SPACE_ZS = ip->compbuf_reserved_space_zs;
442 	mode_lib->vba.MaximumDSCBitsPerComponent = ip->maximum_dsc_bits_per_component;
443 	mode_lib->vba.DSC422NativeSupport = ip->dsc422_native_support;
444     /* In DCN3.2, nomDETInKByte should be initialized correctly. */
445 	mode_lib->vba.nomDETInKByte = ip->det_buffer_size_kbytes;
446 	mode_lib->vba.CompbufReservedSpace64B  = ip->compbuf_reserved_space_64b;
447 	mode_lib->vba.CompbufReservedSpaceZs = ip->compbuf_reserved_space_zs;
448 	mode_lib->vba.CompressedBufferSegmentSizeInkByteFinal = ip->compressed_buffer_segment_size_in_kbytes;
449 	mode_lib->vba.LineBufferSizeFinal = ip->line_buffer_size_bits;
450 	mode_lib->vba.AlphaPixelChunkSizeInKByte = ip->alpha_pixel_chunk_size_kbytes; // not ysed
451 	mode_lib->vba.MinPixelChunkSizeBytes = ip->min_pixel_chunk_size_bytes; // not used
452 	mode_lib->vba.MaximumPixelsPerLinePerDSCUnit = ip->maximum_pixels_per_line_per_dsc_unit;
453 	mode_lib->vba.MaxNumDP2p0Outputs = ip->max_num_dp2p0_outputs;
454 	mode_lib->vba.MaxNumDP2p0Streams = ip->max_num_dp2p0_streams;
455 	mode_lib->vba.DCCMetaBufferSizeBytes = ip->dcc_meta_buffer_size_bytes;
456 
457 	mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
458 	mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
459 	mode_lib->vba.MinMetaChunkSizeBytes = ip->min_meta_chunk_size_bytes;
460 	mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
461 	mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
462 	mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
463 	mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma;
464 	mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma;
465 	mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
466 	mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
467 	mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio;
468 	mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio;
469 	mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024;
470 	mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024;
471 
472 	mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes;
473 	mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size;
474 
475 	mode_lib->vba.WritebackChromaLineBufferWidth =
476 			ip->writeback_chroma_line_buffer_width_pixels;
477 	mode_lib->vba.WritebackLineBufferLumaBufferSize =
478 			ip->writeback_line_buffer_luma_buffer_size;
479 	mode_lib->vba.WritebackLineBufferChromaBufferSize =
480 			ip->writeback_line_buffer_chroma_buffer_size;
481 	mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported;
482 	mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio;
483 	mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio;
484 	mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio;
485 	mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio;
486 	mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps;
487 	mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps;
488 	mode_lib->vba.WritebackConfiguration = dm_normal;
489 	mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels;
490 	mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels;
491 	mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels;
492 	mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels;
493 	mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
494 	mode_lib->vba.NumberOfDSC = ip->num_dsc;
495 	mode_lib->vba.ODMCapability = ip->odm_capable;
496 	mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
497 
498 	mode_lib->vba.XFCSupported = ip->xfc_supported;
499 	mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
500 	mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
501 	mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
502 	mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
503 	mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
504 	mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
505 	mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
506 	mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
507 	mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled;
508 	mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported;
509 	mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
510 	mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
511 	mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes;
512 	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported;
513 }
514 
515 static void fetch_pipe_params(struct display_mode_lib *mode_lib)
516 {
517 	display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
518 	ip_params_st *ip = &mode_lib->vba.ip;
519 
520 	unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
521 	unsigned int j, k;
522 	bool PlaneVisited[DC__NUM_DPP__MAX];
523 	bool visited[DC__NUM_DPP__MAX];
524 
525 	// Convert Pipes to Planes
526 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
527 		visited[k] = false;
528 
529 	mode_lib->vba.NumberOfActivePlanes = 0;
530 	mode_lib->vba.NumberOfActiveSurfaces = 0;
531 	mode_lib->vba.ImmediateFlipSupport = false;
532 	for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
533 		display_pipe_source_params_st *src = &pipes[j].pipe.src;
534 		display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
535 		scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
536 		scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
537 		display_output_params_st *dout = &pipes[j].dout;
538 		display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
539 
540 		if (visited[j])
541 			continue;
542 		visited[j] = true;
543 
544 		mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_not_required;
545 		mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
546 		mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
547 		mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
548 				(enum scan_direction_class) (src->source_scan);
549 		mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
550 				src->viewport_width;
551 		mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] =
552 				src->viewport_width_c;
553 		mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
554 				src->viewport_height;
555 		mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] =
556 				src->viewport_height_c;
557 		mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
558 				src->viewport_y_y;
559 		mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
560 				src->viewport_y_c;
561 		mode_lib->vba.SourceRotation[mode_lib->vba.NumberOfActiveSurfaces] = src->source_rotation;
562 		mode_lib->vba.ViewportXStartY[mode_lib->vba.NumberOfActiveSurfaces] = src->viewport_x_y;
563 		mode_lib->vba.ViewportXStartC[mode_lib->vba.NumberOfActiveSurfaces] = src->viewport_x_c;
564 		// TODO: Assign correct value to viewport_stationary
565 		mode_lib->vba.ViewportStationary[mode_lib->vba.NumberOfActivePlanes] =
566 				src->viewport_stationary;
567 		mode_lib->vba.UsesMALLForPStateChange[mode_lib->vba.NumberOfActivePlanes] = src->use_mall_for_pstate_change;
568 		mode_lib->vba.UseMALLForStaticScreen[mode_lib->vba.NumberOfActivePlanes] = src->use_mall_for_static_screen;
569 		mode_lib->vba.GPUVMMinPageSizeKBytes[mode_lib->vba.NumberOfActivePlanes] = src->gpuvm_min_page_size_kbytes;
570 		mode_lib->vba.RefreshRate[mode_lib->vba.NumberOfActivePlanes] = dst->refresh_rate; //todo remove this
571 		mode_lib->vba.OutputLinkDPRate[mode_lib->vba.NumberOfActivePlanes] = dout->dp_rate;
572 		mode_lib->vba.ODMUse[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine_policy;
573 		mode_lib->vba.DETSizeOverride[mode_lib->vba.NumberOfActivePlanes] = src->det_size_override;
574 		//TODO: Need to assign correct values to dp_multistream vars
575 		mode_lib->vba.OutputMultistreamEn[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_en;
576 		mode_lib->vba.OutputMultistreamId[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_id;
577 		mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
578 		mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_y;
579 		mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_y;
580 		mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
581 		mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_c;
582 		mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_c;
583 		mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
584 		mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c;
585 		mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
586 		mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c;
587 		mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
588 		mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c;
589 		mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
590 		mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
591 		if (dst->interlaced && !ip->ptoi_supported) {
592 			mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
593 			mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
594 		}
595 		mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
596 		mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
597 		mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
598 		mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
599 		mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
600 		mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
601 		mode_lib->vba.VFrontPorch[mode_lib->vba.NumberOfActivePlanes] = dst->vfront_porch;
602 		mode_lib->vba.VBlankNom[mode_lib->vba.NumberOfActivePlanes] = dst->vblank_nom;
603 		mode_lib->vba.DCCFractionOfZeroSizeRequestsLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_luma;
604 		mode_lib->vba.DCCFractionOfZeroSizeRequestsChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_chroma;
605 		mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
606 				src->dcc_use_global ?
607 						ip->dcc_supported : src->dcc && ip->dcc_supported;
608 		mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
609 		/* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
610 		mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
611 		mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
612 		mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format);
613 		mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
614 		mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
615 		mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
616 				(enum dm_swizzle_mode) (src->sw_mode);
617 		mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
618 				dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
619 		mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
620 				dst->odm_combine;
621 		mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
622 				(enum output_format_class) (dout->output_format);
623 		mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
624 				dout->output_bpp;
625 		mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
626 				(enum output_encoder_class) (dout->output_type);
627 		mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
628 				dout->is_virtual;
629 
630 		if (dout->dsc_enable)
631 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
632 		else
633 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
634 
635 		mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
636 				dout->dp_lanes;
637 		/* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
638 		mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
639 			dout->max_audio_sample_rate;
640 		mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
641 			1;
642 		mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
643 		mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
644 		mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
645 		mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
646 				dout->dsc_slices;
647 		if (!dout->dsc_input_bpc) {
648 			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
649 				ip->maximum_dsc_bits_per_component;
650 		} else {
651 			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
652 				dout->dsc_input_bpc;
653 		}
654 		mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
655 		mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
656 				dout->num_active_wb;
657 		mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
658 				dout->wb.wb_src_height;
659 		mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
660 				dout->wb.wb_src_width;
661 		mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
662 				dout->wb.wb_dst_width;
663 		mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
664 				dout->wb.wb_dst_height;
665 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
666 				dout->wb.wb_hratio;
667 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
668 				dout->wb.wb_vratio;
669 		mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
670 				(enum source_format_class) (dout->wb.wb_pixel_format);
671 		mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
672 				dout->wb.wb_htaps_luma;
673 		mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
674 				dout->wb.wb_vtaps_luma;
675 		mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
676 				dout->wb.wb_htaps_luma;
677 		mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
678 				dout->wb.wb_vtaps_luma;
679 		mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
680 				dout->wb.wb_htaps_chroma;
681 		mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
682 				dout->wb.wb_vtaps_chroma;
683 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
684 				dout->wb.wb_hratio;
685 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
686 				dout->wb.wb_vratio;
687 
688 		mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
689 				src->dynamic_metadata_enable;
690 		mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
691 				src->dynamic_metadata_lines_before_active;
692 		mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
693 				src->dynamic_metadata_xmit_bytes;
694 
695 		mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
696 				&& ip->xfc_supported;
697 		mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
698 		mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
699 		mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
700 		mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
701 		mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
702 		mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
703 		mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
704 		mode_lib->vba.DRRDisplay[mode_lib->vba.NumberOfActiveSurfaces] = dst->drr_display;
705 		if (ip->is_line_buffer_bpp_fixed)
706 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
707 					ip->line_buffer_fixed_bpp;
708 		else {
709 			unsigned int lb_depth;
710 
711 			switch (scl->lb_depth) {
712 			case dm_lb_6:
713 				lb_depth = 18;
714 				break;
715 			case dm_lb_8:
716 				lb_depth = 24;
717 				break;
718 			case dm_lb_10:
719 				lb_depth = 30;
720 				break;
721 			case dm_lb_12:
722 				lb_depth = 36;
723 				break;
724 			case dm_lb_16:
725 				lb_depth = 48;
726 				break;
727 			case dm_lb_19:
728 				lb_depth = 57;
729 				break;
730 			default:
731 				lb_depth = 36;
732 			}
733 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
734 		}
735 		mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
736 		// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
737 		// calculate things a little more accurately
738 		for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
739 			switch (k) {
740 			case 0:
741 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
742 						CursorBppEnumToBits(
743 								(enum cursor_bpp) (src->cur0_bpp));
744 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
745 						src->cur0_src_width;
746 				if (src->cur0_src_width > 0)
747 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
748 				break;
749 			case 1:
750 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
751 						CursorBppEnumToBits(
752 								(enum cursor_bpp) (src->cur1_bpp));
753 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
754 						src->cur1_src_width;
755 				if (src->cur1_src_width > 0)
756 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
757 				break;
758 			default:
759 				dml_print(
760 						"ERROR: Number of cursors specified exceeds supported maximum\n")
761 				;
762 			}
763 		}
764 
765 		OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
766 
767 		if (j == 0)
768 			mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
769 		else
770 			mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
771 									|| dst->use_maximum_vstartup;
772 
773 		if (dst->odm_combine && !src->is_hsplit)
774 			dml_print(
775 					"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
776 					j);
777 
778 		if (src->is_hsplit) {
779 			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
780 				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
781 				display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
782 
783 				if (src_k->is_hsplit && !visited[k]
784 						&& src->hsplit_grp == src_k->hsplit_grp) {
785 					mode_lib->vba.pipe_plane[k] =
786 							mode_lib->vba.NumberOfActivePlanes;
787 					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
788 					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
789 							== dm_horz) {
790 						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
791 								src_k->viewport_width;
792 						mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
793 								src_k->viewport_width_c;
794 						mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
795 								dst_k->recout_width;
796 					} else {
797 						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
798 								src_k->viewport_height;
799 						mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
800 								src_k->viewport_height_c;
801 					}
802 
803 					visited[k] = true;
804 				}
805 			}
806 		}
807 		if (src->viewport_width_max) {
808 			int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
809 			int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
810 
811 			if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
812 				mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
813 			if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
814 				mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
815 			if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
816 				mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
817 			if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
818 				mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
819 		}
820 
821 		if (pipes[j].pipe.src.immediate_flip) {
822 			mode_lib->vba.ImmediateFlipSupport = true;
823 			mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_required;
824 		}
825 
826 		mode_lib->vba.NumberOfActivePlanes++;
827 		mode_lib->vba.NumberOfActiveSurfaces++;
828 	}
829 
830 	// handle overlays through BlendingAndTiming
831 	// BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
832 
833 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
834 		PlaneVisited[j] = false;
835 
836 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
837 		for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
838 			if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
839 				// doesn't matter, so choose the smaller one
840 				mode_lib->vba.BlendingAndTiming[j] = j;
841 				PlaneVisited[j] = true;
842 				mode_lib->vba.BlendingAndTiming[k] = j;
843 				PlaneVisited[k] = true;
844 			}
845 		}
846 
847 		if (!PlaneVisited[j]) {
848 			mode_lib->vba.BlendingAndTiming[j] = j;
849 			PlaneVisited[j] = true;
850 		}
851 	}
852 
853 	mode_lib->vba.SynchronizeTimingsFinal = pipes[0].pipe.dest.synchronize_timings;
854 	mode_lib->vba.DCCProgrammingAssumesScanDirectionUnknownFinal = false;
855 
856 	mode_lib->vba.DisableUnboundRequestIfCompBufReservedSpaceNeedAdjustment = 0;
857 
858 	mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting;
859 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
860 		if (pipes[k].pipe.src.unbounded_req_mode == 0)
861 			mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting_disable;
862 	}
863 	// TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
864 	// Do we want the dscclk to automatically be halved? Guess not since the value is specified
865 	mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
866 	for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
867 		ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
868 	}
869 
870 	mode_lib->vba.GPUVMEnable = false;
871 	mode_lib->vba.HostVMEnable = false;
872 	mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
873 	mode_lib->vba.OverrideHostVMPageTableLevels = 0;
874 
875 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
876 		mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
877 		mode_lib->vba.OverrideGPUVMPageTableLevels =
878 				(pipes[k].pipe.src.gpuvm_levels_force_en
879 						&& mode_lib->vba.OverrideGPUVMPageTableLevels
880 								< pipes[k].pipe.src.gpuvm_levels_force) ?
881 						pipes[k].pipe.src.gpuvm_levels_force :
882 						mode_lib->vba.OverrideGPUVMPageTableLevels;
883 
884 		mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
885 		mode_lib->vba.OverrideHostVMPageTableLevels =
886 				(pipes[k].pipe.src.hostvm_levels_force_en
887 						&& mode_lib->vba.OverrideHostVMPageTableLevels
888 								< pipes[k].pipe.src.hostvm_levels_force) ?
889 						pipes[k].pipe.src.hostvm_levels_force :
890 						mode_lib->vba.OverrideHostVMPageTableLevels;
891 	}
892 
893 	if (mode_lib->vba.OverrideGPUVMPageTableLevels)
894 		mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
895 
896 	if (mode_lib->vba.OverrideHostVMPageTableLevels)
897 		mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
898 
899 	mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
900 	mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
901 
902 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
903 		mode_lib->vba.ForceOneRowForFrame[k] = pipes[k].pipe.src.force_one_row_for_frame;
904 		mode_lib->vba.PteBufferMode[k] = pipes[k].pipe.src.pte_buffer_mode;
905 
906 		if (mode_lib->vba.PteBufferMode[k] == 0 && mode_lib->vba.GPUVMEnable) {
907 			if (mode_lib->vba.ForceOneRowForFrame[k] ||
908 				(mode_lib->vba.GPUVMMinPageSizeKBytes[k] > 64*1024) ||
909 				(mode_lib->vba.UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_disable) ||
910 				(mode_lib->vba.UseMALLForStaticScreen[k] != dm_use_mall_static_screen_disable)) {
911 #ifdef __DML_VBA_DEBUG__
912 				dml_print("DML::%s: ERROR: Invalid PteBufferMode=%d for plane %0d!\n",
913 						__func__, mode_lib->vba.PteBufferMode[k], k);
914 				dml_print("DML::%s:  -  ForceOneRowForFrame     = %d\n",
915 						__func__, mode_lib->vba.ForceOneRowForFrame[k]);
916 				dml_print("DML::%s:  -  GPUVMMinPageSizeKBytes  = %d\n",
917 						__func__, mode_lib->vba.GPUVMMinPageSizeKBytes[k]);
918 				dml_print("DML::%s:  -  UseMALLForPStateChange  = %d\n",
919 						__func__, (int) mode_lib->vba.UsesMALLForPStateChange[k]);
920 				dml_print("DML::%s:  -  UseMALLForStaticScreen  = %d\n",
921 						__func__, (int) mode_lib->vba.UseMALLForStaticScreen[k]);
922 #endif
923 				ASSERT(0);
924 			}
925 		}
926 	}
927 }
928 
929 /**
930  * ********************************************************************************************
931  * cache_debug_params: Cache any params that needed to be maintained from the initial validation
932  * for debug purposes.
933  *
934  * The DML getters can modify some of the VBA params that we are interested in (for example when
935  * calculating with dummy p-state latency), so cache any params here that we want for debugging
936  *
937  * @param [in] mode_lib: mode_lib input/output of validate call
938  *
939  * @return: void
940  *
941  * ********************************************************************************************
942  */
943 static void cache_debug_params(struct display_mode_lib *mode_lib)
944 {
945 	int k = 0;
946 
947 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
948 		mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
949 }
950 
951 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
952 // rather than working them out as in recalculate_ms
953 static void recalculate_params(
954 		struct display_mode_lib *mode_lib,
955 		const display_e2e_pipe_params_st *pipes,
956 		unsigned int num_pipes)
957 {
958 	// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
959 	if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
960 			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
961 			|| num_pipes != mode_lib->vba.cache_num_pipes
962 			|| memcmp(
963 					pipes,
964 					mode_lib->vba.cache_pipes,
965 					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
966 		mode_lib->vba.soc = mode_lib->soc;
967 		mode_lib->vba.ip = mode_lib->ip;
968 		memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
969 		mode_lib->vba.cache_num_pipes = num_pipes;
970 		mode_lib->funcs.recalculate(mode_lib);
971 	}
972 }
973 
974 void Calculate256BBlockSizes(
975 		enum source_format_class SourcePixelFormat,
976 		enum dm_swizzle_mode SurfaceTiling,
977 		unsigned int BytePerPixelY,
978 		unsigned int BytePerPixelC,
979 		unsigned int *BlockHeight256BytesY,
980 		unsigned int *BlockHeight256BytesC,
981 		unsigned int *BlockWidth256BytesY,
982 		unsigned int *BlockWidth256BytesC)
983 {
984 	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
985 			|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
986 		if (SurfaceTiling == dm_sw_linear) {
987 			*BlockHeight256BytesY = 1;
988 		} else if (SourcePixelFormat == dm_444_64) {
989 			*BlockHeight256BytesY = 4;
990 		} else if (SourcePixelFormat == dm_444_8) {
991 			*BlockHeight256BytesY = 16;
992 		} else {
993 			*BlockHeight256BytesY = 8;
994 		}
995 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
996 		*BlockHeight256BytesC = 0;
997 		*BlockWidth256BytesC = 0;
998 	} else {
999 		if (SurfaceTiling == dm_sw_linear) {
1000 			*BlockHeight256BytesY = 1;
1001 			*BlockHeight256BytesC = 1;
1002 		} else if (SourcePixelFormat == dm_420_8) {
1003 			*BlockHeight256BytesY = 16;
1004 			*BlockHeight256BytesC = 8;
1005 		} else {
1006 			*BlockHeight256BytesY = 8;
1007 			*BlockHeight256BytesC = 8;
1008 		}
1009 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
1010 		*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
1011 	}
1012 }
1013 
1014 bool CalculateMinAndMaxPrefetchMode(
1015 		enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
1016 		unsigned int *MinPrefetchMode,
1017 		unsigned int *MaxPrefetchMode)
1018 {
1019 	if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1020 			== dm_neither_self_refresh_nor_mclk_switch) {
1021 		*MinPrefetchMode = 2;
1022 		*MaxPrefetchMode = 2;
1023 		return false;
1024 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
1025 		*MinPrefetchMode = 1;
1026 		*MaxPrefetchMode = 1;
1027 		return false;
1028 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1029 			== dm_allow_self_refresh_and_mclk_switch) {
1030 		*MinPrefetchMode = 0;
1031 		*MaxPrefetchMode = 0;
1032 		return false;
1033 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1034 			== dm_try_to_allow_self_refresh_and_mclk_switch) {
1035 		*MinPrefetchMode = 0;
1036 		*MaxPrefetchMode = 2;
1037 		return false;
1038 	}
1039 	*MinPrefetchMode = 0;
1040 	*MaxPrefetchMode = 2;
1041 	return true;
1042 }
1043 
1044 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
1045 {
1046 	unsigned int k;
1047 
1048 	//Progressive To Interlace Unit Effect
1049 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1050 		mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
1051 		if (mode_lib->vba.Interlace[k] == 1
1052 				&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
1053 			mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
1054 		}
1055 	}
1056 }
1057 
1058 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
1059 {
1060 	switch (ebpp) {
1061 	case dm_cur_2bit:
1062 		return 2;
1063 	case dm_cur_32bit:
1064 		return 32;
1065 	case dm_cur_64bit:
1066 		return 64;
1067 	default:
1068 		return 0;
1069 	}
1070 }
1071 
1072 void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
1073 {
1074 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
1075 	unsigned int k;
1076 	unsigned int total_pipes = 0;
1077 	unsigned int pipe_idx = 0;
1078 
1079 	mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
1080 	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
1081 	if (mode_lib->vba.ReturnBW == 0)
1082 		mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
1083 	mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
1084 
1085 	fetch_socbb_params(mode_lib);
1086 	fetch_ip_params(mode_lib);
1087 	fetch_pipe_params(mode_lib);
1088 
1089 	mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
1090 	mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
1091 	if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
1092 		mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
1093 	else
1094 		mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
1095 
1096 	// Total Available Pipes Support Check
1097 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1098 		total_pipes += mode_lib->vba.DPPPerPlane[k];
1099 		pipe_idx = get_pipe_idx(mode_lib, k);
1100 		if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0)
1101 			mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz;
1102 		else
1103 			mode_lib->vba.DPPCLK[k] = soc->clock_limits[mode_lib->vba.VoltageLevel].dppclk_mhz;
1104 	}
1105 	ASSERT(total_pipes <= DC__NUM_DPP__MAX);
1106 }
1107 
1108 double CalculateWriteBackDISPCLK(
1109 		enum source_format_class WritebackPixelFormat,
1110 		double PixelClock,
1111 		double WritebackHRatio,
1112 		double WritebackVRatio,
1113 		unsigned int WritebackLumaHTaps,
1114 		unsigned int WritebackLumaVTaps,
1115 		unsigned int WritebackChromaHTaps,
1116 		unsigned int WritebackChromaVTaps,
1117 		double WritebackDestinationWidth,
1118 		unsigned int HTotal,
1119 		unsigned int WritebackChromaLineBufferWidth)
1120 {
1121 	double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
1122 		dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
1123 		dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
1124 			+ dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
1125 			* (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
1126 			dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
1127 	if (WritebackPixelFormat != dm_444_32) {
1128 		CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
1129 			dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
1130 			dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
1131 				+ dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
1132 				+ dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
1133 				dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
1134 	}
1135 	return CalculateWriteBackDISPCLK;
1136 }
1137 
1138