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