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