1 /*	$NetBSD: amdgpu_display_mode_vba.c,v 1.2 2021/12/18 23:45:04 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2017 Advanced Micro Devices, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: AMD
25  *
26  */
27 
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: amdgpu_display_mode_vba.c,v 1.2 2021/12/18 23:45:04 riastradh Exp $");
31 
32 #include "display_mode_lib.h"
33 #include "display_mode_vba.h"
34 #include "dml_inline_defs.h"
35 
36 /*
37  * NOTE:
38  *   This file is gcc-parsable HW gospel, coming straight from HW engineers.
39  *
40  * It doesn't adhere to Linux kernel style and sometimes will do things in odd
41  * ways. Unless there is something clearly wrong with it the code should
42  * remain as-is as it provides us with a guarantee from HW that it is correct.
43  */
44 
45 
46 static void fetch_socbb_params(struct display_mode_lib *mode_lib);
47 static void fetch_ip_params(struct display_mode_lib *mode_lib);
48 static void fetch_pipe_params(struct display_mode_lib *mode_lib);
49 static void recalculate_params(
50 		struct display_mode_lib *mode_lib,
51 		const display_e2e_pipe_params_st *pipes,
52 		unsigned int num_pipes);
53 
54 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
55 
dml_get_voltage_level(struct display_mode_lib * mode_lib,const display_e2e_pipe_params_st * pipes,unsigned int num_pipes)56 unsigned int dml_get_voltage_level(
57 		struct display_mode_lib *mode_lib,
58 		const display_e2e_pipe_params_st *pipes,
59 		unsigned int num_pipes)
60 {
61 	bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
62 			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
63 			|| num_pipes != mode_lib->vba.cache_num_pipes
64 			|| memcmp(pipes, mode_lib->vba.cache_pipes,
65 					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
66 
67 	mode_lib->vba.soc = mode_lib->soc;
68 	mode_lib->vba.ip = mode_lib->ip;
69 	memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
70 	mode_lib->vba.cache_num_pipes = num_pipes;
71 
72 	if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
73 		mode_lib->funcs.recalculate(mode_lib);
74 	else {
75 		fetch_socbb_params(mode_lib);
76 		fetch_ip_params(mode_lib);
77 		fetch_pipe_params(mode_lib);
78 		PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
79 	}
80 	mode_lib->funcs.validate(mode_lib);
81 
82 	return mode_lib->vba.VoltageLevel;
83 }
84 
85 #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) \
86 { \
87 	recalculate_params(mode_lib, pipes, num_pipes); \
88 	return var; \
89 }
90 
91 dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFCLKDeepSleep);
92 dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
93 dml_get_attr_func(wm_memory_trip, mode_lib->vba.UrgentLatency);
94 dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
95 dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
96 dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
97 dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
98 dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
99 dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent
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(urgent_latency, mode_lib->vba.UrgentLatency);
103 dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
104 dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
105 dml_get_attr_func(
106 		dram_clock_change_latency,
107 		mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
108 dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
109 dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
110 dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
111 dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
112 dml_get_attr_func(fraction_of_urgent_bandwidth, mode_lib->vba.FractionOfUrgentBandwidth);
113 dml_get_attr_func(fraction_of_urgent_bandwidth_imm_flip, mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip);
114 
115 #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) \
116 {\
117 	unsigned int which_plane; \
118 	recalculate_params(mode_lib, pipes, num_pipes); \
119 	which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
120 	return var[which_plane]; \
121 }
122 
123 dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
124 dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
125 dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
126 dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
127 dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
128 dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
129 dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
130 dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
131 dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
132 dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
133 dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
134 dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
135 dml_get_pipe_attr_func(
136 		dst_y_per_row_flip,
137 		mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
138 
139 dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay);
140 dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay);
141 dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency);
142 dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin);
143 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank, mode_lib->vba.TimePerVMGroupVBlank);
144 dml_get_pipe_attr_func(refcyc_per_vm_group_flip, mode_lib->vba.TimePerVMGroupFlip);
145 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank, mode_lib->vba.TimePerVMRequestVBlank);
146 dml_get_pipe_attr_func(refcyc_per_vm_req_flip, mode_lib->vba.TimePerVMRequestFlip);
147 
get_vstartup_calculated(struct display_mode_lib * mode_lib,const display_e2e_pipe_params_st * pipes,unsigned int num_pipes,unsigned int which_pipe)148 unsigned int get_vstartup_calculated(
149 		struct display_mode_lib *mode_lib,
150 		const display_e2e_pipe_params_st *pipes,
151 		unsigned int num_pipes,
152 		unsigned int which_pipe)
153 {
154 	unsigned int which_plane;
155 
156 	recalculate_params(mode_lib, pipes, num_pipes);
157 	which_plane = mode_lib->vba.pipe_plane[which_pipe];
158 	return mode_lib->vba.VStartup[which_plane];
159 }
160 
get_total_immediate_flip_bytes(struct display_mode_lib * mode_lib,const display_e2e_pipe_params_st * pipes,unsigned int num_pipes)161 double get_total_immediate_flip_bytes(
162 		struct display_mode_lib *mode_lib,
163 		const display_e2e_pipe_params_st *pipes,
164 		unsigned int num_pipes)
165 {
166 	recalculate_params(mode_lib, pipes, num_pipes);
167 	return mode_lib->vba.TotImmediateFlipBytes;
168 }
169 
get_total_immediate_flip_bw(struct display_mode_lib * mode_lib,const display_e2e_pipe_params_st * pipes,unsigned int num_pipes)170 double get_total_immediate_flip_bw(
171 		struct display_mode_lib *mode_lib,
172 		const display_e2e_pipe_params_st *pipes,
173 		unsigned int num_pipes)
174 {
175 	unsigned int k;
176 	double immediate_flip_bw = 0.0;
177 	recalculate_params(mode_lib, pipes, num_pipes);
178 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
179 		immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k];
180 	return immediate_flip_bw;
181 }
182 
get_total_prefetch_bw(struct display_mode_lib * mode_lib,const display_e2e_pipe_params_st * pipes,unsigned int num_pipes)183 double get_total_prefetch_bw(
184 		struct display_mode_lib *mode_lib,
185 		const display_e2e_pipe_params_st *pipes,
186 		unsigned int num_pipes)
187 {
188 	unsigned int k;
189 	double total_prefetch_bw = 0.0;
190 
191 	recalculate_params(mode_lib, pipes, num_pipes);
192 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
193 		total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
194 	return total_prefetch_bw;
195 }
196 
fetch_socbb_params(struct display_mode_lib * mode_lib)197 static void fetch_socbb_params(struct display_mode_lib *mode_lib)
198 {
199 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
200 	int i;
201 
202 	// SOC Bounding Box Parameters
203 	mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
204 	mode_lib->vba.NumberOfChannels = soc->num_chans;
205 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly =
206 			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!
207 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData =
208 			soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
209 	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly =
210 			soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
211 	mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation =
212 			soc->max_avg_sdp_bw_use_normal_percent;
213 	mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation =
214 			soc->max_avg_dram_bw_use_normal_percent;
215 	mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us;
216 	mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us;
217 	mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us;
218 	mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
219 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly =
220 			soc->urgent_out_of_order_return_per_channel_pixel_only_bytes;
221 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData =
222 			soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
223 	mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly =
224 			soc->urgent_out_of_order_return_per_channel_vm_only_bytes;
225 	mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
226 	mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
227 	mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
228 	mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
229 	mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
230 	mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
231 			mode_lib->vba.DummyPStateCheck;
232 
233 	mode_lib->vba.Downspreading = soc->downspread_percent;
234 	mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes;   // new!
235 	mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
236 	mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent;   // new
237 	mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz;   // new
238 	mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
239 	mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024;
240 	mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024;
241 	// Set the voltage scaling clocks as the defaults. Most of these will
242 	// be set to different values by the test
243 	for (i = 0; i < mode_lib->vba.soc.num_states; i++)
244 		if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
245 			break;
246 
247 	mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
248 	mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
249 	mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts;
250 	mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
251 
252 	mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
253 	mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
254 	mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw;
255 
256 	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
257 	mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
258 	mode_lib->vba.MaxHSCLRatio = 4;
259 	mode_lib->vba.MaxVSCLRatio = 4;
260 	mode_lib->vba.Cursor64BppSupport = true;
261 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
262 		mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
263 		mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
264 		mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
265 		mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
266 		mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz;
267 		mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
268 		mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
269 		mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts;
270 		//mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
271 		mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
272 		mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz;
273 	}
274 	mode_lib->vba.MinVoltageLevel = 0;
275 	mode_lib->vba.MaxVoltageLevel = mode_lib->vba.soc.num_states;
276 
277 	mode_lib->vba.DoUrgentLatencyAdjustment =
278 		soc->do_urgent_latency_adjustment;
279 	mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent =
280 		soc->urgent_latency_adjustment_fabric_clock_component_us;
281 	mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
282 		soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
283 }
284 
fetch_ip_params(struct display_mode_lib * mode_lib)285 static void fetch_ip_params(struct display_mode_lib *mode_lib)
286 {
287 	ip_params_st *ip = &mode_lib->vba.ip;
288 
289 	// IP Parameters
290 	mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
291 	mode_lib->vba.MaxNumOTG = ip->max_num_otg;
292 	mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
293 	mode_lib->vba.MaxNumWriteback = ip->max_num_wb;
294 	mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
295 	mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
296 
297 	mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
298 	mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
299 	mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
300 	mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
301 	mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
302 	mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
303 	mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
304 	mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
305 	mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
306 	mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma;
307 	mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma;
308 	mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
309 	mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
310 	mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio;
311 	mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio;
312 	mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024;
313 	mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024;
314 
315 	mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes;
316 	mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size;
317 
318 	mode_lib->vba.WritebackChromaLineBufferWidth =
319 			ip->writeback_chroma_line_buffer_width_pixels;
320 	mode_lib->vba.WritebackLineBufferLumaBufferSize =
321 			ip->writeback_line_buffer_luma_buffer_size;
322 	mode_lib->vba.WritebackLineBufferChromaBufferSize =
323 			ip->writeback_line_buffer_chroma_buffer_size;
324 	mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported;
325 	mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio;
326 	mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio;
327 	mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio;
328 	mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio;
329 	mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps;
330 	mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps;
331 	mode_lib->vba.WritebackConfiguration = dm_normal;
332 	mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels;
333 	mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels;
334 	mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels;
335 	mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels;
336 	mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
337 	mode_lib->vba.NumberOfDSC = ip->num_dsc;
338 	mode_lib->vba.ODMCapability = ip->odm_capable;
339 	mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
340 
341 	mode_lib->vba.XFCSupported = ip->xfc_supported;
342 	mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
343 	mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
344 	mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
345 	mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
346 	mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
347 	mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
348 	mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
349 	mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
350 	mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled;
351 	mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported;
352 	mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
353 	mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
354 	mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes;
355 	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported;
356 }
357 
fetch_pipe_params(struct display_mode_lib * mode_lib)358 static void fetch_pipe_params(struct display_mode_lib *mode_lib)
359 {
360 	display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
361 	ip_params_st *ip = &mode_lib->vba.ip;
362 
363 	unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
364 	unsigned int j, k;
365 	bool PlaneVisited[DC__NUM_DPP__MAX];
366 	bool visited[DC__NUM_DPP__MAX];
367 
368 	// Convert Pipes to Planes
369 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
370 		visited[k] = false;
371 
372 	mode_lib->vba.NumberOfActivePlanes = 0;
373 	for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
374 		display_pipe_source_params_st *src = &pipes[j].pipe.src;
375 		display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
376 		scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
377 		scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
378 		display_output_params_st *dout = &pipes[j].dout;
379 		display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
380 
381 		if (visited[j])
382 			continue;
383 		visited[j] = true;
384 
385 		mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
386 
387 		mode_lib->vba.EmbeddedPanel[mode_lib->vba.NumberOfActivePlanes] = dst->embedded;
388 		mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
389 		mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
390 				(enum scan_direction_class) (src->source_scan);
391 		mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
392 				src->viewport_width;
393 		mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] =
394 				src->viewport_width_c;
395 		mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
396 				src->viewport_height;
397 		mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] =
398 				src->viewport_height_c;
399 		mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
400 				src->viewport_y_y;
401 		mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
402 				src->viewport_y_c;
403 		mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
404 		mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height;
405 		mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width;
406 		mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
407 		mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_c;
408 		mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_c;
409 		mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
410 		mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c;
411 		mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
412 		mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c;
413 		mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
414 		mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c;
415 		mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
416 		mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
417 		if (dst->interlaced && !ip->ptoi_supported) {
418 			mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
419 			mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
420 		}
421 		mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
422 		mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
423 		mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
424 		mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
425 		mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
426 		mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
427 		mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
428 				src->dcc_use_global ?
429 						ip->dcc_supported : src->dcc && ip->dcc_supported;
430 		mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
431 		/* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
432 		mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
433 		mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
434 
435 		mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] =
436 				(enum source_format_class) (src->source_format);
437 		mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
438 		mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
439 		mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
440 				(enum dm_swizzle_mode) (src->sw_mode);
441 		mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
442 				dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
443 		mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
444 				dst->odm_combine;
445 		mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
446 				(enum output_format_class) (dout->output_format);
447 		mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
448 				dout->output_bpp;
449 		mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
450 				(enum output_encoder_class) (dout->output_type);
451 
452 		if (!dout->dsc_enable)
453 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
454 		else
455 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
456 
457 		mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
458 				dout->dp_lanes;
459 		/* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
460 		mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
461 			dout->max_audio_sample_rate;
462 		mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
463 			1;
464 		mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
465 		mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
466 		mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
467 				dout->dsc_slices;
468 		mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
469 				dout->output_bpc == 0 ? 12 : dout->output_bpc;
470 		mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
471 		mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
472 				dout->num_active_wb;
473 		mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
474 				dout->wb.wb_src_height;
475 		mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
476 				dout->wb.wb_src_width;
477 		mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
478 				dout->wb.wb_dst_width;
479 		mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
480 				dout->wb.wb_dst_height;
481 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
482 				dout->wb.wb_hratio;
483 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
484 				dout->wb.wb_vratio;
485 		mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
486 				(enum source_format_class) (dout->wb.wb_pixel_format);
487 		mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
488 				dout->wb.wb_htaps_luma;
489 		mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
490 				dout->wb.wb_vtaps_luma;
491 		mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
492 				dout->wb.wb_htaps_luma;
493 		mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
494 				dout->wb.wb_vtaps_luma;
495 		mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
496 				dout->wb.wb_htaps_chroma;
497 		mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
498 				dout->wb.wb_vtaps_chroma;
499 		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
500 				dout->wb.wb_hratio;
501 		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
502 				dout->wb.wb_vratio;
503 
504 		mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
505 				src->dynamic_metadata_enable;
506 		mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
507 				src->dynamic_metadata_lines_before_active;
508 		mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
509 				src->dynamic_metadata_xmit_bytes;
510 
511 		mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
512 				&& ip->xfc_supported;
513 		mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
514 		mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
515 		mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
516 		mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
517 		mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
518 		mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
519 		mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
520 		if (ip->is_line_buffer_bpp_fixed)
521 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
522 					ip->line_buffer_fixed_bpp;
523 		else {
524 			unsigned int lb_depth;
525 
526 			switch (scl->lb_depth) {
527 			case dm_lb_6:
528 				lb_depth = 18;
529 				break;
530 			case dm_lb_8:
531 				lb_depth = 24;
532 				break;
533 			case dm_lb_10:
534 				lb_depth = 30;
535 				break;
536 			case dm_lb_12:
537 				lb_depth = 36;
538 				break;
539 			case dm_lb_16:
540 				lb_depth = 48;
541 				break;
542 			case dm_lb_19:
543 				lb_depth = 57;
544 				break;
545 			default:
546 				lb_depth = 36;
547 			}
548 			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
549 		}
550 		mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
551 		// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
552 		// calculate things a little more accurately
553 		for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
554 			switch (k) {
555 			case 0:
556 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
557 						CursorBppEnumToBits(
558 								(enum cursor_bpp) (src->cur0_bpp));
559 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
560 						src->cur0_src_width;
561 				if (src->cur0_src_width > 0)
562 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
563 				break;
564 			case 1:
565 				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
566 						CursorBppEnumToBits(
567 								(enum cursor_bpp) (src->cur1_bpp));
568 				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
569 						src->cur1_src_width;
570 				if (src->cur1_src_width > 0)
571 					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
572 				break;
573 			default:
574 				dml_print(
575 						"ERROR: Number of cursors specified exceeds supported maximum\n")
576 				;
577 			}
578 		}
579 
580 		OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
581 
582 		if (j == 0)
583 			mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
584 		else
585 			mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
586 									|| dst->use_maximum_vstartup;
587 
588 		if (dst->odm_combine && !src->is_hsplit)
589 			dml_print(
590 					"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
591 					j);
592 
593 		if (src->is_hsplit) {
594 			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
595 				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
596 				display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
597 				display_output_params_st *dout_k = &pipes[j].dout;
598 
599 				if (src_k->is_hsplit && !visited[k]
600 						&& src->hsplit_grp == src_k->hsplit_grp) {
601 					mode_lib->vba.pipe_plane[k] =
602 							mode_lib->vba.NumberOfActivePlanes;
603 					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
604 					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
605 							== dm_horz) {
606 						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
607 								src_k->viewport_width;
608 						mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
609 								src_k->viewport_width;
610 						mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
611 								dst_k->recout_width;
612 					} else {
613 						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
614 								src_k->viewport_height;
615 						mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
616 								src_k->viewport_height;
617 					}
618 					mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] +=
619 							dout_k->dsc_slices;
620 
621 					visited[k] = true;
622 				}
623 			}
624 		}
625 
626 		if (pipes[k].pipe.src.immediate_flip)
627 			mode_lib->vba.ImmediateFlipSupport = true;
628 
629 		mode_lib->vba.NumberOfActivePlanes++;
630 	}
631 
632 	// handle overlays through BlendingAndTiming
633 	// BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
634 
635 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
636 		PlaneVisited[j] = false;
637 
638 	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
639 		for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
640 			if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
641 				// doesn't matter, so choose the smaller one
642 				mode_lib->vba.BlendingAndTiming[j] = j;
643 				PlaneVisited[j] = true;
644 				mode_lib->vba.BlendingAndTiming[k] = j;
645 				PlaneVisited[k] = true;
646 			}
647 		}
648 
649 		if (!PlaneVisited[j]) {
650 			mode_lib->vba.BlendingAndTiming[j] = j;
651 			PlaneVisited[j] = true;
652 		}
653 	}
654 
655 	// TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
656 	// Do we want the dscclk to automatically be halved? Guess not since the value is specified
657 
658 	mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
659 	for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k)
660 		ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
661 
662 	mode_lib->vba.GPUVMEnable = false;
663 	mode_lib->vba.HostVMEnable = false;
664 	mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
665 	mode_lib->vba.OverrideHostVMPageTableLevels = 0;
666 
667 	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
668 		mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
669 		mode_lib->vba.OverrideGPUVMPageTableLevels =
670 				(pipes[k].pipe.src.gpuvm_levels_force_en
671 						&& mode_lib->vba.OverrideGPUVMPageTableLevels
672 								< pipes[k].pipe.src.gpuvm_levels_force) ?
673 						pipes[k].pipe.src.gpuvm_levels_force :
674 						mode_lib->vba.OverrideGPUVMPageTableLevels;
675 
676 		mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
677 		mode_lib->vba.OverrideHostVMPageTableLevels =
678 				(pipes[k].pipe.src.hostvm_levels_force_en
679 						&& mode_lib->vba.OverrideHostVMPageTableLevels
680 								< pipes[k].pipe.src.hostvm_levels_force) ?
681 						pipes[k].pipe.src.hostvm_levels_force :
682 						mode_lib->vba.OverrideHostVMPageTableLevels;
683 	}
684 
685 	mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank = dm_try_to_allow_self_refresh_and_mclk_switch;
686 
687 	if (mode_lib->vba.OverrideGPUVMPageTableLevels)
688 		mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
689 
690 	if (mode_lib->vba.OverrideHostVMPageTableLevels)
691 		mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
692 
693 	mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
694 	mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
695 }
696 
697 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
698 // rather than working them out as in recalculate_ms
recalculate_params(struct display_mode_lib * mode_lib,const display_e2e_pipe_params_st * pipes,unsigned int num_pipes)699 static void recalculate_params(
700 		struct display_mode_lib *mode_lib,
701 		const display_e2e_pipe_params_st *pipes,
702 		unsigned int num_pipes)
703 {
704 	// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
705 	if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
706 			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
707 			|| num_pipes != mode_lib->vba.cache_num_pipes
708 			|| memcmp(
709 					pipes,
710 					mode_lib->vba.cache_pipes,
711 					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
712 		mode_lib->vba.soc = mode_lib->soc;
713 		mode_lib->vba.ip = mode_lib->ip;
714 		memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
715 		mode_lib->vba.cache_num_pipes = num_pipes;
716 		mode_lib->funcs.recalculate(mode_lib);
717 	}
718 }
719 
Calculate256BBlockSizes(enum source_format_class SourcePixelFormat,enum dm_swizzle_mode SurfaceTiling,unsigned int BytePerPixelY,unsigned int BytePerPixelC,unsigned int * BlockHeight256BytesY,unsigned int * BlockHeight256BytesC,unsigned int * BlockWidth256BytesY,unsigned int * BlockWidth256BytesC)720 bool Calculate256BBlockSizes(
721 		enum source_format_class SourcePixelFormat,
722 		enum dm_swizzle_mode SurfaceTiling,
723 		unsigned int BytePerPixelY,
724 		unsigned int BytePerPixelC,
725 		unsigned int *BlockHeight256BytesY,
726 		unsigned int *BlockHeight256BytesC,
727 		unsigned int *BlockWidth256BytesY,
728 		unsigned int *BlockWidth256BytesC)
729 {
730 	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
731 			|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
732 		if (SurfaceTiling == dm_sw_linear) {
733 			*BlockHeight256BytesY = 1;
734 		} else if (SourcePixelFormat == dm_444_64) {
735 			*BlockHeight256BytesY = 4;
736 		} else if (SourcePixelFormat == dm_444_8) {
737 			*BlockHeight256BytesY = 16;
738 		} else {
739 			*BlockHeight256BytesY = 8;
740 		}
741 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
742 		*BlockHeight256BytesC = 0;
743 		*BlockWidth256BytesC = 0;
744 	} else {
745 		if (SurfaceTiling == dm_sw_linear) {
746 			*BlockHeight256BytesY = 1;
747 			*BlockHeight256BytesC = 1;
748 		} else if (SourcePixelFormat == dm_420_8) {
749 			*BlockHeight256BytesY = 16;
750 			*BlockHeight256BytesC = 8;
751 		} else {
752 			*BlockHeight256BytesY = 8;
753 			*BlockHeight256BytesC = 8;
754 		}
755 		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
756 		*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
757 	}
758 	return true;
759 }
760 
CalculateMinAndMaxPrefetchMode(enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,unsigned int * MinPrefetchMode,unsigned int * MaxPrefetchMode)761 bool CalculateMinAndMaxPrefetchMode(
762 		enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
763 		unsigned int *MinPrefetchMode,
764 		unsigned int *MaxPrefetchMode)
765 {
766 	if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
767 			== dm_neither_self_refresh_nor_mclk_switch) {
768 		*MinPrefetchMode = 2;
769 		*MaxPrefetchMode = 2;
770 		return false;
771 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
772 		*MinPrefetchMode = 1;
773 		*MaxPrefetchMode = 1;
774 		return false;
775 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
776 			== dm_allow_self_refresh_and_mclk_switch) {
777 		*MinPrefetchMode = 0;
778 		*MaxPrefetchMode = 0;
779 		return false;
780 	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
781 			== dm_try_to_allow_self_refresh_and_mclk_switch) {
782 		*MinPrefetchMode = 0;
783 		*MaxPrefetchMode = 2;
784 		return false;
785 	}
786 	*MinPrefetchMode = 0;
787 	*MaxPrefetchMode = 2;
788 	return true;
789 }
790 
PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib * mode_lib)791 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
792 {
793 	unsigned int k;
794 
795 	//Progressive To Interlace Unit Effect
796 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
797 		if (mode_lib->vba.Interlace[k] == 1
798 				&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
799 			mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClockBackEnd[k];
800 		}
801 	}
802 }
803 
CursorBppEnumToBits(enum cursor_bpp ebpp)804 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
805 {
806 	switch (ebpp) {
807 	case dm_cur_2bit:
808 		return 2;
809 	case dm_cur_32bit:
810 		return 32;
811 	case dm_cur_64bit:
812 		return 64;
813 	default:
814 		return 0;
815 	}
816 }
817 
ModeSupportAndSystemConfiguration(struct display_mode_lib * mode_lib)818 void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
819 {
820 	soc_bounding_box_st *soc = &mode_lib->vba.soc;
821 	unsigned int k;
822 	unsigned int total_pipes = 0;
823 
824 	mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
825 	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
826 	if (mode_lib->vba.ReturnBW == 0)
827 		mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
828 	mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
829 
830 	fetch_socbb_params(mode_lib);
831 	fetch_ip_params(mode_lib);
832 	fetch_pipe_params(mode_lib);
833 
834 	mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
835 	mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
836 	if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
837 		mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
838 	else
839 		mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
840 
841 	// Total Available Pipes Support Check
842 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
843 		total_pipes += mode_lib->vba.DPPPerPlane[k];
844 	ASSERT(total_pipes <= DC__NUM_DPP__MAX);
845 }
846 
CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat,double PixelClock,double WritebackHRatio,double WritebackVRatio,unsigned int WritebackLumaHTaps,unsigned int WritebackLumaVTaps,unsigned int WritebackChromaHTaps,unsigned int WritebackChromaVTaps,double WritebackDestinationWidth,unsigned int HTotal,unsigned int WritebackChromaLineBufferWidth)847 double CalculateWriteBackDISPCLK(
848 		enum source_format_class WritebackPixelFormat,
849 		double PixelClock,
850 		double WritebackHRatio,
851 		double WritebackVRatio,
852 		unsigned int WritebackLumaHTaps,
853 		unsigned int WritebackLumaVTaps,
854 		unsigned int WritebackChromaHTaps,
855 		unsigned int WritebackChromaVTaps,
856 		double WritebackDestinationWidth,
857 		unsigned int HTotal,
858 		unsigned int WritebackChromaLineBufferWidth)
859 {
860 	double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
861 		dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
862 		dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
863 			+ dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
864 			* (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
865 			dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
866 	if (WritebackPixelFormat != dm_444_32) {
867 		CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
868 			dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
869 			dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
870 				+ dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
871 				+ dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
872 				dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
873 	}
874 	return CalculateWriteBackDISPCLK;
875 }
876 
877