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