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