Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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#include "display_mode_lib.h"
27#include "display_mode_vba.h"
28
29#include "dml_inline_defs.h"
30
31/*
32 * NOTE:
33 * This file is gcc-parseable 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#define BPP_INVALID 0
41#define BPP_BLENDED_PIPE 0xffffffff
42static const unsigned int NumberOfStates = DC__VOLTAGE_STATES;
43
44static void fetch_socbb_params(struct display_mode_lib *mode_lib);
45static void fetch_ip_params(struct display_mode_lib *mode_lib);
46static void fetch_pipe_params(struct display_mode_lib *mode_lib);
47static void recalculate_params(
48 struct display_mode_lib *mode_lib,
49 const display_e2e_pipe_params_st *pipes,
50 unsigned int num_pipes);
51static void recalculate(struct display_mode_lib *mode_lib);
52static double adjust_ReturnBW(
53 struct display_mode_lib *mode_lib,
54 double ReturnBW,
55 bool DCCEnabledAnyPlane,
56 double ReturnBandwidthToDCN);
57static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
58static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
59static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
60 struct display_mode_lib *mode_lib);
61static unsigned int dscceComputeDelay(
62 unsigned int bpc,
63 double bpp,
64 unsigned int sliceWidth,
65 unsigned int numSlices,
66 enum output_format_class pixelFormat);
67static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
68// Super monster function with some 45 argument
69static bool CalculatePrefetchSchedule(
70 struct display_mode_lib *mode_lib,
71 double DPPCLK,
72 double DISPCLK,
73 double PixelClock,
74 double DCFClkDeepSleep,
75 unsigned int DSCDelay,
76 unsigned int DPPPerPlane,
77 bool ScalerEnabled,
78 unsigned int NumberOfCursors,
79 double DPPCLKDelaySubtotal,
80 double DPPCLKDelaySCL,
81 double DPPCLKDelaySCLLBOnly,
82 double DPPCLKDelayCNVCFormater,
83 double DPPCLKDelayCNVCCursor,
84 double DISPCLKDelaySubtotal,
85 unsigned int ScalerRecoutWidth,
86 enum output_format_class OutputFormat,
87 unsigned int VBlank,
88 unsigned int HTotal,
89 unsigned int MaxInterDCNTileRepeaters,
90 unsigned int VStartup,
91 unsigned int PageTableLevels,
92 bool VirtualMemoryEnable,
93 bool DynamicMetadataEnable,
94 unsigned int DynamicMetadataLinesBeforeActiveRequired,
95 unsigned int DynamicMetadataTransmittedBytes,
96 bool DCCEnable,
97 double UrgentLatency,
98 double UrgentExtraLatency,
99 double TCalc,
100 unsigned int PDEAndMetaPTEBytesFrame,
101 unsigned int MetaRowByte,
102 unsigned int PixelPTEBytesPerRow,
103 double PrefetchSourceLinesY,
104 unsigned int SwathWidthY,
105 double BytePerPixelDETY,
106 double VInitPreFillY,
107 unsigned int MaxNumSwathY,
108 double PrefetchSourceLinesC,
109 double BytePerPixelDETC,
110 double VInitPreFillC,
111 unsigned int MaxNumSwathC,
112 unsigned int SwathHeightY,
113 unsigned int SwathHeightC,
114 double TWait,
115 bool XFCEnabled,
116 double XFCRemoteSurfaceFlipDelay,
117 bool InterlaceEnable,
118 bool ProgressiveToInterlaceUnitInOPP,
119 double *DSTXAfterScaler,
120 double *DSTYAfterScaler,
121 double *DestinationLinesForPrefetch,
122 double *PrefetchBandwidth,
123 double *DestinationLinesToRequestVMInVBlank,
124 double *DestinationLinesToRequestRowInVBlank,
125 double *VRatioPrefetchY,
126 double *VRatioPrefetchC,
127 double *RequiredPrefetchPixDataBW,
128 unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
129 double *Tno_bw,
130 unsigned int *VUpdateOffsetPix,
131 unsigned int *VUpdateWidthPix,
132 unsigned int *VReadyOffsetPix);
133static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
134static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
135static double CalculatePrefetchSourceLines(
136 struct display_mode_lib *mode_lib,
137 double VRatio,
138 double vtaps,
139 bool Interlace,
140 bool ProgressiveToInterlaceUnitInOPP,
141 unsigned int SwathHeight,
142 unsigned int ViewportYStart,
143 double *VInitPreFill,
144 unsigned int *MaxNumSwath);
145static unsigned int CalculateVMAndRowBytes(
146 struct display_mode_lib *mode_lib,
147 bool DCCEnable,
148 unsigned int BlockHeight256Bytes,
149 unsigned int BlockWidth256Bytes,
150 enum source_format_class SourcePixelFormat,
151 unsigned int SurfaceTiling,
152 unsigned int BytePerPixel,
153 enum scan_direction_class ScanDirection,
154 unsigned int ViewportWidth,
155 unsigned int ViewportHeight,
156 unsigned int SwathWidthY,
157 bool VirtualMemoryEnable,
158 unsigned int VMMPageSize,
159 unsigned int PTEBufferSizeInRequests,
160 unsigned int PDEProcessingBufIn64KBReqs,
161 unsigned int Pitch,
162 unsigned int DCCMetaPitch,
163 unsigned int *MacroTileWidth,
164 unsigned int *MetaRowByte,
165 unsigned int *PixelPTEBytesPerRow,
166 bool *PTEBufferSizeNotExceeded,
167 unsigned int *dpte_row_height,
168 unsigned int *meta_row_height);
169static double CalculateTWait(
170 unsigned int PrefetchMode,
171 double DRAMClockChangeLatency,
172 double UrgentLatency,
173 double SREnterPlusExitTime);
174static double CalculateRemoteSurfaceFlipDelay(
175 struct display_mode_lib *mode_lib,
176 double VRatio,
177 double SwathWidth,
178 double Bpp,
179 double LineTime,
180 double XFCTSlvVupdateOffset,
181 double XFCTSlvVupdateWidth,
182 double XFCTSlvVreadyOffset,
183 double XFCXBUFLatencyTolerance,
184 double XFCFillBWOverhead,
185 double XFCSlvChunkSize,
186 double XFCBusTransportTime,
187 double TCalc,
188 double TWait,
189 double *SrcActiveDrainRate,
190 double *TInitXFill,
191 double *TslvChk);
192static double CalculateWriteBackDISPCLK(
193 enum source_format_class WritebackPixelFormat,
194 double PixelClock,
195 double WritebackHRatio,
196 double WritebackVRatio,
197 unsigned int WritebackLumaHTaps,
198 unsigned int WritebackLumaVTaps,
199 unsigned int WritebackChromaHTaps,
200 unsigned int WritebackChromaVTaps,
201 double WritebackDestinationWidth,
202 unsigned int HTotal,
203 unsigned int WritebackChromaLineBufferWidth);
204static void CalculateActiveRowBandwidth(
205 bool VirtualMemoryEnable,
206 enum source_format_class SourcePixelFormat,
207 double VRatio,
208 bool DCCEnable,
209 double LineTime,
210 unsigned int MetaRowByteLuma,
211 unsigned int MetaRowByteChroma,
212 unsigned int meta_row_height_luma,
213 unsigned int meta_row_height_chroma,
214 unsigned int PixelPTEBytesPerRowLuma,
215 unsigned int PixelPTEBytesPerRowChroma,
216 unsigned int dpte_row_height_luma,
217 unsigned int dpte_row_height_chroma,
218 double *meta_row_bw,
219 double *dpte_row_bw,
220 double *qual_row_bw);
221static void CalculateFlipSchedule(
222 struct display_mode_lib *mode_lib,
223 double UrgentExtraLatency,
224 double UrgentLatency,
225 unsigned int MaxPageTableLevels,
226 bool VirtualMemoryEnable,
227 double BandwidthAvailableForImmediateFlip,
228 unsigned int TotImmediateFlipBytes,
229 enum source_format_class SourcePixelFormat,
230 unsigned int ImmediateFlipBytes,
231 double LineTime,
232 double Tno_bw,
233 double VRatio,
234 double PDEAndMetaPTEBytesFrame,
235 unsigned int MetaRowByte,
236 unsigned int PixelPTEBytesPerRow,
237 bool DCCEnable,
238 unsigned int dpte_row_height,
239 unsigned int meta_row_height,
240 double qual_row_bw,
241 double *DestinationLinesToRequestVMInImmediateFlip,
242 double *DestinationLinesToRequestRowInImmediateFlip,
243 double *final_flip_bw,
244 bool *ImmediateFlipSupportedForPipe);
245static double CalculateWriteBackDelay(
246 enum source_format_class WritebackPixelFormat,
247 double WritebackHRatio,
248 double WritebackVRatio,
249 unsigned int WritebackLumaHTaps,
250 unsigned int WritebackLumaVTaps,
251 unsigned int WritebackChromaHTaps,
252 unsigned int WritebackChromaVTaps,
253 unsigned int WritebackDestinationWidth);
254static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib);
255static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
256static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
257
258void set_prefetch_mode(
259 struct display_mode_lib *mode_lib,
260 bool cstate_en,
261 bool pstate_en,
262 bool ignore_viewport_pos,
263 bool immediate_flip_support)
264{
265 unsigned int prefetch_mode;
266
267 if (cstate_en && pstate_en)
268 prefetch_mode = 0;
269 else if (cstate_en)
270 prefetch_mode = 1;
271 else
272 prefetch_mode = 2;
273 if (prefetch_mode != mode_lib->vba.PrefetchMode
274 || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning
275 || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) {
276 DTRACE(
277 " Prefetch mode has changed from %i to %i. Recalculating.",
278 prefetch_mode,
279 mode_lib->vba.PrefetchMode);
280 mode_lib->vba.PrefetchMode = prefetch_mode;
281 mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos;
282 mode_lib->vba.ImmediateFlipSupport = immediate_flip_support;
283 recalculate(mode_lib);
284 }
285}
286
287unsigned int dml_get_voltage_level(
288 struct display_mode_lib *mode_lib,
289 const display_e2e_pipe_params_st *pipes,
290 unsigned int num_pipes)
291{
292 bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
293 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
294 || num_pipes != mode_lib->vba.cache_num_pipes
295 || memcmp(pipes, mode_lib->vba.cache_pipes,
296 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
297
298 mode_lib->vba.soc = mode_lib->soc;
299 mode_lib->vba.ip = mode_lib->ip;
300 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
301 mode_lib->vba.cache_num_pipes = num_pipes;
302
303 if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
304 recalculate(mode_lib);
305 else {
306 fetch_socbb_params(mode_lib);
307 fetch_ip_params(mode_lib);
308 fetch_pipe_params(mode_lib);
309 }
310 ModeSupportAndSystemConfigurationFull(mode_lib);
311
312 return mode_lib->vba.VoltageLevel;
313}
314
315#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) \
316{ \
317 recalculate_params(mode_lib, pipes, num_pipes); \
318 return var; \
319}
320
321dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep);
322dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
323dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark);
324dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
325dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
326dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
327dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
328dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
329dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent
330dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
331dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
332dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs);
333dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
334dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
335dml_get_attr_func(
336 dram_clock_change_latency,
337 mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
338dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
339dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
340dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
341dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
342
343#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) \
344{\
345 unsigned int which_plane; \
346 recalculate_params(mode_lib, pipes, num_pipes); \
347 which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
348 return var[which_plane]; \
349}
350
351dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
352dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
353dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
354dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
355dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
356dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
357dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
358dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
359dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
360dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
361dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
362dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
363dml_get_pipe_attr_func(
364 dst_y_per_row_flip,
365 mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
366
367dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay);
368dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay);
369dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency);
370dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin);
371
372unsigned int get_vstartup_calculated(
373 struct display_mode_lib *mode_lib,
374 const display_e2e_pipe_params_st *pipes,
375 unsigned int num_pipes,
376 unsigned int which_pipe)
377{
378 unsigned int which_plane;
379
380 recalculate_params(mode_lib, pipes, num_pipes);
381 which_plane = mode_lib->vba.pipe_plane[which_pipe];
382 return mode_lib->vba.VStartup[which_plane];
383}
384
385double get_total_immediate_flip_bytes(
386 struct display_mode_lib *mode_lib,
387 const display_e2e_pipe_params_st *pipes,
388 unsigned int num_pipes)
389{
390 recalculate_params(mode_lib, pipes, num_pipes);
391 return mode_lib->vba.TotImmediateFlipBytes;
392}
393
394double get_total_immediate_flip_bw(
395 struct display_mode_lib *mode_lib,
396 const display_e2e_pipe_params_st *pipes,
397 unsigned int num_pipes)
398{
399 recalculate_params(mode_lib, pipes, num_pipes);
400 return mode_lib->vba.ImmediateFlipBW;
401}
402
403double get_total_prefetch_bw(
404 struct display_mode_lib *mode_lib,
405 const display_e2e_pipe_params_st *pipes,
406 unsigned int num_pipes)
407{
408 unsigned int k;
409 double total_prefetch_bw = 0.0;
410
411 recalculate_params(mode_lib, pipes, num_pipes);
412 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
413 total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
414 return total_prefetch_bw;
415}
416
417static void fetch_socbb_params(struct display_mode_lib *mode_lib)
418{
419 soc_bounding_box_st *soc = &mode_lib->vba.soc;
420 unsigned int i;
421
422 // SOC Bounding Box Parameters
423 mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
424 mode_lib->vba.NumberOfChannels = soc->num_chans;
425 mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency =
426 soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment!
427 mode_lib->vba.UrgentLatency = soc->urgent_latency_us;
428 mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
429 mode_lib->vba.UrgentOutOfOrderReturnPerChannel =
430 soc->urgent_out_of_order_return_per_channel_bytes;
431 mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
432 mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
433 mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
434 mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
435 mode_lib->vba.Downspreading = soc->downspread_percent;
436 mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new!
437 mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
438 mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new
439 mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new
440 mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
441 // Set the voltage scaling clocks as the defaults. Most of these will
442 // be set to different values by the test
443 for (i = 0; i < DC__VOLTAGE_STATES; i++)
444 if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
445 break;
446
447 mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
448 mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
449 mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz;
450 mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
451
452 mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
453 mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
454
455 mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
456 mode_lib->vba.MaxHSCLRatio = 4;
457 mode_lib->vba.MaxVSCLRatio = 4;
458 mode_lib->vba.MaxNumWriteback = 0; /*TODO*/
459 mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
460 mode_lib->vba.Cursor64BppSupport = true;
461 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
462 mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
463 mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
464 mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
465 mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
466 mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
467 mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
468 mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
469 mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
470 }
471}
472
473static void fetch_ip_params(struct display_mode_lib *mode_lib)
474{
475 ip_params_st *ip = &mode_lib->vba.ip;
476
477 // IP Parameters
478 mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
479 mode_lib->vba.MaxNumOTG = ip->max_num_otg;
480 mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
481 mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
482
483 mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
484 mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
485 mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
486 mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
487 mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
488 mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
489 mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes;
490 mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
491 mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
492 mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
493 mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs;
494 mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
495 mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
496 mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes;
497 mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes;
498 mode_lib->vba.WritebackChromaLineBufferWidth =
499 ip->writeback_chroma_line_buffer_width_pixels;
500 mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels;
501 mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
502 mode_lib->vba.NumberOfDSC = ip->num_dsc;
503 mode_lib->vba.ODMCapability = ip->odm_capable;
504 mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
505
506 mode_lib->vba.XFCSupported = ip->xfc_supported;
507 mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
508 mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
509 mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
510 mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
511 mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
512 mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
513 mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
514 mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
515
516 mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
517
518 mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
519}
520
521static void fetch_pipe_params(struct display_mode_lib *mode_lib)
522{
523 display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
524 ip_params_st *ip = &mode_lib->vba.ip;
525
526 unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
527 unsigned int j, k;
528 bool PlaneVisited[DC__NUM_DPP__MAX];
529 bool visited[DC__NUM_DPP__MAX];
530
531 // Convert Pipes to Planes
532 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
533 visited[k] = false;
534
535 mode_lib->vba.NumberOfActivePlanes = 0;
536 for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
537 display_pipe_source_params_st *src = &pipes[j].pipe.src;
538 display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
539 scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
540 scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
541 display_output_params_st *dout = &pipes[j].dout;
542 display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
543
544 if (visited[j])
545 continue;
546 visited[j] = true;
547
548 mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
549
550 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
551 mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
552 (enum scan_direction_class) (src->source_scan);
553 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
554 src->viewport_width;
555 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
556 src->viewport_height;
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.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
562 mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
563 mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
564 mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
565 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
566 mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
567 mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
568 if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes])
569 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
570 mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
571 mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
572 mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
573 mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
574 mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
575 mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
576 mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
577 src->dcc_use_global ?
578 ip->dcc_supported : src->dcc && ip->dcc_supported;
579 mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
580 mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] =
581 (enum source_format_class) (src->source_format);
582 mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
583 mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
584 mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
585 (enum dm_swizzle_mode) (src->sw_mode);
586 mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
587 dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
588 mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
589 dst->odm_combine;
590 mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
591 (enum output_format_class) (dout->output_format);
592 mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
593 (enum output_encoder_class) (dout->output_type);
594 mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
595 mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
596 dout->dp_lanes;
597 mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
598 mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
599 dout->dsc_slices;
600 mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
601 dout->opp_input_bpc == 0 ? 12 : dout->opp_input_bpc;
602 mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
603 mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
604 dout->wb.wb_src_height;
605 mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
606 dout->wb.wb_dst_width;
607 mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
608 dout->wb.wb_dst_height;
609 mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
610 (enum source_format_class) (dout->wb.wb_pixel_format);
611 mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
612 dout->wb.wb_htaps_luma;
613 mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
614 dout->wb.wb_vtaps_luma;
615 mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
616 dout->wb.wb_htaps_chroma;
617 mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
618 dout->wb.wb_vtaps_chroma;
619 mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
620 dout->wb.wb_hratio;
621 mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
622 dout->wb.wb_vratio;
623
624 mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
625 src->dynamic_metadata_enable;
626 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
627 src->dynamic_metadata_lines_before_active;
628 mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
629 src->dynamic_metadata_xmit_bytes;
630
631 mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
632 && ip->xfc_supported;
633 mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
634 mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
635 mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
636 mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
637 mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
638 mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
639 if (ip->is_line_buffer_bpp_fixed)
640 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
641 ip->line_buffer_fixed_bpp;
642 else {
643 unsigned int lb_depth;
644
645 switch (scl->lb_depth) {
646 case dm_lb_6:
647 lb_depth = 18;
648 break;
649 case dm_lb_8:
650 lb_depth = 24;
651 break;
652 case dm_lb_10:
653 lb_depth = 30;
654 break;
655 case dm_lb_12:
656 lb_depth = 36;
657 break;
658 case dm_lb_16:
659 lb_depth = 48;
660 break;
661 default:
662 lb_depth = 36;
663 }
664 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
665 }
666 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
667 // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
668 // calculate things a little more accurately
669 for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
670 switch (k) {
671 case 0:
672 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
673 CursorBppEnumToBits(
674 (enum cursor_bpp) (src->cur0_bpp));
675 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
676 src->cur0_src_width;
677 if (src->cur0_src_width > 0)
678 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
679 break;
680 case 1:
681 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
682 CursorBppEnumToBits(
683 (enum cursor_bpp) (src->cur1_bpp));
684 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
685 src->cur1_src_width;
686 if (src->cur1_src_width > 0)
687 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
688 break;
689 default:
690 dml_print(
691 "ERROR: Number of cursors specified exceeds supported maximum\n")
692 ;
693 }
694 }
695
696 OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
697
698 if (dst->odm_combine && !src->is_hsplit)
699 dml_print(
700 "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
701 j);
702
703 if (src->is_hsplit) {
704 for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
705 display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
706 display_output_params_st *dout_k = &pipes[k].dout;
707
708 if (src_k->is_hsplit && !visited[k]
709 && src->hsplit_grp == src_k->hsplit_grp) {
710 mode_lib->vba.pipe_plane[k] =
711 mode_lib->vba.NumberOfActivePlanes;
712 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
713 if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
714 == dm_horz)
715 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
716 src_k->viewport_width;
717 else
718 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
719 src_k->viewport_height;
720
721 mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] +=
722 dout_k->dsc_slices;
723 visited[k] = true;
724 }
725 }
726 }
727
728 mode_lib->vba.NumberOfActivePlanes++;
729 }
730
731 // handle overlays through dml_ml->vba.BlendingAndTiming
732 // dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
733
734 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
735 PlaneVisited[j] = false;
736
737 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
738 for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
739 if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
740 // doesn't matter, so choose the smaller one
741 mode_lib->vba.BlendingAndTiming[j] = j;
742 PlaneVisited[j] = true;
743 mode_lib->vba.BlendingAndTiming[k] = j;
744 PlaneVisited[k] = true;
745 }
746 }
747
748 if (!PlaneVisited[j]) {
749 mode_lib->vba.BlendingAndTiming[j] = j;
750 PlaneVisited[j] = true;
751 }
752 }
753
754 // TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified
755 // Do we want the dscclk to automatically be halved? Guess not since the value is specified
756
757 mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
758 for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k)
759 ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
760
761 mode_lib->vba.VirtualMemoryEnable = false;
762 mode_lib->vba.OverridePageTableLevels = 0;
763
764 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
765 mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable
766 || !!pipes[k].pipe.src.vm;
767 mode_lib->vba.OverridePageTableLevels =
768 (pipes[k].pipe.src.vm_levels_force_en
769 && mode_lib->vba.OverridePageTableLevels
770 < pipes[k].pipe.src.vm_levels_force) ?
771 pipes[k].pipe.src.vm_levels_force :
772 mode_lib->vba.OverridePageTableLevels;
773 }
774
775 if (mode_lib->vba.OverridePageTableLevels)
776 mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels;
777
778 mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable && !!ip->pte_enable;
779
780 mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
781 mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels
782 * mode_lib->vba.DRAMChannelWidth,
783 mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn)
784 / 1000.0;
785
786 // TODO: Must be consistent across all pipes
787 // DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown;
788}
789
790static void recalculate(struct display_mode_lib *mode_lib)
791{
792 ModeSupportAndSystemConfiguration(mode_lib);
793 PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
794 DisplayPipeConfiguration(mode_lib);
795 DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
796}
797
798// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
799// rather than working them out as in recalculate_ms
800static void recalculate_params(
801 struct display_mode_lib *mode_lib,
802 const display_e2e_pipe_params_st *pipes,
803 unsigned int num_pipes)
804{
805 // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
806 if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
807 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
808 || num_pipes != mode_lib->vba.cache_num_pipes
809 || memcmp(
810 pipes,
811 mode_lib->vba.cache_pipes,
812 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
813 mode_lib->vba.soc = mode_lib->soc;
814 mode_lib->vba.ip = mode_lib->ip;
815 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
816 mode_lib->vba.cache_num_pipes = num_pipes;
817 recalculate(mode_lib);
818 }
819}
820
821static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
822{
823 soc_bounding_box_st *soc = &mode_lib->vba.soc;
824 unsigned int i, k;
825 unsigned int total_pipes = 0;
826
827 mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
828 for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i)
829 ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage);
830
831 mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
832 mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
833
834 if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
835 mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
836 else
837 mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
838
839 fetch_socbb_params(mode_lib);
840 fetch_ip_params(mode_lib);
841 fetch_pipe_params(mode_lib);
842
843 // Total Available Pipes Support Check
844 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
845 total_pipes += mode_lib->vba.DPPPerPlane[k];
846 ASSERT(total_pipes <= DC__NUM_DPP__MAX);
847}
848
849static double adjust_ReturnBW(
850 struct display_mode_lib *mode_lib,
851 double ReturnBW,
852 bool DCCEnabledAnyPlane,
853 double ReturnBandwidthToDCN)
854{
855 double CriticalCompression;
856
857 if (DCCEnabledAnyPlane
858 && ReturnBandwidthToDCN
859 > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
860 ReturnBW =
861 dml_min(
862 ReturnBW,
863 ReturnBandwidthToDCN * 4
864 * (1.0
865 - mode_lib->vba.UrgentLatency
866 / ((mode_lib->vba.ROBBufferSizeInKByte
867 - mode_lib->vba.PixelChunkSizeInKByte)
868 * 1024
869 / ReturnBandwidthToDCN
870 - mode_lib->vba.DCFCLK
871 * mode_lib->vba.ReturnBusWidth
872 / 4)
873 + mode_lib->vba.UrgentLatency));
874
875 CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
876 * mode_lib->vba.UrgentLatency
877 / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency
878 + (mode_lib->vba.ROBBufferSizeInKByte
879 - mode_lib->vba.PixelChunkSizeInKByte)
880 * 1024);
881
882 if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
883 ReturnBW =
884 dml_min(
885 ReturnBW,
886 4.0 * ReturnBandwidthToDCN
887 * (mode_lib->vba.ROBBufferSizeInKByte
888 - mode_lib->vba.PixelChunkSizeInKByte)
889 * 1024
890 * mode_lib->vba.ReturnBusWidth
891 * mode_lib->vba.DCFCLK
892 * mode_lib->vba.UrgentLatency
893 / dml_pow(
894 (ReturnBandwidthToDCN
895 * mode_lib->vba.UrgentLatency
896 + (mode_lib->vba.ROBBufferSizeInKByte
897 - mode_lib->vba.PixelChunkSizeInKByte)
898 * 1024),
899 2));
900
901 return ReturnBW;
902}
903
904static unsigned int dscceComputeDelay(
905 unsigned int bpc,
906 double bpp,
907 unsigned int sliceWidth,
908 unsigned int numSlices,
909 enum output_format_class pixelFormat)
910{
911 // valid bpc = source bits per component in the set of {8, 10, 12}
912 // valid bpp = increments of 1/16 of a bit
913 // min = 6/7/8 in N420/N422/444, respectively
914 // max = such that compression is 1:1
915 //valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
916 //valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
917 //valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
918
919 // fixed value
920 unsigned int rcModelSize = 8192;
921
922 // N422/N420 operate at 2 pixels per clock
923 unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
924 Delay, pixels;
925
926 if (pixelFormat == dm_n422 || pixelFormat == dm_420)
927 pixelsPerClock = 2;
928 // #all other modes operate at 1 pixel per clock
929 else
930 pixelsPerClock = 1;
931
932 //initial transmit delay as per PPS
933 initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
934
935 //compute ssm delay
936 if (bpc == 8)
937 D = 81;
938 else if (bpc == 10)
939 D = 89;
940 else
941 D = 113;
942
943 //divide by pixel per cycle to compute slice width as seen by DSC
944 w = sliceWidth / pixelsPerClock;
945
946 //422 mode has an additional cycle of delay
947 if (pixelFormat == dm_s422)
948 s = 1;
949 else
950 s = 0;
951
952 //main calculation for the dscce
953 ix = initalXmitDelay + 45;
954 wx = (w + 2) / 3;
955 p = 3 * wx - w;
956 l0 = ix / w;
957 a = ix + p * l0;
958 ax = (a + 2) / 3 + D + 6 + 1;
959 l = (ax + wx - 1) / wx;
960 if ((ix % w) == 0 && p != 0)
961 lstall = 1;
962 else
963 lstall = 0;
964 Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
965
966 //dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
967 pixels = Delay * 3 * pixelsPerClock;
968 return pixels;
969}
970
971static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
972{
973 unsigned int Delay = 0;
974
975 if (pixelFormat == dm_420) {
976 // sfr
977 Delay = Delay + 2;
978 // dsccif
979 Delay = Delay + 0;
980 // dscc - input deserializer
981 Delay = Delay + 3;
982 // dscc gets pixels every other cycle
983 Delay = Delay + 2;
984 // dscc - input cdc fifo
985 Delay = Delay + 12;
986 // dscc gets pixels every other cycle
987 Delay = Delay + 13;
988 // dscc - cdc uncertainty
989 Delay = Delay + 2;
990 // dscc - output cdc fifo
991 Delay = Delay + 7;
992 // dscc gets pixels every other cycle
993 Delay = Delay + 3;
994 // dscc - cdc uncertainty
995 Delay = Delay + 2;
996 // dscc - output serializer
997 Delay = Delay + 1;
998 // sft
999 Delay = Delay + 1;
1000 } else if (pixelFormat == dm_n422) {
1001 // sfr
1002 Delay = Delay + 2;
1003 // dsccif
1004 Delay = Delay + 1;
1005 // dscc - input deserializer
1006 Delay = Delay + 5;
1007 // dscc - input cdc fifo
1008 Delay = Delay + 25;
1009 // dscc - cdc uncertainty
1010 Delay = Delay + 2;
1011 // dscc - output cdc fifo
1012 Delay = Delay + 10;
1013 // dscc - cdc uncertainty
1014 Delay = Delay + 2;
1015 // dscc - output serializer
1016 Delay = Delay + 1;
1017 // sft
1018 Delay = Delay + 1;
1019 } else {
1020 // sfr
1021 Delay = Delay + 2;
1022 // dsccif
1023 Delay = Delay + 0;
1024 // dscc - input deserializer
1025 Delay = Delay + 3;
1026 // dscc - input cdc fifo
1027 Delay = Delay + 12;
1028 // dscc - cdc uncertainty
1029 Delay = Delay + 2;
1030 // dscc - output cdc fifo
1031 Delay = Delay + 7;
1032 // dscc - output serializer
1033 Delay = Delay + 1;
1034 // dscc - cdc uncertainty
1035 Delay = Delay + 2;
1036 // sft
1037 Delay = Delay + 1;
1038 }
1039
1040 return Delay;
1041}
1042
1043static bool CalculatePrefetchSchedule(
1044 struct display_mode_lib *mode_lib,
1045 double DPPCLK,
1046 double DISPCLK,
1047 double PixelClock,
1048 double DCFClkDeepSleep,
1049 unsigned int DSCDelay,
1050 unsigned int DPPPerPlane,
1051 bool ScalerEnabled,
1052 unsigned int NumberOfCursors,
1053 double DPPCLKDelaySubtotal,
1054 double DPPCLKDelaySCL,
1055 double DPPCLKDelaySCLLBOnly,
1056 double DPPCLKDelayCNVCFormater,
1057 double DPPCLKDelayCNVCCursor,
1058 double DISPCLKDelaySubtotal,
1059 unsigned int ScalerRecoutWidth,
1060 enum output_format_class OutputFormat,
1061 unsigned int VBlank,
1062 unsigned int HTotal,
1063 unsigned int MaxInterDCNTileRepeaters,
1064 unsigned int VStartup,
1065 unsigned int PageTableLevels,
1066 bool VirtualMemoryEnable,
1067 bool DynamicMetadataEnable,
1068 unsigned int DynamicMetadataLinesBeforeActiveRequired,
1069 unsigned int DynamicMetadataTransmittedBytes,
1070 bool DCCEnable,
1071 double UrgentLatency,
1072 double UrgentExtraLatency,
1073 double TCalc,
1074 unsigned int PDEAndMetaPTEBytesFrame,
1075 unsigned int MetaRowByte,
1076 unsigned int PixelPTEBytesPerRow,
1077 double PrefetchSourceLinesY,
1078 unsigned int SwathWidthY,
1079 double BytePerPixelDETY,
1080 double VInitPreFillY,
1081 unsigned int MaxNumSwathY,
1082 double PrefetchSourceLinesC,
1083 double BytePerPixelDETC,
1084 double VInitPreFillC,
1085 unsigned int MaxNumSwathC,
1086 unsigned int SwathHeightY,
1087 unsigned int SwathHeightC,
1088 double TWait,
1089 bool XFCEnabled,
1090 double XFCRemoteSurfaceFlipDelay,
1091 bool InterlaceEnable,
1092 bool ProgressiveToInterlaceUnitInOPP,
1093 double *DSTXAfterScaler,
1094 double *DSTYAfterScaler,
1095 double *DestinationLinesForPrefetch,
1096 double *PrefetchBandwidth,
1097 double *DestinationLinesToRequestVMInVBlank,
1098 double *DestinationLinesToRequestRowInVBlank,
1099 double *VRatioPrefetchY,
1100 double *VRatioPrefetchC,
1101 double *RequiredPrefetchPixDataBW,
1102 unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
1103 double *Tno_bw,
1104 unsigned int *VUpdateOffsetPix,
1105 unsigned int *VUpdateWidthPix,
1106 unsigned int *VReadyOffsetPix)
1107{
1108 bool MyError = false;
1109 unsigned int DPPCycles, DISPCLKCycles;
1110 double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
1111 double Tdm, LineTime, Tsetup;
1112 double dst_y_prefetch_equ;
1113 double Tsw_oto;
1114 double prefetch_bw_oto;
1115 double Tvm_oto;
1116 double Tr0_oto;
1117 double Tpre_oto;
1118 double dst_y_prefetch_oto;
1119 double TimeForFetchingMetaPTE = 0;
1120 double TimeForFetchingRowInVBlank = 0;
1121 double LinesToRequestPrefetchPixelData = 0;
1122
1123 if (ScalerEnabled)
1124 DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
1125 else
1126 DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
1127
1128 DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
1129
1130 DISPCLKCycles = DISPCLKDelaySubtotal;
1131
1132 if (DPPCLK == 0.0 || DISPCLK == 0.0)
1133 return true;
1134
1135 *DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
1136 + DSCDelay;
1137
1138 if (DPPPerPlane > 1)
1139 *DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
1140
1141 if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
1142 *DSTYAfterScaler = 1;
1143 else
1144 *DSTYAfterScaler = 0;
1145
1146 DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
1147 *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
1148 *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
1149
1150 *VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
1151 TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
1152 *VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
1153 * PixelClock;
1154
1155 *VReadyOffsetPix = dml_max(
1156 150.0 / DPPCLK,
1157 TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK)
1158 * PixelClock;
1159
1160 Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
1161
1162 LineTime = (double) HTotal / PixelClock;
1163
1164 if (DynamicMetadataEnable) {
1165 double Tdmbf, Tdmec, Tdmsks;
1166
1167 Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
1168 Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
1169 Tdmec = LineTime;
1170 if (DynamicMetadataLinesBeforeActiveRequired == 0)
1171 Tdmsks = VBlank * LineTime / 2.0;
1172 else
1173 Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
1174 if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
1175 Tdmsks = Tdmsks / 2;
1176 if (VStartup * LineTime
1177 < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
1178 MyError = true;
1179 *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
1180 + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
1181 } else
1182 *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
1183 } else
1184 Tdm = 0;
1185
1186 if (VirtualMemoryEnable) {
1187 if (PageTableLevels == 4)
1188 *Tno_bw = UrgentExtraLatency + UrgentLatency;
1189 else if (PageTableLevels == 3)
1190 *Tno_bw = UrgentExtraLatency;
1191 else
1192 *Tno_bw = 0;
1193 } else if (DCCEnable)
1194 *Tno_bw = LineTime;
1195 else
1196 *Tno_bw = LineTime / 4;
1197
1198 dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
1199 - (Tsetup + Tdm) / LineTime
1200 - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal);
1201
1202 Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
1203
1204 prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
1205 + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
1206 + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
1207 / Tsw_oto;
1208
1209 if (VirtualMemoryEnable == true) {
1210 Tvm_oto =
1211 dml_max(
1212 *Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
1213 dml_max(
1214 UrgentExtraLatency
1215 + UrgentLatency
1216 * (PageTableLevels
1217 - 1),
1218 LineTime / 4.0));
1219 } else
1220 Tvm_oto = LineTime / 4.0;
1221
1222 if ((VirtualMemoryEnable == true || DCCEnable == true)) {
1223 Tr0_oto = dml_max(
1224 (MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
1225 dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4)));
1226 } else
1227 Tr0_oto = LineTime - Tvm_oto;
1228
1229 Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
1230
1231 dst_y_prefetch_oto = Tpre_oto / LineTime;
1232
1233 if (dst_y_prefetch_oto < dst_y_prefetch_equ)
1234 *DestinationLinesForPrefetch = dst_y_prefetch_oto;
1235 else
1236 *DestinationLinesForPrefetch = dst_y_prefetch_equ;
1237
1238 *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
1239 / 4;
1240
1241 dml_print("DML: VStartup: %d\n", VStartup);
1242 dml_print("DML: TCalc: %f\n", TCalc);
1243 dml_print("DML: TWait: %f\n", TWait);
1244 dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
1245 dml_print("DML: LineTime: %f\n", LineTime);
1246 dml_print("DML: Tsetup: %f\n", Tsetup);
1247 dml_print("DML: Tdm: %f\n", Tdm);
1248 dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler);
1249 dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler);
1250 dml_print("DML: HTotal: %d\n", HTotal);
1251
1252 *PrefetchBandwidth = 0;
1253 *DestinationLinesToRequestVMInVBlank = 0;
1254 *DestinationLinesToRequestRowInVBlank = 0;
1255 *VRatioPrefetchY = 0;
1256 *VRatioPrefetchC = 0;
1257 *RequiredPrefetchPixDataBW = 0;
1258 if (*DestinationLinesForPrefetch > 1) {
1259 *PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
1260 + 2 * PixelPTEBytesPerRow
1261 + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
1262 + PrefetchSourceLinesC * SwathWidthY / 2
1263 * dml_ceil(BytePerPixelDETC, 2))
1264 / (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
1265 if (VirtualMemoryEnable) {
1266 TimeForFetchingMetaPTE =
1267 dml_max(
1268 *Tno_bw
1269 + (double) PDEAndMetaPTEBytesFrame
1270 / *PrefetchBandwidth,
1271 dml_max(
1272 UrgentExtraLatency
1273 + UrgentLatency
1274 * (PageTableLevels
1275 - 1),
1276 LineTime / 4));
1277 } else {
1278 if (NumberOfCursors > 0 || XFCEnabled)
1279 TimeForFetchingMetaPTE = LineTime / 4;
1280 else
1281 TimeForFetchingMetaPTE = 0.0;
1282 }
1283
1284 if ((VirtualMemoryEnable == true || DCCEnable == true)) {
1285 TimeForFetchingRowInVBlank =
1286 dml_max(
1287 (MetaRowByte + PixelPTEBytesPerRow)
1288 / *PrefetchBandwidth,
1289 dml_max(
1290 UrgentLatency,
1291 dml_max(
1292 LineTime
1293 - TimeForFetchingMetaPTE,
1294 LineTime
1295 / 4.0)));
1296 } else {
1297 if (NumberOfCursors > 0 || XFCEnabled)
1298 TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
1299 else
1300 TimeForFetchingRowInVBlank = 0.0;
1301 }
1302
1303 *DestinationLinesToRequestVMInVBlank = dml_floor(
1304 4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
1305 1) / 4.0;
1306
1307 *DestinationLinesToRequestRowInVBlank = dml_floor(
1308 4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
1309 1) / 4.0;
1310
1311 LinesToRequestPrefetchPixelData =
1312 *DestinationLinesForPrefetch
1313 - ((NumberOfCursors > 0 || VirtualMemoryEnable
1314 || DCCEnable) ?
1315 (*DestinationLinesToRequestVMInVBlank
1316 + *DestinationLinesToRequestRowInVBlank) :
1317 0.0);
1318
1319 if (LinesToRequestPrefetchPixelData > 0) {
1320
1321 *VRatioPrefetchY = (double) PrefetchSourceLinesY
1322 / LinesToRequestPrefetchPixelData;
1323 *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1324 if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
1325 if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
1326 *VRatioPrefetchY =
1327 dml_max(
1328 (double) PrefetchSourceLinesY
1329 / LinesToRequestPrefetchPixelData,
1330 (double) MaxNumSwathY
1331 * SwathHeightY
1332 / (LinesToRequestPrefetchPixelData
1333 - (VInitPreFillY
1334 - 3.0)
1335 / 2.0));
1336 *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1337 } else {
1338 MyError = true;
1339 *VRatioPrefetchY = 0;
1340 }
1341 }
1342
1343 *VRatioPrefetchC = (double) PrefetchSourceLinesC
1344 / LinesToRequestPrefetchPixelData;
1345 *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1346
1347 if ((SwathHeightC > 4)) {
1348 if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
1349 *VRatioPrefetchC =
1350 dml_max(
1351 *VRatioPrefetchC,
1352 (double) MaxNumSwathC
1353 * SwathHeightC
1354 / (LinesToRequestPrefetchPixelData
1355 - (VInitPreFillC
1356 - 3.0)
1357 / 2.0));
1358 *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1359 } else {
1360 MyError = true;
1361 *VRatioPrefetchC = 0;
1362 }
1363 }
1364
1365 *RequiredPrefetchPixDataBW =
1366 DPPPerPlane
1367 * ((double) PrefetchSourceLinesY
1368 / LinesToRequestPrefetchPixelData
1369 * dml_ceil(
1370 BytePerPixelDETY,
1371 1)
1372 + (double) PrefetchSourceLinesC
1373 / LinesToRequestPrefetchPixelData
1374 * dml_ceil(
1375 BytePerPixelDETC,
1376 2)
1377 / 2)
1378 * SwathWidthY / LineTime;
1379 } else {
1380 MyError = true;
1381 *VRatioPrefetchY = 0;
1382 *VRatioPrefetchC = 0;
1383 *RequiredPrefetchPixDataBW = 0;
1384 }
1385
1386 } else {
1387 MyError = true;
1388 }
1389
1390 if (MyError) {
1391 *PrefetchBandwidth = 0;
1392 TimeForFetchingMetaPTE = 0;
1393 TimeForFetchingRowInVBlank = 0;
1394 *DestinationLinesToRequestVMInVBlank = 0;
1395 *DestinationLinesToRequestRowInVBlank = 0;
1396 *DestinationLinesForPrefetch = 0;
1397 LinesToRequestPrefetchPixelData = 0;
1398 *VRatioPrefetchY = 0;
1399 *VRatioPrefetchC = 0;
1400 *RequiredPrefetchPixDataBW = 0;
1401 }
1402
1403 return MyError;
1404}
1405
1406static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
1407{
1408 return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
1409}
1410
1411static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
1412{
1413 return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
1414}
1415
1416static double CalculatePrefetchSourceLines(
1417 struct display_mode_lib *mode_lib,
1418 double VRatio,
1419 double vtaps,
1420 bool Interlace,
1421 bool ProgressiveToInterlaceUnitInOPP,
1422 unsigned int SwathHeight,
1423 unsigned int ViewportYStart,
1424 double *VInitPreFill,
1425 unsigned int *MaxNumSwath)
1426{
1427 unsigned int MaxPartialSwath;
1428
1429 if (ProgressiveToInterlaceUnitInOPP)
1430 *VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
1431 else
1432 *VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
1433
1434 if (!mode_lib->vba.IgnoreViewportPositioning) {
1435
1436 *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
1437
1438 if (*VInitPreFill > 1.0)
1439 MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
1440 else
1441 MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
1442 % SwathHeight;
1443 MaxPartialSwath = dml_max(1U, MaxPartialSwath);
1444
1445 } else {
1446
1447 if (ViewportYStart != 0)
1448 dml_print(
1449 "WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
1450
1451 *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
1452
1453 if (*VInitPreFill > 1.0)
1454 MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
1455 else
1456 MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
1457 % SwathHeight;
1458 }
1459
1460 return *MaxNumSwath * SwathHeight + MaxPartialSwath;
1461}
1462
1463static unsigned int CalculateVMAndRowBytes(
1464 struct display_mode_lib *mode_lib,
1465 bool DCCEnable,
1466 unsigned int BlockHeight256Bytes,
1467 unsigned int BlockWidth256Bytes,
1468 enum source_format_class SourcePixelFormat,
1469 unsigned int SurfaceTiling,
1470 unsigned int BytePerPixel,
1471 enum scan_direction_class ScanDirection,
1472 unsigned int ViewportWidth,
1473 unsigned int ViewportHeight,
1474 unsigned int SwathWidth,
1475 bool VirtualMemoryEnable,
1476 unsigned int VMMPageSize,
1477 unsigned int PTEBufferSizeInRequests,
1478 unsigned int PDEProcessingBufIn64KBReqs,
1479 unsigned int Pitch,
1480 unsigned int DCCMetaPitch,
1481 unsigned int *MacroTileWidth,
1482 unsigned int *MetaRowByte,
1483 unsigned int *PixelPTEBytesPerRow,
1484 bool *PTEBufferSizeNotExceeded,
1485 unsigned int *dpte_row_height,
1486 unsigned int *meta_row_height)
1487{
1488 unsigned int MetaRequestHeight;
1489 unsigned int MetaRequestWidth;
1490 unsigned int MetaSurfWidth;
1491 unsigned int MetaSurfHeight;
1492 unsigned int MPDEBytesFrame;
1493 unsigned int MetaPTEBytesFrame;
1494 unsigned int DCCMetaSurfaceBytes;
1495
1496 unsigned int MacroTileSizeBytes;
1497 unsigned int MacroTileHeight;
1498 unsigned int DPDE0BytesFrame;
1499 unsigned int ExtraDPDEBytesFrame;
1500 unsigned int PDEAndMetaPTEBytesFrame;
1501
1502 if (DCCEnable == true) {
1503 MetaRequestHeight = 8 * BlockHeight256Bytes;
1504 MetaRequestWidth = 8 * BlockWidth256Bytes;
1505 if (ScanDirection == dm_horz) {
1506 *meta_row_height = MetaRequestHeight;
1507 MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
1508 + MetaRequestWidth;
1509 *MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
1510 } else {
1511 *meta_row_height = MetaRequestWidth;
1512 MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
1513 + MetaRequestHeight;
1514 *MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
1515 }
1516 if (ScanDirection == dm_horz) {
1517 DCCMetaSurfaceBytes = DCCMetaPitch
1518 * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
1519 + 64 * BlockHeight256Bytes) * BytePerPixel
1520 / 256;
1521 } else {
1522 DCCMetaSurfaceBytes = DCCMetaPitch
1523 * (dml_ceil(
1524 (double) ViewportHeight - 1,
1525 64 * BlockHeight256Bytes)
1526 + 64 * BlockHeight256Bytes) * BytePerPixel
1527 / 256;
1528 }
1529 if (VirtualMemoryEnable == true) {
1530 MetaPTEBytesFrame = (dml_ceil(
1531 (double) (DCCMetaSurfaceBytes - VMMPageSize)
1532 / (8 * VMMPageSize),
1533 1) + 1) * 64;
1534 MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1);
1535 } else {
1536 MetaPTEBytesFrame = 0;
1537 MPDEBytesFrame = 0;
1538 }
1539 } else {
1540 MetaPTEBytesFrame = 0;
1541 MPDEBytesFrame = 0;
1542 *MetaRowByte = 0;
1543 }
1544
1545 if (SurfaceTiling == dm_sw_linear) {
1546 MacroTileSizeBytes = 256;
1547 MacroTileHeight = 1;
1548 } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
1549 || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
1550 MacroTileSizeBytes = 4096;
1551 MacroTileHeight = 4 * BlockHeight256Bytes;
1552 } else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
1553 || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
1554 || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
1555 || SurfaceTiling == dm_sw_64kb_r_x) {
1556 MacroTileSizeBytes = 65536;
1557 MacroTileHeight = 16 * BlockHeight256Bytes;
1558 } else {
1559 MacroTileSizeBytes = 262144;
1560 MacroTileHeight = 32 * BlockHeight256Bytes;
1561 }
1562 *MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
1563
1564 if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) {
1565 if (ScanDirection == dm_horz) {
1566 DPDE0BytesFrame =
1567 64
1568 * (dml_ceil(
1569 ((Pitch
1570 * (dml_ceil(
1571 ViewportHeight
1572 - 1,
1573 MacroTileHeight)
1574 + MacroTileHeight)
1575 * BytePerPixel)
1576 - MacroTileSizeBytes)
1577 / (8
1578 * 2097152),
1579 1) + 1);
1580 } else {
1581 DPDE0BytesFrame =
1582 64
1583 * (dml_ceil(
1584 ((Pitch
1585 * (dml_ceil(
1586 (double) SwathWidth
1587 - 1,
1588 MacroTileHeight)
1589 + MacroTileHeight)
1590 * BytePerPixel)
1591 - MacroTileSizeBytes)
1592 / (8
1593 * 2097152),
1594 1) + 1);
1595 }
1596 ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2);
1597 } else {
1598 DPDE0BytesFrame = 0;
1599 ExtraDPDEBytesFrame = 0;
1600 }
1601
1602 PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
1603 + ExtraDPDEBytesFrame;
1604
1605 if (VirtualMemoryEnable == true) {
1606 unsigned int PTERequestSize;
1607 unsigned int PixelPTEReqHeight;
1608 unsigned int PixelPTEReqWidth;
1609 double FractionOfPTEReturnDrop;
1610 unsigned int EffectivePDEProcessingBufIn64KBReqs;
1611
1612 if (SurfaceTiling == dm_sw_linear) {
1613 PixelPTEReqHeight = 1;
1614 PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
1615 PTERequestSize = 64;
1616 FractionOfPTEReturnDrop = 0;
1617 } else if (MacroTileSizeBytes == 4096) {
1618 PixelPTEReqHeight = MacroTileHeight;
1619 PixelPTEReqWidth = 8 * *MacroTileWidth;
1620 PTERequestSize = 64;
1621 if (ScanDirection == dm_horz)
1622 FractionOfPTEReturnDrop = 0;
1623 else
1624 FractionOfPTEReturnDrop = 7 / 8;
1625 } else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
1626 PixelPTEReqHeight = 16 * BlockHeight256Bytes;
1627 PixelPTEReqWidth = 16 * BlockWidth256Bytes;
1628 PTERequestSize = 128;
1629 FractionOfPTEReturnDrop = 0;
1630 } else {
1631 PixelPTEReqHeight = MacroTileHeight;
1632 PixelPTEReqWidth = 8 * *MacroTileWidth;
1633 PTERequestSize = 64;
1634 FractionOfPTEReturnDrop = 0;
1635 }
1636
1637 if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
1638 EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
1639 else
1640 EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
1641
1642 if (SurfaceTiling == dm_sw_linear) {
1643 *dpte_row_height =
1644 dml_min(
1645 128,
1646 1
1647 << (unsigned int) dml_floor(
1648 dml_log2(
1649 dml_min(
1650 (double) PTEBufferSizeInRequests
1651 * PixelPTEReqWidth,
1652 EffectivePDEProcessingBufIn64KBReqs
1653 * 65536.0
1654 / BytePerPixel)
1655 / Pitch),
1656 1));
1657 *PixelPTEBytesPerRow = PTERequestSize
1658 * (dml_ceil(
1659 (double) (Pitch * *dpte_row_height - 1)
1660 / PixelPTEReqWidth,
1661 1) + 1);
1662 } else if (ScanDirection == dm_horz) {
1663 *dpte_row_height = PixelPTEReqHeight;
1664 *PixelPTEBytesPerRow = PTERequestSize
1665 * (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
1666 + 1);
1667 } else {
1668 *dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
1669 *PixelPTEBytesPerRow = PTERequestSize
1670 * (dml_ceil(
1671 ((double) SwathWidth - 1)
1672 / PixelPTEReqHeight,
1673 1) + 1);
1674 }
1675 if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
1676 <= 64 * PTEBufferSizeInRequests) {
1677 *PTEBufferSizeNotExceeded = true;
1678 } else {
1679 *PTEBufferSizeNotExceeded = false;
1680 }
1681 } else {
1682 *PixelPTEBytesPerRow = 0;
1683 *PTEBufferSizeNotExceeded = true;
1684 }
1685
1686 return PDEAndMetaPTEBytesFrame;
1687}
1688
1689static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
1690 struct display_mode_lib *mode_lib)
1691{
1692 unsigned int j, k;
1693
1694 mode_lib->vba.WritebackDISPCLK = 0.0;
1695 mode_lib->vba.DISPCLKWithRamping = 0;
1696 mode_lib->vba.DISPCLKWithoutRamping = 0;
1697 mode_lib->vba.GlobalDPPCLK = 0.0;
1698
1699 // dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
1700 //
1701 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1702 if (mode_lib->vba.WritebackEnable[k]) {
1703 mode_lib->vba.WritebackDISPCLK =
1704 dml_max(
1705 mode_lib->vba.WritebackDISPCLK,
1706 CalculateWriteBackDISPCLK(
1707 mode_lib->vba.WritebackPixelFormat[k],
1708 mode_lib->vba.PixelClock[k],
1709 mode_lib->vba.WritebackHRatio[k],
1710 mode_lib->vba.WritebackVRatio[k],
1711 mode_lib->vba.WritebackLumaHTaps[k],
1712 mode_lib->vba.WritebackLumaVTaps[k],
1713 mode_lib->vba.WritebackChromaHTaps[k],
1714 mode_lib->vba.WritebackChromaVTaps[k],
1715 mode_lib->vba.WritebackDestinationWidth[k],
1716 mode_lib->vba.HTotal[k],
1717 mode_lib->vba.WritebackChromaLineBufferWidth));
1718 }
1719 }
1720
1721 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1722 if (mode_lib->vba.HRatio[k] > 1) {
1723 mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
1724 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1725 mode_lib->vba.MaxPSCLToLBThroughput
1726 * mode_lib->vba.HRatio[k]
1727 / dml_ceil(
1728 mode_lib->vba.htaps[k]
1729 / 6.0,
1730 1));
1731 } else {
1732 mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
1733 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1734 mode_lib->vba.MaxPSCLToLBThroughput);
1735 }
1736
1737 mode_lib->vba.DPPCLKUsingSingleDPPLuma =
1738 mode_lib->vba.PixelClock[k]
1739 * dml_max(
1740 mode_lib->vba.vtaps[k] / 6.0
1741 * dml_min(
1742 1.0,
1743 mode_lib->vba.HRatio[k]),
1744 dml_max(
1745 mode_lib->vba.HRatio[k]
1746 * mode_lib->vba.VRatio[k]
1747 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
1748 1.0));
1749
1750 if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
1751 && mode_lib->vba.DPPCLKUsingSingleDPPLuma
1752 < 2 * mode_lib->vba.PixelClock[k]) {
1753 mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
1754 }
1755
1756 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
1757 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
1758 mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
1759 mode_lib->vba.DPPCLKUsingSingleDPP[k] =
1760 mode_lib->vba.DPPCLKUsingSingleDPPLuma;
1761 } else {
1762 if (mode_lib->vba.HRatio[k] > 1) {
1763 mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
1764 dml_min(
1765 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1766 mode_lib->vba.MaxPSCLToLBThroughput
1767 * mode_lib->vba.HRatio[k]
1768 / 2
1769 / dml_ceil(
1770 mode_lib->vba.HTAPsChroma[k]
1771 / 6.0,
1772 1.0));
1773 } else {
1774 mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
1775 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1776 mode_lib->vba.MaxPSCLToLBThroughput);
1777 }
1778 mode_lib->vba.DPPCLKUsingSingleDPPChroma =
1779 mode_lib->vba.PixelClock[k]
1780 * dml_max(
1781 mode_lib->vba.VTAPsChroma[k]
1782 / 6.0
1783 * dml_min(
1784 1.0,
1785 mode_lib->vba.HRatio[k]
1786 / 2),
1787 dml_max(
1788 mode_lib->vba.HRatio[k]
1789 * mode_lib->vba.VRatio[k]
1790 / 4
1791 / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
1792 1.0));
1793
1794 if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
1795 && mode_lib->vba.DPPCLKUsingSingleDPPChroma
1796 < 2 * mode_lib->vba.PixelClock[k]) {
1797 mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
1798 * mode_lib->vba.PixelClock[k];
1799 }
1800
1801 mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
1802 mode_lib->vba.DPPCLKUsingSingleDPPLuma,
1803 mode_lib->vba.DPPCLKUsingSingleDPPChroma);
1804 }
1805 }
1806
1807 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1808 if (mode_lib->vba.BlendingAndTiming[k] != k)
1809 continue;
1810 if (mode_lib->vba.ODMCombineEnabled[k]) {
1811 mode_lib->vba.DISPCLKWithRamping =
1812 dml_max(
1813 mode_lib->vba.DISPCLKWithRamping,
1814 mode_lib->vba.PixelClock[k] / 2
1815 * (1
1816 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1817 / 100)
1818 * (1
1819 + mode_lib->vba.DISPCLKRampingMargin
1820 / 100));
1821 mode_lib->vba.DISPCLKWithoutRamping =
1822 dml_max(
1823 mode_lib->vba.DISPCLKWithoutRamping,
1824 mode_lib->vba.PixelClock[k] / 2
1825 * (1
1826 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1827 / 100));
1828 } else if (!mode_lib->vba.ODMCombineEnabled[k]) {
1829 mode_lib->vba.DISPCLKWithRamping =
1830 dml_max(
1831 mode_lib->vba.DISPCLKWithRamping,
1832 mode_lib->vba.PixelClock[k]
1833 * (1
1834 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1835 / 100)
1836 * (1
1837 + mode_lib->vba.DISPCLKRampingMargin
1838 / 100));
1839 mode_lib->vba.DISPCLKWithoutRamping =
1840 dml_max(
1841 mode_lib->vba.DISPCLKWithoutRamping,
1842 mode_lib->vba.PixelClock[k]
1843 * (1
1844 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1845 / 100));
1846 }
1847 }
1848
1849 mode_lib->vba.DISPCLKWithRamping = dml_max(
1850 mode_lib->vba.DISPCLKWithRamping,
1851 mode_lib->vba.WritebackDISPCLK);
1852 mode_lib->vba.DISPCLKWithoutRamping = dml_max(
1853 mode_lib->vba.DISPCLKWithoutRamping,
1854 mode_lib->vba.WritebackDISPCLK);
1855
1856 ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
1857 mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
1858 mode_lib->vba.DISPCLKWithRamping,
1859 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1860 mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
1861 mode_lib->vba.DISPCLKWithoutRamping,
1862 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1863 mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
1864 mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz,
1865 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1866 if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
1867 > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
1868 mode_lib->vba.DISPCLK_calculated =
1869 mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
1870 } else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
1871 > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
1872 mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
1873 } else {
1874 mode_lib->vba.DISPCLK_calculated =
1875 mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
1876 }
1877 DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
1878
1879 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1880 mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
1881 / mode_lib->vba.DPPPerPlane[k]
1882 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
1883 mode_lib->vba.GlobalDPPCLK = dml_max(
1884 mode_lib->vba.GlobalDPPCLK,
1885 mode_lib->vba.DPPCLK_calculated[k]);
1886 }
1887 mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
1888 mode_lib->vba.GlobalDPPCLK,
1889 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1890 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1891 mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
1892 * dml_ceil(
1893 mode_lib->vba.DPPCLK_calculated[k] * 255
1894 / mode_lib->vba.GlobalDPPCLK,
1895 1);
1896 DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
1897 }
1898
1899 // Urgent Watermark
1900 mode_lib->vba.DCCEnabledAnyPlane = false;
1901 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
1902 if (mode_lib->vba.DCCEnable[k])
1903 mode_lib->vba.DCCEnabledAnyPlane = true;
1904
1905 mode_lib->vba.ReturnBandwidthToDCN = dml_min(
1906 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
1907 mode_lib->vba.FabricAndDRAMBandwidth * 1000)
1908 * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100;
1909
1910 mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
1911 mode_lib->vba.ReturnBW = adjust_ReturnBW(
1912 mode_lib,
1913 mode_lib->vba.ReturnBW,
1914 mode_lib->vba.DCCEnabledAnyPlane,
1915 mode_lib->vba.ReturnBandwidthToDCN);
1916
1917 // Let's do this calculation again??
1918 mode_lib->vba.ReturnBandwidthToDCN = dml_min(
1919 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
1920 mode_lib->vba.FabricAndDRAMBandwidth * 1000);
1921 mode_lib->vba.ReturnBW = adjust_ReturnBW(
1922 mode_lib,
1923 mode_lib->vba.ReturnBW,
1924 mode_lib->vba.DCCEnabledAnyPlane,
1925 mode_lib->vba.ReturnBandwidthToDCN);
1926
1927 DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK);
1928 DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN);
1929 DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW);
1930
1931 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1932 bool MainPlaneDoesODMCombine = false;
1933
1934 if (mode_lib->vba.SourceScan[k] == dm_horz)
1935 mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
1936 else
1937 mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
1938
1939 if (mode_lib->vba.ODMCombineEnabled[k] == true)
1940 MainPlaneDoesODMCombine = true;
1941 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
1942 if (mode_lib->vba.BlendingAndTiming[k] == j
1943 && mode_lib->vba.ODMCombineEnabled[j] == true)
1944 MainPlaneDoesODMCombine = true;
1945
1946 if (MainPlaneDoesODMCombine == true)
1947 mode_lib->vba.SwathWidthY[k] = dml_min(
1948 (double) mode_lib->vba.SwathWidthSingleDPPY[k],
1949 dml_round(
1950 mode_lib->vba.HActive[k] / 2.0
1951 * mode_lib->vba.HRatio[k]));
1952 else
1953 mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
1954 / mode_lib->vba.DPPPerPlane[k];
1955 }
1956
1957 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1958 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
1959 mode_lib->vba.BytePerPixelDETY[k] = 8;
1960 mode_lib->vba.BytePerPixelDETC[k] = 0;
1961 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
1962 mode_lib->vba.BytePerPixelDETY[k] = 4;
1963 mode_lib->vba.BytePerPixelDETC[k] = 0;
1964 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
1965 mode_lib->vba.BytePerPixelDETY[k] = 2;
1966 mode_lib->vba.BytePerPixelDETC[k] = 0;
1967 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
1968 mode_lib->vba.BytePerPixelDETY[k] = 1;
1969 mode_lib->vba.BytePerPixelDETC[k] = 0;
1970 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
1971 mode_lib->vba.BytePerPixelDETY[k] = 1;
1972 mode_lib->vba.BytePerPixelDETC[k] = 2;
1973 } else { // dm_420_10
1974 mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
1975 mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
1976 }
1977 }
1978
1979 mode_lib->vba.TotalDataReadBandwidth = 0.0;
1980 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1981 mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
1982 * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
1983 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
1984 * mode_lib->vba.VRatio[k];
1985 mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
1986 / 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
1987 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
1988 * mode_lib->vba.VRatio[k] / 2;
1989 DTRACE(
1990 " read_bw[%i] = %fBps",
1991 k,
1992 mode_lib->vba.ReadBandwidthPlaneLuma[k]
1993 + mode_lib->vba.ReadBandwidthPlaneChroma[k]);
1994 mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
1995 + mode_lib->vba.ReadBandwidthPlaneChroma[k];
1996 }
1997
1998 mode_lib->vba.TotalDCCActiveDPP = 0;
1999 mode_lib->vba.TotalActiveDPP = 0;
2000 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2001 mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
2002 + mode_lib->vba.DPPPerPlane[k];
2003 if (mode_lib->vba.DCCEnable[k])
2004 mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
2005 + mode_lib->vba.DPPPerPlane[k];
2006 }
2007
2008 mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
2009 (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
2010 + mode_lib->vba.UrgentOutOfOrderReturnPerChannel
2011 * mode_lib->vba.NumberOfChannels
2012 / mode_lib->vba.ReturnBW;
2013
2014 mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
2015 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2016 double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma;
2017
2018 if (mode_lib->vba.VRatio[k] <= 1.0)
2019 mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
2020 (double) mode_lib->vba.SwathWidthY[k]
2021 * mode_lib->vba.DPPPerPlane[k]
2022 / mode_lib->vba.HRatio[k]
2023 / mode_lib->vba.PixelClock[k];
2024 else
2025 mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
2026 (double) mode_lib->vba.SwathWidthY[k]
2027 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2028 / mode_lib->vba.DPPCLK[k];
2029
2030 DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k]
2031 * mode_lib->vba.SwathHeightY[k]
2032 * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
2033 / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k]
2034 / mode_lib->vba.TotalDataReadBandwidth);
2035 mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(
2036 mode_lib->vba.LastPixelOfLineExtraWatermark,
2037 DataFabricLineDeliveryTimeLuma
2038 - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]);
2039
2040 if (mode_lib->vba.BytePerPixelDETC[k] == 0)
2041 mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0;
2042 else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0)
2043 mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
2044 mode_lib->vba.SwathWidthY[k] / 2.0
2045 * mode_lib->vba.DPPPerPlane[k]
2046 / (mode_lib->vba.HRatio[k] / 2.0)
2047 / mode_lib->vba.PixelClock[k];
2048 else
2049 mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
2050 mode_lib->vba.SwathWidthY[k] / 2.0
2051 / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
2052 / mode_lib->vba.DPPCLK[k];
2053
2054 DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0
2055 * mode_lib->vba.SwathHeightC[k]
2056 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
2057 / (mode_lib->vba.ReturnBW
2058 * mode_lib->vba.ReadBandwidthPlaneChroma[k]
2059 / mode_lib->vba.TotalDataReadBandwidth);
2060 mode_lib->vba.LastPixelOfLineExtraWatermark =
2061 dml_max(
2062 mode_lib->vba.LastPixelOfLineExtraWatermark,
2063 DataFabricLineDeliveryTimeChroma
2064 - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
2065 }
2066
2067 mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
2068 + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
2069 + mode_lib->vba.TotalDCCActiveDPP
2070 * mode_lib->vba.MetaChunkSize) * 1024.0
2071 / mode_lib->vba.ReturnBW;
2072
2073 if (mode_lib->vba.VirtualMemoryEnable)
2074 mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
2075 * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW;
2076
2077 mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency
2078 + mode_lib->vba.LastPixelOfLineExtraWatermark
2079 + mode_lib->vba.UrgentExtraLatency;
2080
2081 DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
2082 DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
2083
2084 mode_lib->vba.MemoryTripWatermark = mode_lib->vba.UrgentLatency;
2085
2086 mode_lib->vba.TotalActiveWriteback = 0;
2087 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2088 if (mode_lib->vba.WritebackEnable[k])
2089 mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
2090 }
2091
2092 if (mode_lib->vba.TotalActiveWriteback <= 1)
2093 mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
2094 else
2095 mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
2096 + mode_lib->vba.WritebackChunkSize * 1024.0 / 32
2097 / mode_lib->vba.SOCCLK;
2098
2099 DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
2100
2101 // NB P-State/DRAM Clock Change Watermark
2102 mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
2103 + mode_lib->vba.UrgentWatermark;
2104
2105 DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
2106
2107 DTRACE(" calculating wb pstate watermark");
2108 DTRACE(" total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
2109 DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
2110
2111 if (mode_lib->vba.TotalActiveWriteback <= 1)
2112 mode_lib->vba.WritebackDRAMClockChangeWatermark =
2113 mode_lib->vba.DRAMClockChangeLatency
2114 + mode_lib->vba.WritebackLatency;
2115 else
2116 mode_lib->vba.WritebackDRAMClockChangeWatermark =
2117 mode_lib->vba.DRAMClockChangeLatency
2118 + mode_lib->vba.WritebackLatency
2119 + mode_lib->vba.WritebackChunkSize * 1024.0 / 32
2120 / mode_lib->vba.SOCCLK;
2121
2122 DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
2123
2124 // Stutter Efficiency
2125 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2126 mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
2127 / mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
2128 mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
2129 mode_lib->vba.LinesInDETY[k],
2130 mode_lib->vba.SwathHeightY[k]);
2131 mode_lib->vba.FullDETBufferingTimeY[k] =
2132 mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
2133 * (mode_lib->vba.HTotal[k]
2134 / mode_lib->vba.PixelClock[k])
2135 / mode_lib->vba.VRatio[k];
2136 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
2137 mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k]
2138 / mode_lib->vba.BytePerPixelDETC[k]
2139 / (mode_lib->vba.SwathWidthY[k] / 2);
2140 mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(
2141 mode_lib->vba.LinesInDETC[k],
2142 mode_lib->vba.SwathHeightC[k]);
2143 mode_lib->vba.FullDETBufferingTimeC[k] =
2144 mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
2145 * (mode_lib->vba.HTotal[k]
2146 / mode_lib->vba.PixelClock[k])
2147 / (mode_lib->vba.VRatio[k] / 2);
2148 } else {
2149 mode_lib->vba.LinesInDETC[k] = 0;
2150 mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
2151 mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
2152 }
2153 }
2154
2155 mode_lib->vba.MinFullDETBufferingTime = 999999.0;
2156 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2157 if (mode_lib->vba.FullDETBufferingTimeY[k]
2158 < mode_lib->vba.MinFullDETBufferingTime) {
2159 mode_lib->vba.MinFullDETBufferingTime =
2160 mode_lib->vba.FullDETBufferingTimeY[k];
2161 mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
2162 (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
2163 / mode_lib->vba.PixelClock[k];
2164 }
2165 if (mode_lib->vba.FullDETBufferingTimeC[k]
2166 < mode_lib->vba.MinFullDETBufferingTime) {
2167 mode_lib->vba.MinFullDETBufferingTime =
2168 mode_lib->vba.FullDETBufferingTimeC[k];
2169 mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
2170 (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
2171 / mode_lib->vba.PixelClock[k];
2172 }
2173 }
2174
2175 mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
2176 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2177 if (mode_lib->vba.DCCEnable[k]) {
2178 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2179 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2180 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2181 / mode_lib->vba.DCCRate[k]
2182 / 1000
2183 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2184 / mode_lib->vba.DCCRate[k]
2185 / 1000;
2186 } else {
2187 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2188 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2189 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2190 / 1000
2191 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2192 / 1000;
2193 }
2194 if (mode_lib->vba.DCCEnable[k]) {
2195 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2196 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2197 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2198 / 1000 / 256
2199 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2200 / 1000 / 256;
2201 }
2202 if (mode_lib->vba.VirtualMemoryEnable) {
2203 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2204 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2205 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2206 / 1000 / 512
2207 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2208 / 1000 / 512;
2209 }
2210 }
2211
2212 mode_lib->vba.PartOfBurstThatFitsInROB =
2213 dml_min(
2214 mode_lib->vba.MinFullDETBufferingTime
2215 * mode_lib->vba.TotalDataReadBandwidth,
2216 mode_lib->vba.ROBBufferSizeInKByte * 1024
2217 * mode_lib->vba.TotalDataReadBandwidth
2218 / (mode_lib->vba.AverageReadBandwidthGBytePerSecond
2219 * 1000));
2220 mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
2221 * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
2222 / mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
2223 + (mode_lib->vba.MinFullDETBufferingTime
2224 * mode_lib->vba.TotalDataReadBandwidth
2225 - mode_lib->vba.PartOfBurstThatFitsInROB)
2226 / (mode_lib->vba.DCFCLK * 64);
2227 if (mode_lib->vba.TotalActiveWriteback == 0) {
2228 mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
2229 - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
2230 / mode_lib->vba.MinFullDETBufferingTime) * 100;
2231 } else {
2232 mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
2233 }
2234
2235 mode_lib->vba.SmallestVBlank = 999999;
2236 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2237 if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
2238 mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
2239 - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
2240 / mode_lib->vba.PixelClock[k];
2241 } else {
2242 mode_lib->vba.VBlankTime = 0;
2243 }
2244 mode_lib->vba.SmallestVBlank = dml_min(
2245 mode_lib->vba.SmallestVBlank,
2246 mode_lib->vba.VBlankTime);
2247 }
2248
2249 mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
2250 * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
2251 - mode_lib->vba.SmallestVBlank)
2252 + mode_lib->vba.SmallestVBlank)
2253 / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
2254
2255 // dml_ml->vba.DCFCLK Deep Sleep
2256 mode_lib->vba.DCFClkDeepSleep = 8.0;
2257
2258 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
2259 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
2260 mode_lib->vba.DCFCLKDeepSleepPerPlane =
2261 dml_max(
2262 1.1 * mode_lib->vba.SwathWidthY[k]
2263 * dml_ceil(
2264 mode_lib->vba.BytePerPixelDETY[k],
2265 1) / 32
2266 / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
2267 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
2268 * dml_ceil(
2269 mode_lib->vba.BytePerPixelDETC[k],
2270 2) / 32
2271 / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
2272 } else
2273 mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k]
2274 * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
2275 / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
2276 mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(
2277 mode_lib->vba.DCFCLKDeepSleepPerPlane,
2278 mode_lib->vba.PixelClock[k] / 16.0);
2279 mode_lib->vba.DCFClkDeepSleep = dml_max(
2280 mode_lib->vba.DCFClkDeepSleep,
2281 mode_lib->vba.DCFCLKDeepSleepPerPlane);
2282
2283 DTRACE(
2284 " dcfclk_deepsleep_per_plane[%i] = %fMHz",
2285 k,
2286 mode_lib->vba.DCFCLKDeepSleepPerPlane);
2287 }
2288
2289 DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep);
2290
2291 // Stutter Watermark
2292 mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
2293 + mode_lib->vba.LastPixelOfLineExtraWatermark
2294 + mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFClkDeepSleep;
2295 mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
2296 + mode_lib->vba.LastPixelOfLineExtraWatermark
2297 + mode_lib->vba.UrgentExtraLatency;
2298
2299 DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark);
2300 DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
2301
2302 // Urgent Latency Supported
2303 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2304 mode_lib->vba.EffectiveDETPlusLBLinesLuma =
2305 dml_floor(
2306 mode_lib->vba.LinesInDETY[k]
2307 + dml_min(
2308 mode_lib->vba.LinesInDETY[k]
2309 * mode_lib->vba.DPPCLK[k]
2310 * mode_lib->vba.BytePerPixelDETY[k]
2311 * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2312 / (mode_lib->vba.ReturnBW
2313 / mode_lib->vba.DPPPerPlane[k]),
2314 (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
2315 mode_lib->vba.SwathHeightY[k]);
2316
2317 mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
2318 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
2319 / mode_lib->vba.VRatio[k]
2320 - mode_lib->vba.EffectiveDETPlusLBLinesLuma
2321 * mode_lib->vba.SwathWidthY[k]
2322 * mode_lib->vba.BytePerPixelDETY[k]
2323 / (mode_lib->vba.ReturnBW
2324 / mode_lib->vba.DPPPerPlane[k]);
2325
2326 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
2327 mode_lib->vba.EffectiveDETPlusLBLinesChroma =
2328 dml_floor(
2329 mode_lib->vba.LinesInDETC[k]
2330 + dml_min(
2331 mode_lib->vba.LinesInDETC[k]
2332 * mode_lib->vba.DPPCLK[k]
2333 * mode_lib->vba.BytePerPixelDETC[k]
2334 * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
2335 / (mode_lib->vba.ReturnBW
2336 / mode_lib->vba.DPPPerPlane[k]),
2337 (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
2338 mode_lib->vba.SwathHeightC[k]);
2339 mode_lib->vba.UrgentLatencySupportUsChroma =
2340 mode_lib->vba.EffectiveDETPlusLBLinesChroma
2341 * (mode_lib->vba.HTotal[k]
2342 / mode_lib->vba.PixelClock[k])
2343 / (mode_lib->vba.VRatio[k] / 2)
2344 - mode_lib->vba.EffectiveDETPlusLBLinesChroma
2345 * (mode_lib->vba.SwathWidthY[k]
2346 / 2)
2347 * mode_lib->vba.BytePerPixelDETC[k]
2348 / (mode_lib->vba.ReturnBW
2349 / mode_lib->vba.DPPPerPlane[k]);
2350 mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
2351 mode_lib->vba.UrgentLatencySupportUsLuma,
2352 mode_lib->vba.UrgentLatencySupportUsChroma);
2353 } else {
2354 mode_lib->vba.UrgentLatencySupportUs[k] =
2355 mode_lib->vba.UrgentLatencySupportUsLuma;
2356 }
2357 }
2358
2359 mode_lib->vba.MinUrgentLatencySupportUs = 999999;
2360 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2361 mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
2362 mode_lib->vba.MinUrgentLatencySupportUs,
2363 mode_lib->vba.UrgentLatencySupportUs[k]);
2364 }
2365
2366 // Non-Urgent Latency Tolerance
2367 mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
2368 - mode_lib->vba.UrgentWatermark;
2369
2370 // DSCCLK
2371 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2372 if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
2373 mode_lib->vba.DSCCLK_calculated[k] = 0.0;
2374 } else {
2375 if (mode_lib->vba.OutputFormat[k] == dm_420
2376 || mode_lib->vba.OutputFormat[k] == dm_n422)
2377 mode_lib->vba.DSCFormatFactor = 2;
2378 else
2379 mode_lib->vba.DSCFormatFactor = 1;
2380 if (mode_lib->vba.ODMCombineEnabled[k])
2381 mode_lib->vba.DSCCLK_calculated[k] =
2382 mode_lib->vba.PixelClockBackEnd[k] / 6
2383 / mode_lib->vba.DSCFormatFactor
2384 / (1
2385 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
2386 / 100);
2387 else
2388 mode_lib->vba.DSCCLK_calculated[k] =
2389 mode_lib->vba.PixelClockBackEnd[k] / 3
2390 / mode_lib->vba.DSCFormatFactor
2391 / (1
2392 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
2393 / 100);
2394 }
2395 }
2396
2397 // DSC Delay
2398 // TODO
2399 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2400 double bpp = mode_lib->vba.OutputBpp[k];
2401 unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
2402
2403 if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
2404 if (!mode_lib->vba.ODMCombineEnabled[k]) {
2405 mode_lib->vba.DSCDelay[k] =
2406 dscceComputeDelay(
2407 mode_lib->vba.DSCInputBitPerComponent[k],
2408 bpp,
2409 dml_ceil(
2410 (double) mode_lib->vba.HActive[k]
2411 / mode_lib->vba.NumberOfDSCSlices[k],
2412 1),
2413 slices,
2414 mode_lib->vba.OutputFormat[k])
2415 + dscComputeDelay(
2416 mode_lib->vba.OutputFormat[k]);
2417 } else {
2418 mode_lib->vba.DSCDelay[k] =
2419 2
2420 * (dscceComputeDelay(
2421 mode_lib->vba.DSCInputBitPerComponent[k],
2422 bpp,
2423 dml_ceil(
2424 (double) mode_lib->vba.HActive[k]
2425 / mode_lib->vba.NumberOfDSCSlices[k],
2426 1),
2427 slices / 2.0,
2428 mode_lib->vba.OutputFormat[k])
2429 + dscComputeDelay(
2430 mode_lib->vba.OutputFormat[k]));
2431 }
2432 mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k]
2433 * mode_lib->vba.PixelClock[k]
2434 / mode_lib->vba.PixelClockBackEnd[k];
2435 } else {
2436 mode_lib->vba.DSCDelay[k] = 0;
2437 }
2438 }
2439
2440 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
2441 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes
2442 if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
2443 && mode_lib->vba.DSCEnabled[j])
2444 mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
2445
2446 // Prefetch
2447 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2448 unsigned int PDEAndMetaPTEBytesFrameY;
2449 unsigned int PixelPTEBytesPerRowY;
2450 unsigned int MetaRowByteY;
2451 unsigned int MetaRowByteC;
2452 unsigned int PDEAndMetaPTEBytesFrameC;
2453 unsigned int PixelPTEBytesPerRowC;
2454
2455 Calculate256BBlockSizes(
2456 mode_lib->vba.SourcePixelFormat[k],
2457 mode_lib->vba.SurfaceTiling[k],
2458 dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
2459 dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
2460 &mode_lib->vba.BlockHeight256BytesY[k],
2461 &mode_lib->vba.BlockHeight256BytesC[k],
2462 &mode_lib->vba.BlockWidth256BytesY[k],
2463 &mode_lib->vba.BlockWidth256BytesC[k]);
2464 PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
2465 mode_lib,
2466 mode_lib->vba.DCCEnable[k],
2467 mode_lib->vba.BlockHeight256BytesY[k],
2468 mode_lib->vba.BlockWidth256BytesY[k],
2469 mode_lib->vba.SourcePixelFormat[k],
2470 mode_lib->vba.SurfaceTiling[k],
2471 dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
2472 mode_lib->vba.SourceScan[k],
2473 mode_lib->vba.ViewportWidth[k],
2474 mode_lib->vba.ViewportHeight[k],
2475 mode_lib->vba.SwathWidthY[k],
2476 mode_lib->vba.VirtualMemoryEnable,
2477 mode_lib->vba.VMMPageSize,
2478 mode_lib->vba.PTEBufferSizeInRequests,
2479 mode_lib->vba.PDEProcessingBufIn64KBReqs,
2480 mode_lib->vba.PitchY[k],
2481 mode_lib->vba.DCCMetaPitchY[k],
2482 &mode_lib->vba.MacroTileWidthY[k],
2483 &MetaRowByteY,
2484 &PixelPTEBytesPerRowY,
2485 &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
2486 &mode_lib->vba.dpte_row_height[k],
2487 &mode_lib->vba.meta_row_height[k]);
2488 mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
2489 mode_lib,
2490 mode_lib->vba.VRatio[k],
2491 mode_lib->vba.vtaps[k],
2492 mode_lib->vba.Interlace[k],
2493 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
2494 mode_lib->vba.SwathHeightY[k],
2495 mode_lib->vba.ViewportYStartY[k],
2496 &mode_lib->vba.VInitPreFillY[k],
2497 &mode_lib->vba.MaxNumSwathY[k]);
2498
2499 if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
2500 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
2501 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
2502 && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
2503 PDEAndMetaPTEBytesFrameC =
2504 CalculateVMAndRowBytes(
2505 mode_lib,
2506 mode_lib->vba.DCCEnable[k],
2507 mode_lib->vba.BlockHeight256BytesC[k],
2508 mode_lib->vba.BlockWidth256BytesC[k],
2509 mode_lib->vba.SourcePixelFormat[k],
2510 mode_lib->vba.SurfaceTiling[k],
2511 dml_ceil(
2512 mode_lib->vba.BytePerPixelDETC[k],
2513 2),
2514 mode_lib->vba.SourceScan[k],
2515 mode_lib->vba.ViewportWidth[k] / 2,
2516 mode_lib->vba.ViewportHeight[k] / 2,
2517 mode_lib->vba.SwathWidthY[k] / 2,
2518 mode_lib->vba.VirtualMemoryEnable,
2519 mode_lib->vba.VMMPageSize,
2520 mode_lib->vba.PTEBufferSizeInRequests,
2521 mode_lib->vba.PDEProcessingBufIn64KBReqs,
2522 mode_lib->vba.PitchC[k],
2523 0,
2524 &mode_lib->vba.MacroTileWidthC[k],
2525 &MetaRowByteC,
2526 &PixelPTEBytesPerRowC,
2527 &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
2528 &mode_lib->vba.dpte_row_height_chroma[k],
2529 &mode_lib->vba.meta_row_height_chroma[k]);
2530 mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
2531 mode_lib,
2532 mode_lib->vba.VRatio[k] / 2,
2533 mode_lib->vba.VTAPsChroma[k],
2534 mode_lib->vba.Interlace[k],
2535 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
2536 mode_lib->vba.SwathHeightC[k],
2537 mode_lib->vba.ViewportYStartC[k],
2538 &mode_lib->vba.VInitPreFillC[k],
2539 &mode_lib->vba.MaxNumSwathC[k]);
2540 } else {
2541 PixelPTEBytesPerRowC = 0;
2542 PDEAndMetaPTEBytesFrameC = 0;
2543 MetaRowByteC = 0;
2544 mode_lib->vba.MaxNumSwathC[k] = 0;
2545 mode_lib->vba.PrefetchSourceLinesC[k] = 0;
2546 }
2547
2548 mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
2549 mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
2550 + PDEAndMetaPTEBytesFrameC;
2551 mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
2552
2553 CalculateActiveRowBandwidth(
2554 mode_lib->vba.VirtualMemoryEnable,
2555 mode_lib->vba.SourcePixelFormat[k],
2556 mode_lib->vba.VRatio[k],
2557 mode_lib->vba.DCCEnable[k],
2558 mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
2559 MetaRowByteY,
2560 MetaRowByteC,
2561 mode_lib->vba.meta_row_height[k],
2562 mode_lib->vba.meta_row_height_chroma[k],
2563 PixelPTEBytesPerRowY,
2564 PixelPTEBytesPerRowC,
2565 mode_lib->vba.dpte_row_height[k],
2566 mode_lib->vba.dpte_row_height_chroma[k],
2567 &mode_lib->vba.meta_row_bw[k],
2568 &mode_lib->vba.dpte_row_bw[k],
2569 &mode_lib->vba.qual_row_bw[k]);
2570 }
2571
2572 mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep;
2573
2574 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2575 if (mode_lib->vba.BlendingAndTiming[k] == k) {
2576 if (mode_lib->vba.WritebackEnable[k] == true) {
2577 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
2578 mode_lib->vba.WritebackLatency
2579 + CalculateWriteBackDelay(
2580 mode_lib->vba.WritebackPixelFormat[k],
2581 mode_lib->vba.WritebackHRatio[k],
2582 mode_lib->vba.WritebackVRatio[k],
2583 mode_lib->vba.WritebackLumaHTaps[k],
2584 mode_lib->vba.WritebackLumaVTaps[k],
2585 mode_lib->vba.WritebackChromaHTaps[k],
2586 mode_lib->vba.WritebackChromaVTaps[k],
2587 mode_lib->vba.WritebackDestinationWidth[k])
2588 / mode_lib->vba.DISPCLK;
2589 } else
2590 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
2591 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
2592 if (mode_lib->vba.BlendingAndTiming[j] == k
2593 && mode_lib->vba.WritebackEnable[j] == true) {
2594 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
2595 dml_max(
2596 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
2597 mode_lib->vba.WritebackLatency
2598 + CalculateWriteBackDelay(
2599 mode_lib->vba.WritebackPixelFormat[j],
2600 mode_lib->vba.WritebackHRatio[j],
2601 mode_lib->vba.WritebackVRatio[j],
2602 mode_lib->vba.WritebackLumaHTaps[j],
2603 mode_lib->vba.WritebackLumaVTaps[j],
2604 mode_lib->vba.WritebackChromaHTaps[j],
2605 mode_lib->vba.WritebackChromaVTaps[j],
2606 mode_lib->vba.WritebackDestinationWidth[j])
2607 / mode_lib->vba.DISPCLK);
2608 }
2609 }
2610 }
2611 }
2612
2613 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
2614 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
2615 if (mode_lib->vba.BlendingAndTiming[k] == j)
2616 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
2617 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
2618
2619 mode_lib->vba.VStartupLines = 13;
2620 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2621 mode_lib->vba.MaxVStartupLines[k] =
2622 mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
2623 - dml_max(
2624 1.0,
2625 dml_ceil(
2626 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
2627 / (mode_lib->vba.HTotal[k]
2628 / mode_lib->vba.PixelClock[k]),
2629 1));
2630 }
2631
2632 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
2633 mode_lib->vba.MaximumMaxVStartupLines = dml_max(
2634 mode_lib->vba.MaximumMaxVStartupLines,
2635 mode_lib->vba.MaxVStartupLines[k]);
2636
2637 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2638 mode_lib->vba.cursor_bw[k] = 0.0;
2639 for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
2640 mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
2641 * mode_lib->vba.CursorBPP[k][j] / 8.0
2642 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
2643 * mode_lib->vba.VRatio[k];
2644 }
2645
2646 do {
2647 double MaxTotalRDBandwidth = 0;
2648 bool DestinationLineTimesForPrefetchLessThan2 = false;
2649 bool VRatioPrefetchMoreThan4 = false;
2650 bool prefetch_vm_bw_valid = true;
2651 bool prefetch_row_bw_valid = true;
2652 double TWait = CalculateTWait(
2653 mode_lib->vba.PrefetchMode,
2654 mode_lib->vba.DRAMClockChangeLatency,
2655 mode_lib->vba.UrgentLatency,
2656 mode_lib->vba.SREnterPlusExitTime);
2657
2658 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2659 if (mode_lib->vba.XFCEnabled[k] == true) {
2660 mode_lib->vba.XFCRemoteSurfaceFlipDelay =
2661 CalculateRemoteSurfaceFlipDelay(
2662 mode_lib,
2663 mode_lib->vba.VRatio[k],
2664 mode_lib->vba.SwathWidthY[k],
2665 dml_ceil(
2666 mode_lib->vba.BytePerPixelDETY[k],
2667 1),
2668 mode_lib->vba.HTotal[k]
2669 / mode_lib->vba.PixelClock[k],
2670 mode_lib->vba.XFCTSlvVupdateOffset,
2671 mode_lib->vba.XFCTSlvVupdateWidth,
2672 mode_lib->vba.XFCTSlvVreadyOffset,
2673 mode_lib->vba.XFCXBUFLatencyTolerance,
2674 mode_lib->vba.XFCFillBWOverhead,
2675 mode_lib->vba.XFCSlvChunkSize,
2676 mode_lib->vba.XFCBusTransportTime,
2677 mode_lib->vba.TCalc,
2678 TWait,
2679 &mode_lib->vba.SrcActiveDrainRate,
2680 &mode_lib->vba.TInitXFill,
2681 &mode_lib->vba.TslvChk);
2682 } else {
2683 mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
2684 }
2685 mode_lib->vba.ErrorResult[k] =
2686 CalculatePrefetchSchedule(
2687 mode_lib,
2688 mode_lib->vba.DPPCLK[k],
2689 mode_lib->vba.DISPCLK,
2690 mode_lib->vba.PixelClock[k],
2691 mode_lib->vba.DCFClkDeepSleep,
2692 mode_lib->vba.DSCDelay[k],
2693 mode_lib->vba.DPPPerPlane[k],
2694 mode_lib->vba.ScalerEnabled[k],
2695 mode_lib->vba.NumberOfCursors[k],
2696 mode_lib->vba.DPPCLKDelaySubtotal,
2697 mode_lib->vba.DPPCLKDelaySCL,
2698 mode_lib->vba.DPPCLKDelaySCLLBOnly,
2699 mode_lib->vba.DPPCLKDelayCNVCFormater,
2700 mode_lib->vba.DPPCLKDelayCNVCCursor,
2701 mode_lib->vba.DISPCLKDelaySubtotal,
2702 (unsigned int) (mode_lib->vba.SwathWidthY[k]
2703 / mode_lib->vba.HRatio[k]),
2704 mode_lib->vba.OutputFormat[k],
2705 mode_lib->vba.VTotal[k]
2706 - mode_lib->vba.VActive[k],
2707 mode_lib->vba.HTotal[k],
2708 mode_lib->vba.MaxInterDCNTileRepeaters,
2709 dml_min(
2710 mode_lib->vba.VStartupLines,
2711 mode_lib->vba.MaxVStartupLines[k]),
2712 mode_lib->vba.MaxPageTableLevels,
2713 mode_lib->vba.VirtualMemoryEnable,
2714 mode_lib->vba.DynamicMetadataEnable[k],
2715 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
2716 mode_lib->vba.DynamicMetadataTransmittedBytes[k],
2717 mode_lib->vba.DCCEnable[k],
2718 mode_lib->vba.UrgentLatency,
2719 mode_lib->vba.UrgentExtraLatency,
2720 mode_lib->vba.TCalc,
2721 mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
2722 mode_lib->vba.MetaRowByte[k],
2723 mode_lib->vba.PixelPTEBytesPerRow[k],
2724 mode_lib->vba.PrefetchSourceLinesY[k],
2725 mode_lib->vba.SwathWidthY[k],
2726 mode_lib->vba.BytePerPixelDETY[k],
2727 mode_lib->vba.VInitPreFillY[k],
2728 mode_lib->vba.MaxNumSwathY[k],
2729 mode_lib->vba.PrefetchSourceLinesC[k],
2730 mode_lib->vba.BytePerPixelDETC[k],
2731 mode_lib->vba.VInitPreFillC[k],
2732 mode_lib->vba.MaxNumSwathC[k],
2733 mode_lib->vba.SwathHeightY[k],
2734 mode_lib->vba.SwathHeightC[k],
2735 TWait,
2736 mode_lib->vba.XFCEnabled[k],
2737 mode_lib->vba.XFCRemoteSurfaceFlipDelay,
2738 mode_lib->vba.Interlace[k],
2739 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
2740 &mode_lib->vba.DSTXAfterScaler[k],
2741 &mode_lib->vba.DSTYAfterScaler[k],
2742 &mode_lib->vba.DestinationLinesForPrefetch[k],
2743 &mode_lib->vba.PrefetchBandwidth[k],
2744 &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
2745 &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
2746 &mode_lib->vba.VRatioPrefetchY[k],
2747 &mode_lib->vba.VRatioPrefetchC[k],
2748 &mode_lib->vba.RequiredPrefetchPixDataBW[k],
2749 &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
2750 &mode_lib->vba.Tno_bw[k],
2751 &mode_lib->vba.VUpdateOffsetPix[k],
2752 &mode_lib->vba.VUpdateWidthPix[k],
2753 &mode_lib->vba.VReadyOffsetPix[k]);
2754 if (mode_lib->vba.BlendingAndTiming[k] == k) {
2755 mode_lib->vba.VStartup[k] = dml_min(
2756 mode_lib->vba.VStartupLines,
2757 mode_lib->vba.MaxVStartupLines[k]);
2758 if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
2759 != 0) {
2760 mode_lib->vba.VStartup[k] =
2761 mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
2762 }
2763 } else {
2764 mode_lib->vba.VStartup[k] =
2765 dml_min(
2766 mode_lib->vba.VStartupLines,
2767 mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
2768 }
2769 }
2770
2771 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2772
2773 if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
2774 mode_lib->vba.prefetch_vm_bw[k] = 0;
2775 else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
2776 mode_lib->vba.prefetch_vm_bw[k] =
2777 (double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
2778 / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
2779 * mode_lib->vba.HTotal[k]
2780 / mode_lib->vba.PixelClock[k]);
2781 } else {
2782 mode_lib->vba.prefetch_vm_bw[k] = 0;
2783 prefetch_vm_bw_valid = false;
2784 }
2785 if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
2786 == 0)
2787 mode_lib->vba.prefetch_row_bw[k] = 0;
2788 else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
2789 mode_lib->vba.prefetch_row_bw[k] =
2790 (double) (mode_lib->vba.MetaRowByte[k]
2791 + mode_lib->vba.PixelPTEBytesPerRow[k])
2792 / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
2793 * mode_lib->vba.HTotal[k]
2794 / mode_lib->vba.PixelClock[k]);
2795 } else {
2796 mode_lib->vba.prefetch_row_bw[k] = 0;
2797 prefetch_row_bw_valid = false;
2798 }
2799
2800 MaxTotalRDBandwidth =
2801 MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
2802 + dml_max(
2803 mode_lib->vba.prefetch_vm_bw[k],
2804 dml_max(
2805 mode_lib->vba.prefetch_row_bw[k],
2806 dml_max(
2807 mode_lib->vba.ReadBandwidthPlaneLuma[k]
2808 + mode_lib->vba.ReadBandwidthPlaneChroma[k],
2809 mode_lib->vba.RequiredPrefetchPixDataBW[k])
2810 + mode_lib->vba.meta_row_bw[k]
2811 + mode_lib->vba.dpte_row_bw[k]));
2812
2813 if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
2814 DestinationLineTimesForPrefetchLessThan2 = true;
2815 if (mode_lib->vba.VRatioPrefetchY[k] > 4
2816 || mode_lib->vba.VRatioPrefetchC[k] > 4)
2817 VRatioPrefetchMoreThan4 = true;
2818 }
2819
2820 if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
2821 && prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
2822 && !DestinationLineTimesForPrefetchLessThan2)
2823 mode_lib->vba.PrefetchModeSupported = true;
2824 else {
2825 mode_lib->vba.PrefetchModeSupported = false;
2826 dml_print(
2827 "DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
2828 }
2829
2830 if (mode_lib->vba.PrefetchModeSupported == true) {
2831 double final_flip_bw[DC__NUM_DPP__MAX];
2832 unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
2833 double total_dcn_read_bw_with_flip = 0;
2834
2835 mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
2836 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2837 mode_lib->vba.BandwidthAvailableForImmediateFlip =
2838 mode_lib->vba.BandwidthAvailableForImmediateFlip
2839 - mode_lib->vba.cursor_bw[k]
2840 - dml_max(
2841 mode_lib->vba.ReadBandwidthPlaneLuma[k]
2842 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2843 + mode_lib->vba.qual_row_bw[k],
2844 mode_lib->vba.PrefetchBandwidth[k]);
2845 }
2846
2847 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2848 ImmediateFlipBytes[k] = 0;
2849 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
2850 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
2851 ImmediateFlipBytes[k] =
2852 mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
2853 + mode_lib->vba.MetaRowByte[k]
2854 + mode_lib->vba.PixelPTEBytesPerRow[k];
2855 }
2856 }
2857 mode_lib->vba.TotImmediateFlipBytes = 0;
2858 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2859 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
2860 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
2861 mode_lib->vba.TotImmediateFlipBytes =
2862 mode_lib->vba.TotImmediateFlipBytes
2863 + ImmediateFlipBytes[k];
2864 }
2865 }
2866 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2867 CalculateFlipSchedule(
2868 mode_lib,
2869 mode_lib->vba.UrgentExtraLatency,
2870 mode_lib->vba.UrgentLatency,
2871 mode_lib->vba.MaxPageTableLevels,
2872 mode_lib->vba.VirtualMemoryEnable,
2873 mode_lib->vba.BandwidthAvailableForImmediateFlip,
2874 mode_lib->vba.TotImmediateFlipBytes,
2875 mode_lib->vba.SourcePixelFormat[k],
2876 ImmediateFlipBytes[k],
2877 mode_lib->vba.HTotal[k]
2878 / mode_lib->vba.PixelClock[k],
2879 mode_lib->vba.VRatio[k],
2880 mode_lib->vba.Tno_bw[k],
2881 mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
2882 mode_lib->vba.MetaRowByte[k],
2883 mode_lib->vba.PixelPTEBytesPerRow[k],
2884 mode_lib->vba.DCCEnable[k],
2885 mode_lib->vba.dpte_row_height[k],
2886 mode_lib->vba.meta_row_height[k],
2887 mode_lib->vba.qual_row_bw[k],
2888 &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
2889 &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
2890 &final_flip_bw[k],
2891 &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
2892 }
2893 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2894 total_dcn_read_bw_with_flip =
2895 total_dcn_read_bw_with_flip
2896 + mode_lib->vba.cursor_bw[k]
2897 + dml_max(
2898 mode_lib->vba.prefetch_vm_bw[k],
2899 dml_max(
2900 mode_lib->vba.prefetch_row_bw[k],
2901 final_flip_bw[k]
2902 + dml_max(
2903 mode_lib->vba.ReadBandwidthPlaneLuma[k]
2904 + mode_lib->vba.ReadBandwidthPlaneChroma[k],
2905 mode_lib->vba.RequiredPrefetchPixDataBW[k])));
2906 }
2907 mode_lib->vba.ImmediateFlipSupported = true;
2908 if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
2909 mode_lib->vba.ImmediateFlipSupported = false;
2910 }
2911 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2912 if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
2913 mode_lib->vba.ImmediateFlipSupported = false;
2914 }
2915 }
2916 } else {
2917 mode_lib->vba.ImmediateFlipSupported = false;
2918 }
2919
2920 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2921 if (mode_lib->vba.ErrorResult[k]) {
2922 mode_lib->vba.PrefetchModeSupported = false;
2923 dml_print(
2924 "DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
2925 }
2926 }
2927
2928 mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
2929 } while (!((mode_lib->vba.PrefetchModeSupported
2930 && (!mode_lib->vba.ImmediateFlipSupport
2931 || mode_lib->vba.ImmediateFlipSupported))
2932 || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
2933
2934 //Display Pipeline Delivery Time in Prefetch
2935 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2936 if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
2937 mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
2938 mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
2939 / mode_lib->vba.HRatio[k]
2940 / mode_lib->vba.PixelClock[k];
2941 } else {
2942 mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
2943 mode_lib->vba.SwathWidthY[k]
2944 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2945 / mode_lib->vba.DPPCLK[k];
2946 }
2947 if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
2948 mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
2949 } else {
2950 if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
2951 mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
2952 mode_lib->vba.SwathWidthY[k]
2953 * mode_lib->vba.DPPPerPlane[k]
2954 / mode_lib->vba.HRatio[k]
2955 / mode_lib->vba.PixelClock[k];
2956 } else {
2957 mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
2958 mode_lib->vba.SwathWidthY[k]
2959 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2960 / mode_lib->vba.DPPCLK[k];
2961 }
2962 }
2963 }
2964
2965 // Min TTUVBlank
2966 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2967 if (mode_lib->vba.PrefetchMode == 0) {
2968 mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
2969 mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
2970 mode_lib->vba.MinTTUVBlank[k] = dml_max(
2971 mode_lib->vba.DRAMClockChangeWatermark,
2972 dml_max(
2973 mode_lib->vba.StutterEnterPlusExitWatermark,
2974 mode_lib->vba.UrgentWatermark));
2975 } else if (mode_lib->vba.PrefetchMode == 1) {
2976 mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
2977 mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
2978 mode_lib->vba.MinTTUVBlank[k] = dml_max(
2979 mode_lib->vba.StutterEnterPlusExitWatermark,
2980 mode_lib->vba.UrgentWatermark);
2981 } else {
2982 mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
2983 mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
2984 mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
2985 }
2986 if (!mode_lib->vba.DynamicMetadataEnable[k])
2987 mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
2988 + mode_lib->vba.MinTTUVBlank[k];
2989 }
2990
2991 // DCC Configuration
2992 mode_lib->vba.ActiveDPPs = 0;
2993 // NB P-State/DRAM Clock Change Support
2994 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2995 mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
2996 }
2997
2998 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2999 double EffectiveLBLatencyHidingY;
3000 double EffectiveLBLatencyHidingC;
3001 double DPPOutputBufferLinesY;
3002 double DPPOutputBufferLinesC;
3003 double DPPOPPBufferingY;
3004 double MaxDETBufferingTimeY;
3005 double ActiveDRAMClockChangeLatencyMarginY;
3006
3007 mode_lib->vba.LBLatencyHidingSourceLinesY =
3008 dml_min(
3009 mode_lib->vba.MaxLineBufferLines,
3010 (unsigned int) dml_floor(
3011 (double) mode_lib->vba.LineBufferSize
3012 / mode_lib->vba.LBBitPerPixel[k]
3013 / (mode_lib->vba.SwathWidthY[k]
3014 / dml_max(
3015 mode_lib->vba.HRatio[k],
3016 1.0)),
3017 1)) - (mode_lib->vba.vtaps[k] - 1);
3018
3019 mode_lib->vba.LBLatencyHidingSourceLinesC =
3020 dml_min(
3021 mode_lib->vba.MaxLineBufferLines,
3022 (unsigned int) dml_floor(
3023 (double) mode_lib->vba.LineBufferSize
3024 / mode_lib->vba.LBBitPerPixel[k]
3025 / (mode_lib->vba.SwathWidthY[k]
3026 / 2.0
3027 / dml_max(
3028 mode_lib->vba.HRatio[k]
3029 / 2,
3030 1.0)),
3031 1))
3032 - (mode_lib->vba.VTAPsChroma[k] - 1);
3033
3034 EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
3035 / mode_lib->vba.VRatio[k]
3036 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
3037
3038 EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
3039 / (mode_lib->vba.VRatio[k] / 2)
3040 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
3041
3042 if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
3043 DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
3044 / mode_lib->vba.SwathWidthY[k];
3045 } else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
3046 DPPOutputBufferLinesY = 0.5;
3047 } else {
3048 DPPOutputBufferLinesY = 1;
3049 }
3050
3051 if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
3052 DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
3053 / (mode_lib->vba.SwathWidthY[k] / 2);
3054 } else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
3055 DPPOutputBufferLinesC = 0.5;
3056 } else {
3057 DPPOutputBufferLinesC = 1;
3058 }
3059
3060 DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
3061 * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
3062 MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
3063 + (mode_lib->vba.LinesInDETY[k]
3064 - mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
3065 / mode_lib->vba.SwathHeightY[k]
3066 * (mode_lib->vba.HTotal[k]
3067 / mode_lib->vba.PixelClock[k]);
3068
3069 ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
3070 + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
3071
3072 if (mode_lib->vba.ActiveDPPs > 1) {
3073 ActiveDRAMClockChangeLatencyMarginY =
3074 ActiveDRAMClockChangeLatencyMarginY
3075 - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
3076 * mode_lib->vba.SwathHeightY[k]
3077 * (mode_lib->vba.HTotal[k]
3078 / mode_lib->vba.PixelClock[k]);
3079 }
3080
3081 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
3082 double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
3083 / mode_lib->vba.PixelClock[k])
3084 * (DPPOutputBufferLinesC
3085 + mode_lib->vba.OPPOutputBufferLines);
3086 double MaxDETBufferingTimeC =
3087 mode_lib->vba.FullDETBufferingTimeC[k]
3088 + (mode_lib->vba.LinesInDETC[k]
3089 - mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
3090 / mode_lib->vba.SwathHeightC[k]
3091 * (mode_lib->vba.HTotal[k]
3092 / mode_lib->vba.PixelClock[k]);
3093 double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
3094 + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
3095 - mode_lib->vba.DRAMClockChangeWatermark;
3096
3097 if (mode_lib->vba.ActiveDPPs > 1) {
3098 ActiveDRAMClockChangeLatencyMarginC =
3099 ActiveDRAMClockChangeLatencyMarginC
3100 - (1
3101 - 1
3102 / (mode_lib->vba.ActiveDPPs
3103 - 1))
3104 * mode_lib->vba.SwathHeightC[k]
3105 * (mode_lib->vba.HTotal[k]
3106 / mode_lib->vba.PixelClock[k]);
3107 }
3108 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
3109 ActiveDRAMClockChangeLatencyMarginY,
3110 ActiveDRAMClockChangeLatencyMarginC);
3111 } else {
3112 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
3113 ActiveDRAMClockChangeLatencyMarginY;
3114 }
3115
3116 if (mode_lib->vba.WritebackEnable[k]) {
3117 double WritebackDRAMClockChangeLatencyMargin;
3118
3119 if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
3120 WritebackDRAMClockChangeLatencyMargin =
3121 (double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
3122 + mode_lib->vba.WritebackInterfaceChromaBufferSize)
3123 / (mode_lib->vba.WritebackDestinationWidth[k]
3124 * mode_lib->vba.WritebackDestinationHeight[k]
3125 / (mode_lib->vba.WritebackSourceHeight[k]
3126 * mode_lib->vba.HTotal[k]
3127 / mode_lib->vba.PixelClock[k])
3128 * 4)
3129 - mode_lib->vba.WritebackDRAMClockChangeWatermark;
3130 } else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
3131 WritebackDRAMClockChangeLatencyMargin =
3132 dml_min(
3133 (double) mode_lib->vba.WritebackInterfaceLumaBufferSize
3134 * 8.0 / 10,
3135 2.0
3136 * mode_lib->vba.WritebackInterfaceChromaBufferSize
3137 * 8 / 10)
3138 / (mode_lib->vba.WritebackDestinationWidth[k]
3139 * mode_lib->vba.WritebackDestinationHeight[k]
3140 / (mode_lib->vba.WritebackSourceHeight[k]
3141 * mode_lib->vba.HTotal[k]
3142 / mode_lib->vba.PixelClock[k]))
3143 - mode_lib->vba.WritebackDRAMClockChangeWatermark;
3144 } else {
3145 WritebackDRAMClockChangeLatencyMargin =
3146 dml_min(
3147 (double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
3148 2.0
3149 * mode_lib->vba.WritebackInterfaceChromaBufferSize)
3150 / (mode_lib->vba.WritebackDestinationWidth[k]
3151 * mode_lib->vba.WritebackDestinationHeight[k]
3152 / (mode_lib->vba.WritebackSourceHeight[k]
3153 * mode_lib->vba.HTotal[k]
3154 / mode_lib->vba.PixelClock[k]))
3155 - mode_lib->vba.WritebackDRAMClockChangeWatermark;
3156 }
3157 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
3158 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
3159 WritebackDRAMClockChangeLatencyMargin);
3160 }
3161 }
3162
3163 mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
3164 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3165 if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
3166 < mode_lib->vba.MinActiveDRAMClockChangeMargin) {
3167 mode_lib->vba.MinActiveDRAMClockChangeMargin =
3168 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
3169 }
3170 }
3171
3172 mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
3173 mode_lib->vba.MinActiveDRAMClockChangeMargin
3174 + mode_lib->vba.DRAMClockChangeLatency;
3175
3176 if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
3177 mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive;
3178 } else {
3179 if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
3180 mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank;
3181 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3182 if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
3183 mode_lib->vba.DRAMClockChangeSupport =
3184 dm_dram_clock_change_unsupported;
3185 }
3186 }
3187 } else {
3188 mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
3189 }
3190 }
3191
3192 //XFC Parameters:
3193 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3194 if (mode_lib->vba.XFCEnabled[k] == true) {
3195 double TWait;
3196
3197 mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
3198 mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
3199 mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
3200 TWait = CalculateTWait(
3201 mode_lib->vba.PrefetchMode,
3202 mode_lib->vba.DRAMClockChangeLatency,
3203 mode_lib->vba.UrgentLatency,
3204 mode_lib->vba.SREnterPlusExitTime);
3205 mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
3206 mode_lib,
3207 mode_lib->vba.VRatio[k],
3208 mode_lib->vba.SwathWidthY[k],
3209 dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
3210 mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
3211 mode_lib->vba.XFCTSlvVupdateOffset,
3212 mode_lib->vba.XFCTSlvVupdateWidth,
3213 mode_lib->vba.XFCTSlvVreadyOffset,
3214 mode_lib->vba.XFCXBUFLatencyTolerance,
3215 mode_lib->vba.XFCFillBWOverhead,
3216 mode_lib->vba.XFCSlvChunkSize,
3217 mode_lib->vba.XFCBusTransportTime,
3218 mode_lib->vba.TCalc,
3219 TWait,
3220 &mode_lib->vba.SrcActiveDrainRate,
3221 &mode_lib->vba.TInitXFill,
3222 &mode_lib->vba.TslvChk);
3223 mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
3224 dml_floor(
3225 mode_lib->vba.XFCRemoteSurfaceFlipDelay
3226 / (mode_lib->vba.HTotal[k]
3227 / mode_lib->vba.PixelClock[k]),
3228 1);
3229 mode_lib->vba.XFCTransferDelay[k] =
3230 dml_ceil(
3231 mode_lib->vba.XFCBusTransportTime
3232 / (mode_lib->vba.HTotal[k]
3233 / mode_lib->vba.PixelClock[k]),
3234 1);
3235 mode_lib->vba.XFCPrechargeDelay[k] =
3236 dml_ceil(
3237 (mode_lib->vba.XFCBusTransportTime
3238 + mode_lib->vba.TInitXFill
3239 + mode_lib->vba.TslvChk)
3240 / (mode_lib->vba.HTotal[k]
3241 / mode_lib->vba.PixelClock[k]),
3242 1);
3243 mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
3244 * mode_lib->vba.SrcActiveDrainRate;
3245 mode_lib->vba.FinalFillMargin =
3246 (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
3247 + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
3248 * mode_lib->vba.HTotal[k]
3249 / mode_lib->vba.PixelClock[k]
3250 * mode_lib->vba.SrcActiveDrainRate
3251 + mode_lib->vba.XFCFillConstant;
3252 mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
3253 * mode_lib->vba.SrcActiveDrainRate
3254 + mode_lib->vba.FinalFillMargin;
3255 mode_lib->vba.RemainingFillLevel = dml_max(
3256 0.0,
3257 mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
3258 mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
3259 / (mode_lib->vba.SrcActiveDrainRate
3260 * mode_lib->vba.XFCFillBWOverhead / 100);
3261 mode_lib->vba.XFCPrefetchMargin[k] =
3262 mode_lib->vba.XFCRemoteSurfaceFlipDelay
3263 + mode_lib->vba.TFinalxFill
3264 + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
3265 + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
3266 * mode_lib->vba.HTotal[k]
3267 / mode_lib->vba.PixelClock[k];
3268 } else {
3269 mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
3270 mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
3271 mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
3272 mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
3273 mode_lib->vba.XFCPrechargeDelay[k] = 0;
3274 mode_lib->vba.XFCTransferDelay[k] = 0;
3275 mode_lib->vba.XFCPrefetchMargin[k] = 0;
3276 }
3277 }
3278}
3279
3280static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
3281{
3282 double BytePerPixDETY;
3283 double BytePerPixDETC;
3284 double Read256BytesBlockHeightY;
3285 double Read256BytesBlockHeightC;
3286 double Read256BytesBlockWidthY;
3287 double Read256BytesBlockWidthC;
3288 double MaximumSwathHeightY;
3289 double MaximumSwathHeightC;
3290 double MinimumSwathHeightY;
3291 double MinimumSwathHeightC;
3292 double SwathWidth;
3293 double SwathWidthGranularityY;
3294 double SwathWidthGranularityC;
3295 double RoundedUpMaxSwathSizeBytesY;
3296 double RoundedUpMaxSwathSizeBytesC;
3297 unsigned int j, k;
3298
3299 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3300 bool MainPlaneDoesODMCombine = false;
3301
3302 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
3303 BytePerPixDETY = 8;
3304 BytePerPixDETC = 0;
3305 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
3306 BytePerPixDETY = 4;
3307 BytePerPixDETC = 0;
3308 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
3309 BytePerPixDETY = 2;
3310 BytePerPixDETC = 0;
3311 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
3312 BytePerPixDETY = 1;
3313 BytePerPixDETC = 0;
3314 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
3315 BytePerPixDETY = 1;
3316 BytePerPixDETC = 2;
3317 } else {
3318 BytePerPixDETY = 4.0 / 3.0;
3319 BytePerPixDETC = 8.0 / 3.0;
3320 }
3321
3322 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3323 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3324 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
3325 || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
3326 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3327 Read256BytesBlockHeightY = 1;
3328 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
3329 Read256BytesBlockHeightY = 4;
3330 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3331 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
3332 Read256BytesBlockHeightY = 8;
3333 } else {
3334 Read256BytesBlockHeightY = 16;
3335 }
3336 Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
3337 / Read256BytesBlockHeightY;
3338 Read256BytesBlockHeightC = 0;
3339 Read256BytesBlockWidthC = 0;
3340 } else {
3341 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3342 Read256BytesBlockHeightY = 1;
3343 Read256BytesBlockHeightC = 1;
3344 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
3345 Read256BytesBlockHeightY = 16;
3346 Read256BytesBlockHeightC = 8;
3347 } else {
3348 Read256BytesBlockHeightY = 8;
3349 Read256BytesBlockHeightC = 8;
3350 }
3351 Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
3352 / Read256BytesBlockHeightY;
3353 Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
3354 / Read256BytesBlockHeightC;
3355 }
3356
3357 if (mode_lib->vba.SourceScan[k] == dm_horz) {
3358 MaximumSwathHeightY = Read256BytesBlockHeightY;
3359 MaximumSwathHeightC = Read256BytesBlockHeightC;
3360 } else {
3361 MaximumSwathHeightY = Read256BytesBlockWidthY;
3362 MaximumSwathHeightC = Read256BytesBlockWidthC;
3363 }
3364
3365 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3366 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3367 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
3368 || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
3369 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
3370 || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3371 && (mode_lib->vba.SurfaceTiling[k]
3372 == dm_sw_4kb_s
3373 || mode_lib->vba.SurfaceTiling[k]
3374 == dm_sw_4kb_s_x
3375 || mode_lib->vba.SurfaceTiling[k]
3376 == dm_sw_64kb_s
3377 || mode_lib->vba.SurfaceTiling[k]
3378 == dm_sw_64kb_s_t
3379 || mode_lib->vba.SurfaceTiling[k]
3380 == dm_sw_64kb_s_x
3381 || mode_lib->vba.SurfaceTiling[k]
3382 == dm_sw_var_s
3383 || mode_lib->vba.SurfaceTiling[k]
3384 == dm_sw_var_s_x)
3385 && mode_lib->vba.SourceScan[k] == dm_horz)) {
3386 MinimumSwathHeightY = MaximumSwathHeightY;
3387 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
3388 && mode_lib->vba.SourceScan[k] != dm_horz) {
3389 MinimumSwathHeightY = MaximumSwathHeightY;
3390 } else {
3391 MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
3392 }
3393 MinimumSwathHeightC = MaximumSwathHeightC;
3394 } else {
3395 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3396 MinimumSwathHeightY = MaximumSwathHeightY;
3397 MinimumSwathHeightC = MaximumSwathHeightC;
3398 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
3399 && mode_lib->vba.SourceScan[k] == dm_horz) {
3400 MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
3401 MinimumSwathHeightC = MaximumSwathHeightC;
3402 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
3403 && mode_lib->vba.SourceScan[k] == dm_horz) {
3404 MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
3405 MinimumSwathHeightY = MaximumSwathHeightY;
3406 } else {
3407 MinimumSwathHeightY = MaximumSwathHeightY;
3408 MinimumSwathHeightC = MaximumSwathHeightC;
3409 }
3410 }
3411
3412 if (mode_lib->vba.SourceScan[k] == dm_horz) {
3413 SwathWidth = mode_lib->vba.ViewportWidth[k];
3414 } else {
3415 SwathWidth = mode_lib->vba.ViewportHeight[k];
3416 }
3417
3418 if (mode_lib->vba.ODMCombineEnabled[k] == true) {
3419 MainPlaneDoesODMCombine = true;
3420 }
3421 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
3422 if (mode_lib->vba.BlendingAndTiming[k] == j
3423 && mode_lib->vba.ODMCombineEnabled[j] == true) {
3424 MainPlaneDoesODMCombine = true;
3425 }
3426 }
3427
3428 if (MainPlaneDoesODMCombine == true) {
3429 SwathWidth = dml_min(
3430 SwathWidth,
3431 mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
3432 } else {
3433 SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
3434 }
3435
3436 SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
3437 RoundedUpMaxSwathSizeBytesY = (dml_ceil(
3438 (double) (SwathWidth - 1),
3439 SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
3440 * MaximumSwathHeightY;
3441 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
3442 RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
3443 + 256;
3444 }
3445 if (MaximumSwathHeightC > 0) {
3446 SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
3447 / MaximumSwathHeightC;
3448 RoundedUpMaxSwathSizeBytesC = (dml_ceil(
3449 (double) (SwathWidth / 2.0 - 1),
3450 SwathWidthGranularityC) + SwathWidthGranularityC)
3451 * BytePerPixDETC * MaximumSwathHeightC;
3452 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
3453 RoundedUpMaxSwathSizeBytesC = dml_ceil(
3454 RoundedUpMaxSwathSizeBytesC,
3455 256) + 256;
3456 }
3457 } else
3458 RoundedUpMaxSwathSizeBytesC = 0.0;
3459
3460 if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
3461 <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
3462 mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
3463 mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
3464 } else {
3465 mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
3466 mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
3467 }
3468
3469 if (mode_lib->vba.SwathHeightC[k] == 0) {
3470 mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
3471 mode_lib->vba.DETBufferSizeC[k] = 0;
3472 } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
3473 mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
3474 * 1024.0 / 2;
3475 mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
3476 * 1024.0 / 2;
3477 } else {
3478 mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
3479 * 1024.0 * 2 / 3;
3480 mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
3481 * 1024.0 / 3;
3482 }
3483 }
3484}
3485
3486bool Calculate256BBlockSizes(
3487 enum source_format_class SourcePixelFormat,
3488 enum dm_swizzle_mode SurfaceTiling,
3489 unsigned int BytePerPixelY,
3490 unsigned int BytePerPixelC,
3491 unsigned int *BlockHeight256BytesY,
3492 unsigned int *BlockHeight256BytesC,
3493 unsigned int *BlockWidth256BytesY,
3494 unsigned int *BlockWidth256BytesC)
3495{
3496 if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
3497 || SourcePixelFormat == dm_444_16
3498 || SourcePixelFormat == dm_444_8)) {
3499 if (SurfaceTiling == dm_sw_linear) {
3500 *BlockHeight256BytesY = 1;
3501 } else if (SourcePixelFormat == dm_444_64) {
3502 *BlockHeight256BytesY = 4;
3503 } else if (SourcePixelFormat == dm_444_8) {
3504 *BlockHeight256BytesY = 16;
3505 } else {
3506 *BlockHeight256BytesY = 8;
3507 }
3508 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
3509 *BlockHeight256BytesC = 0;
3510 *BlockWidth256BytesC = 0;
3511 } else {
3512 if (SurfaceTiling == dm_sw_linear) {
3513 *BlockHeight256BytesY = 1;
3514 *BlockHeight256BytesC = 1;
3515 } else if (SourcePixelFormat == dm_420_8) {
3516 *BlockHeight256BytesY = 16;
3517 *BlockHeight256BytesC = 8;
3518 } else {
3519 *BlockHeight256BytesY = 8;
3520 *BlockHeight256BytesC = 8;
3521 }
3522 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
3523 *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
3524 }
3525 return true;
3526}
3527
3528static double CalculateTWait(
3529 unsigned int PrefetchMode,
3530 double DRAMClockChangeLatency,
3531 double UrgentLatency,
3532 double SREnterPlusExitTime)
3533{
3534 if (PrefetchMode == 0) {
3535 return dml_max(
3536 DRAMClockChangeLatency + UrgentLatency,
3537 dml_max(SREnterPlusExitTime, UrgentLatency));
3538 } else if (PrefetchMode == 1) {
3539 return dml_max(SREnterPlusExitTime, UrgentLatency);
3540 } else {
3541 return UrgentLatency;
3542 }
3543}
3544
3545static double CalculateRemoteSurfaceFlipDelay(
3546 struct display_mode_lib *mode_lib,
3547 double VRatio,
3548 double SwathWidth,
3549 double Bpp,
3550 double LineTime,
3551 double XFCTSlvVupdateOffset,
3552 double XFCTSlvVupdateWidth,
3553 double XFCTSlvVreadyOffset,
3554 double XFCXBUFLatencyTolerance,
3555 double XFCFillBWOverhead,
3556 double XFCSlvChunkSize,
3557 double XFCBusTransportTime,
3558 double TCalc,
3559 double TWait,
3560 double *SrcActiveDrainRate,
3561 double *TInitXFill,
3562 double *TslvChk)
3563{
3564 double TSlvSetup, AvgfillRate, result;
3565
3566 *SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
3567 TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
3568 *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
3569 AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
3570 *TslvChk = XFCSlvChunkSize / AvgfillRate;
3571 dml_print(
3572 "DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
3573 *SrcActiveDrainRate);
3574 dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
3575 dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
3576 dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
3577 dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
3578 result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
3579 dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
3580 return result;
3581}
3582
3583static double CalculateWriteBackDISPCLK(
3584 enum source_format_class WritebackPixelFormat,
3585 double PixelClock,
3586 double WritebackHRatio,
3587 double WritebackVRatio,
3588 unsigned int WritebackLumaHTaps,
3589 unsigned int WritebackLumaVTaps,
3590 unsigned int WritebackChromaHTaps,
3591 unsigned int WritebackChromaVTaps,
3592 double WritebackDestinationWidth,
3593 unsigned int HTotal,
3594 unsigned int WritebackChromaLineBufferWidth)
3595{
3596 double CalculateWriteBackDISPCLK =
3597 1.01 * PixelClock
3598 * dml_max(
3599 dml_ceil(WritebackLumaHTaps / 4.0, 1)
3600 / WritebackHRatio,
3601 dml_max(
3602 (WritebackLumaVTaps
3603 * dml_ceil(
3604 1.0
3605 / WritebackVRatio,
3606 1)
3607 * dml_ceil(
3608 WritebackDestinationWidth
3609 / 4.0,
3610 1)
3611 + dml_ceil(
3612 WritebackDestinationWidth
3613 / 4.0,
3614 1))
3615 / (double) HTotal
3616 + dml_ceil(
3617 1.0
3618 / WritebackVRatio,
3619 1)
3620 * (dml_ceil(
3621 WritebackLumaVTaps
3622 / 4.0,
3623 1)
3624 + 4.0)
3625 / (double) HTotal,
3626 dml_ceil(
3627 1.0
3628 / WritebackVRatio,
3629 1)
3630 * WritebackDestinationWidth
3631 / (double) HTotal));
3632 if (WritebackPixelFormat != dm_444_32) {
3633 CalculateWriteBackDISPCLK =
3634 dml_max(
3635 CalculateWriteBackDISPCLK,
3636 1.01 * PixelClock
3637 * dml_max(
3638 dml_ceil(
3639 WritebackChromaHTaps
3640 / 2.0,
3641 1)
3642 / (2
3643 * WritebackHRatio),
3644 dml_max(
3645 (WritebackChromaVTaps
3646 * dml_ceil(
3647 1
3648 / (2
3649 * WritebackVRatio),
3650 1)
3651 * dml_ceil(
3652 WritebackDestinationWidth
3653 / 2.0
3654 / 2.0,
3655 1)
3656 + dml_ceil(
3657 WritebackDestinationWidth
3658 / 2.0
3659 / WritebackChromaLineBufferWidth,
3660 1))
3661 / HTotal
3662 + dml_ceil(
3663 1
3664 / (2
3665 * WritebackVRatio),
3666 1)
3667 * (dml_ceil(
3668 WritebackChromaVTaps
3669 / 4.0,
3670 1)
3671 + 4)
3672 / HTotal,
3673 dml_ceil(
3674 1.0
3675 / (2
3676 * WritebackVRatio),
3677 1)
3678 * WritebackDestinationWidth
3679 / 2.0
3680 / HTotal)));
3681 }
3682 return CalculateWriteBackDISPCLK;
3683}
3684
3685static double CalculateWriteBackDelay(
3686 enum source_format_class WritebackPixelFormat,
3687 double WritebackHRatio,
3688 double WritebackVRatio,
3689 unsigned int WritebackLumaHTaps,
3690 unsigned int WritebackLumaVTaps,
3691 unsigned int WritebackChromaHTaps,
3692 unsigned int WritebackChromaVTaps,
3693 unsigned int WritebackDestinationWidth)
3694{
3695 double CalculateWriteBackDelay =
3696 dml_max(
3697 dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
3698 WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
3699 * dml_ceil(
3700 WritebackDestinationWidth
3701 / 4.0,
3702 1)
3703 + dml_ceil(1.0 / WritebackVRatio, 1)
3704 * (dml_ceil(
3705 WritebackLumaVTaps
3706 / 4.0,
3707 1) + 4));
3708
3709 if (WritebackPixelFormat != dm_444_32) {
3710 CalculateWriteBackDelay =
3711 dml_max(
3712 CalculateWriteBackDelay,
3713 dml_max(
3714 dml_ceil(
3715 WritebackChromaHTaps
3716 / 2.0,
3717 1)
3718 / (2
3719 * WritebackHRatio),
3720 WritebackChromaVTaps
3721 * dml_ceil(
3722 1
3723 / (2
3724 * WritebackVRatio),
3725 1)
3726 * dml_ceil(
3727 WritebackDestinationWidth
3728 / 2.0
3729 / 2.0,
3730 1)
3731 + dml_ceil(
3732 1
3733 / (2
3734 * WritebackVRatio),
3735 1)
3736 * (dml_ceil(
3737 WritebackChromaVTaps
3738 / 4.0,
3739 1)
3740 + 4)));
3741 }
3742 return CalculateWriteBackDelay;
3743}
3744
3745static void CalculateActiveRowBandwidth(
3746 bool VirtualMemoryEnable,
3747 enum source_format_class SourcePixelFormat,
3748 double VRatio,
3749 bool DCCEnable,
3750 double LineTime,
3751 unsigned int MetaRowByteLuma,
3752 unsigned int MetaRowByteChroma,
3753 unsigned int meta_row_height_luma,
3754 unsigned int meta_row_height_chroma,
3755 unsigned int PixelPTEBytesPerRowLuma,
3756 unsigned int PixelPTEBytesPerRowChroma,
3757 unsigned int dpte_row_height_luma,
3758 unsigned int dpte_row_height_chroma,
3759 double *meta_row_bw,
3760 double *dpte_row_bw,
3761 double *qual_row_bw)
3762{
3763 if (DCCEnable != true) {
3764 *meta_row_bw = 0;
3765 } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3766 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
3767 + VRatio / 2 * MetaRowByteChroma
3768 / (meta_row_height_chroma * LineTime);
3769 } else {
3770 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
3771 }
3772
3773 if (VirtualMemoryEnable != true) {
3774 *dpte_row_bw = 0;
3775 } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3776 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
3777 + VRatio / 2 * PixelPTEBytesPerRowChroma
3778 / (dpte_row_height_chroma * LineTime);
3779 } else {
3780 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
3781 }
3782
3783 if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
3784 *qual_row_bw = *meta_row_bw + *dpte_row_bw;
3785 } else {
3786 *qual_row_bw = 0;
3787 }
3788}
3789
3790static void CalculateFlipSchedule(
3791 struct display_mode_lib *mode_lib,
3792 double UrgentExtraLatency,
3793 double UrgentLatency,
3794 unsigned int MaxPageTableLevels,
3795 bool VirtualMemoryEnable,
3796 double BandwidthAvailableForImmediateFlip,
3797 unsigned int TotImmediateFlipBytes,
3798 enum source_format_class SourcePixelFormat,
3799 unsigned int ImmediateFlipBytes,
3800 double LineTime,
3801 double Tno_bw,
3802 double VRatio,
3803 double PDEAndMetaPTEBytesFrame,
3804 unsigned int MetaRowByte,
3805 unsigned int PixelPTEBytesPerRow,
3806 bool DCCEnable,
3807 unsigned int dpte_row_height,
3808 unsigned int meta_row_height,
3809 double qual_row_bw,
3810 double *DestinationLinesToRequestVMInImmediateFlip,
3811 double *DestinationLinesToRequestRowInImmediateFlip,
3812 double *final_flip_bw,
3813 bool *ImmediateFlipSupportedForPipe)
3814{
3815 double min_row_time = 0.0;
3816
3817 if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3818 *DestinationLinesToRequestVMInImmediateFlip = 0.0;
3819 *DestinationLinesToRequestRowInImmediateFlip = 0.0;
3820 *final_flip_bw = qual_row_bw;
3821 *ImmediateFlipSupportedForPipe = true;
3822 } else {
3823 double TimeForFetchingMetaPTEImmediateFlip;
3824 double TimeForFetchingRowInVBlankImmediateFlip;
3825
3826 if (VirtualMemoryEnable == true) {
3827 mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
3828 * ImmediateFlipBytes / TotImmediateFlipBytes;
3829 TimeForFetchingMetaPTEImmediateFlip =
3830 dml_max(
3831 Tno_bw
3832 + PDEAndMetaPTEBytesFrame
3833 / mode_lib->vba.ImmediateFlipBW,
3834 dml_max(
3835 UrgentExtraLatency
3836 + UrgentLatency
3837 * (MaxPageTableLevels
3838 - 1),
3839 LineTime / 4.0));
3840 } else {
3841 TimeForFetchingMetaPTEImmediateFlip = 0;
3842 }
3843
3844 *DestinationLinesToRequestVMInImmediateFlip = dml_floor(
3845 4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
3846 1) / 4.0;
3847
3848 if ((VirtualMemoryEnable == true || DCCEnable == true)) {
3849 mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
3850 * ImmediateFlipBytes / TotImmediateFlipBytes;
3851 TimeForFetchingRowInVBlankImmediateFlip = dml_max(
3852 (MetaRowByte + PixelPTEBytesPerRow)
3853 / mode_lib->vba.ImmediateFlipBW,
3854 dml_max(UrgentLatency, LineTime / 4.0));
3855 } else {
3856 TimeForFetchingRowInVBlankImmediateFlip = 0;
3857 }
3858
3859 *DestinationLinesToRequestRowInImmediateFlip = dml_floor(
3860 4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
3861 1) / 4.0;
3862
3863 if (VirtualMemoryEnable == true) {
3864 *final_flip_bw =
3865 dml_max(
3866 PDEAndMetaPTEBytesFrame
3867 / (*DestinationLinesToRequestVMInImmediateFlip
3868 * LineTime),
3869 (MetaRowByte + PixelPTEBytesPerRow)
3870 / (TimeForFetchingRowInVBlankImmediateFlip
3871 * LineTime));
3872 } else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
3873 *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
3874 / (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
3875 } else {
3876 *final_flip_bw = 0;
3877 }
3878
3879 if (VirtualMemoryEnable && !DCCEnable)
3880 min_row_time = dpte_row_height * LineTime / VRatio;
3881 else if (!VirtualMemoryEnable && DCCEnable)
3882 min_row_time = meta_row_height * LineTime / VRatio;
3883 else
3884 min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
3885 / VRatio;
3886
3887 if (*DestinationLinesToRequestVMInImmediateFlip >= 8
3888 || *DestinationLinesToRequestRowInImmediateFlip >= 16
3889 || TimeForFetchingMetaPTEImmediateFlip
3890 + 2 * TimeForFetchingRowInVBlankImmediateFlip
3891 > min_row_time)
3892 *ImmediateFlipSupportedForPipe = false;
3893 else
3894 *ImmediateFlipSupportedForPipe = true;
3895 }
3896}
3897
3898static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
3899{
3900 unsigned int k;
3901
3902 //Progressive To dml_ml->vba.Interlace Unit Effect
3903 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3904 mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
3905 if (mode_lib->vba.Interlace[k] == 1
3906 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
3907 mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
3908 }
3909 }
3910}
3911
3912static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
3913{
3914 switch (ebpp) {
3915 case dm_cur_2bit:
3916 return 2;
3917 case dm_cur_32bit:
3918 return 32;
3919 case dm_cur_64bit:
3920 return 64;
3921 default:
3922 return 0;
3923 }
3924}
3925
3926static unsigned int TruncToValidBPP(
3927 double DecimalBPP,
3928 bool DSCEnabled,
3929 enum output_encoder_class Output,
3930 enum output_format_class Format,
3931 unsigned int DSCInputBitPerComponent)
3932{
3933 if (Output == dm_hdmi) {
3934 if (Format == dm_420) {
3935 if (DecimalBPP >= 18)
3936 return 18;
3937 else if (DecimalBPP >= 15)
3938 return 15;
3939 else if (DecimalBPP >= 12)
3940 return 12;
3941 else
3942 return BPP_INVALID;
3943 } else if (Format == dm_444) {
3944 if (DecimalBPP >= 36)
3945 return 36;
3946 else if (DecimalBPP >= 30)
3947 return 30;
3948 else if (DecimalBPP >= 24)
3949 return 24;
3950 else
3951 return BPP_INVALID;
3952 } else {
3953 if (DecimalBPP / 1.5 >= 24)
3954 return 24;
3955 else if (DecimalBPP / 1.5 >= 20)
3956 return 20;
3957 else if (DecimalBPP / 1.5 >= 16)
3958 return 16;
3959 else
3960 return BPP_INVALID;
3961 }
3962 } else {
3963 if (DSCEnabled) {
3964 if (Format == dm_420) {
3965 if (DecimalBPP < 6)
3966 return BPP_INVALID;
3967 else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
3968 return 1.5 * DSCInputBitPerComponent - 1 / 16;
3969 else
3970 return dml_floor(16 * DecimalBPP, 1) / 16;
3971 } else if (Format == dm_n422) {
3972 if (DecimalBPP < 7)
3973 return BPP_INVALID;
3974 else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
3975 return 2 * DSCInputBitPerComponent - 1 / 16;
3976 else
3977 return dml_floor(16 * DecimalBPP, 1) / 16;
3978 } else {
3979 if (DecimalBPP < 8)
3980 return BPP_INVALID;
3981 else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
3982 return 3 * DSCInputBitPerComponent - 1 / 16;
3983 else
3984 return dml_floor(16 * DecimalBPP, 1) / 16;
3985 }
3986 } else if (Format == dm_420) {
3987 if (DecimalBPP >= 18)
3988 return 18;
3989 else if (DecimalBPP >= 15)
3990 return 15;
3991 else if (DecimalBPP >= 12)
3992 return 12;
3993 else
3994 return BPP_INVALID;
3995 } else if (Format == dm_s422 || Format == dm_n422) {
3996 if (DecimalBPP >= 24)
3997 return 24;
3998 else if (DecimalBPP >= 20)
3999 return 20;
4000 else if (DecimalBPP >= 16)
4001 return 16;
4002 else
4003 return BPP_INVALID;
4004 } else {
4005 if (DecimalBPP >= 36)
4006 return 36;
4007 else if (DecimalBPP >= 30)
4008 return 30;
4009 else if (DecimalBPP >= 24)
4010 return 24;
4011 else
4012 return BPP_INVALID;
4013 }
4014 }
4015}
4016
4017static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
4018{
4019 int i;
4020 unsigned int j, k;
4021 /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
4022
4023 /*Scale Ratio, taps Support Check*/
4024
4025 mode_lib->vba.ScaleRatioAndTapsSupport = true;
4026 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4027 if (mode_lib->vba.ScalerEnabled[k] == false
4028 && ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
4029 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
4030 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
4031 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
4032 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
4033 || mode_lib->vba.HRatio[k] != 1.0
4034 || mode_lib->vba.htaps[k] != 1.0
4035 || mode_lib->vba.VRatio[k] != 1.0
4036 || mode_lib->vba.vtaps[k] != 1.0)) {
4037 mode_lib->vba.ScaleRatioAndTapsSupport = false;
4038 } else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
4039 || mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
4040 || (mode_lib->vba.htaps[k] > 1.0
4041 && (mode_lib->vba.htaps[k] % 2) == 1)
4042 || mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
4043 || mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
4044 || mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
4045 || mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
4046 || (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
4047 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
4048 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
4049 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
4050 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
4051 && (mode_lib->vba.HRatio[k] / 2.0
4052 > mode_lib->vba.HTAPsChroma[k]
4053 || mode_lib->vba.VRatio[k] / 2.0
4054 > mode_lib->vba.VTAPsChroma[k]))) {
4055 mode_lib->vba.ScaleRatioAndTapsSupport = false;
4056 }
4057 }
4058 /*Source Format, Pixel Format and Scan Support Check*/
4059
4060 mode_lib->vba.SourceFormatPixelAndScanSupport = true;
4061 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4062 if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
4063 && mode_lib->vba.SourceScan[k] != dm_horz)
4064 || ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
4065 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
4066 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
4067 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
4068 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
4069 || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
4070 || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
4071 && mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
4072 || (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
4073 && (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
4074 || mode_lib->vba.SourcePixelFormat[k]
4075 == dm_420_8
4076 || mode_lib->vba.SourcePixelFormat[k]
4077 == dm_420_10))
4078 || (((mode_lib->vba.SurfaceTiling[k]
4079 == dm_sw_gfx7_2d_thin_gl
4080 || mode_lib->vba.SurfaceTiling[k]
4081 == dm_sw_gfx7_2d_thin_lvp)
4082 && !((mode_lib->vba.SourcePixelFormat[k]
4083 == dm_444_64
4084 || mode_lib->vba.SourcePixelFormat[k]
4085 == dm_444_32)
4086 && mode_lib->vba.SourceScan[k]
4087 == dm_horz
4088 && mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
4089 == true
4090 && mode_lib->vba.DCCEnable[k]
4091 == false))
4092 || (mode_lib->vba.DCCEnable[k] == true
4093 && (mode_lib->vba.SurfaceTiling[k]
4094 == dm_sw_linear
4095 || mode_lib->vba.SourcePixelFormat[k]
4096 == dm_420_8
4097 || mode_lib->vba.SourcePixelFormat[k]
4098 == dm_420_10)))) {
4099 mode_lib->vba.SourceFormatPixelAndScanSupport = false;
4100 }
4101 }
4102 /*Bandwidth Support Check*/
4103
4104 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4105 if (mode_lib->vba.SourceScan[k] == dm_horz) {
4106 mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
4107 } else {
4108 mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
4109 }
4110 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
4111 mode_lib->vba.BytePerPixelInDETY[k] = 8.0;
4112 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4113 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
4114 mode_lib->vba.BytePerPixelInDETY[k] = 4.0;
4115 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4116 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
4117 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
4118 mode_lib->vba.BytePerPixelInDETY[k] = 2.0;
4119 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4120 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
4121 mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
4122 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4123 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
4124 mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
4125 mode_lib->vba.BytePerPixelInDETC[k] = 2.0;
4126 } else {
4127 mode_lib->vba.BytePerPixelInDETY[k] = 4.0 / 3;
4128 mode_lib->vba.BytePerPixelInDETC[k] = 8.0 / 3;
4129 }
4130 }
4131 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = 0.0;
4132 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4133 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.SwathWidthYSingleDPP[k]
4134 * (dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
4135 * mode_lib->vba.VRatio[k]
4136 + dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
4137 / 2.0 * mode_lib->vba.VRatio[k] / 2)
4138 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
4139 if (mode_lib->vba.DCCEnable[k] == true) {
4140 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4141 * (1 + 1 / 256);
4142 }
4143 if (mode_lib->vba.VirtualMemoryEnable == true
4144 && mode_lib->vba.SourceScan[k] != dm_horz
4145 && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s
4146 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s_x
4147 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
4148 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x)) {
4149 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4150 * (1 + 1 / 64);
4151 } else if (mode_lib->vba.VirtualMemoryEnable == true
4152 && mode_lib->vba.SourceScan[k] == dm_horz
4153 && (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
4154 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32)
4155 && (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s
4156 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_t
4157 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_x
4158 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
4159 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
4160 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
4161 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x)) {
4162 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4163 * (1 + 1 / 256);
4164 } else if (mode_lib->vba.VirtualMemoryEnable == true) {
4165 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4166 * (1 + 1 / 512);
4167 }
4168 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond =
4169 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
4170 + mode_lib->vba.ReadBandwidth[k] / 1000.0;
4171 }
4172 mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = 0.0;
4173 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4174 if (mode_lib->vba.WritebackEnable[k] == true
4175 && mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
4176 mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
4177 * mode_lib->vba.WritebackDestinationHeight[k]
4178 / (mode_lib->vba.WritebackSourceHeight[k]
4179 * mode_lib->vba.HTotal[k]
4180 / mode_lib->vba.PixelClock[k]) * 4.0;
4181 } else if (mode_lib->vba.WritebackEnable[k] == true
4182 && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
4183 mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
4184 * mode_lib->vba.WritebackDestinationHeight[k]
4185 / (mode_lib->vba.WritebackSourceHeight[k]
4186 * mode_lib->vba.HTotal[k]
4187 / mode_lib->vba.PixelClock[k]) * 3.0;
4188 } else if (mode_lib->vba.WritebackEnable[k] == true) {
4189 mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
4190 * mode_lib->vba.WritebackDestinationHeight[k]
4191 / (mode_lib->vba.WritebackSourceHeight[k]
4192 * mode_lib->vba.HTotal[k]
4193 / mode_lib->vba.PixelClock[k]) * 1.5;
4194 } else {
4195 mode_lib->vba.WriteBandwidth[k] = 0.0;
4196 }
4197 mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond =
4198 mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond
4199 + mode_lib->vba.WriteBandwidth[k] / 1000.0;
4200 }
4201 mode_lib->vba.TotalBandwidthConsumedGBytePerSecond =
4202 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
4203 + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond;
4204 mode_lib->vba.DCCEnabledInAnyPlane = false;
4205 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4206 if (mode_lib->vba.DCCEnable[k] == true) {
4207 mode_lib->vba.DCCEnabledInAnyPlane = true;
4208 }
4209 }
4210 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4211 mode_lib->vba.FabricAndDRAMBandwidthPerState[i] = dml_min(
4212 mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
4213 * mode_lib->vba.DRAMChannelWidth,
4214 mode_lib->vba.FabricClockPerState[i]
4215 * mode_lib->vba.FabricDatapathToDCNDataReturn)
4216 / 1000;
4217 mode_lib->vba.ReturnBWToDCNPerState = dml_min(
4218 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
4219 mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0)
4220 * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
4221 / 100;
4222 mode_lib->vba.ReturnBWPerState[i] = mode_lib->vba.ReturnBWToDCNPerState;
4223 if (mode_lib->vba.DCCEnabledInAnyPlane == true
4224 && mode_lib->vba.ReturnBWToDCNPerState
4225 > mode_lib->vba.DCFCLKPerState[i]
4226 * mode_lib->vba.ReturnBusWidth
4227 / 4.0) {
4228 mode_lib->vba.ReturnBWPerState[i] =
4229 dml_min(
4230 mode_lib->vba.ReturnBWPerState[i],
4231 mode_lib->vba.ReturnBWToDCNPerState * 4.0
4232 * (1.0
4233 - mode_lib->vba.UrgentLatency
4234 / ((mode_lib->vba.ROBBufferSizeInKByte
4235 - mode_lib->vba.PixelChunkSizeInKByte)
4236 * 1024.0
4237 / (mode_lib->vba.ReturnBWToDCNPerState
4238 - mode_lib->vba.DCFCLKPerState[i]
4239 * mode_lib->vba.ReturnBusWidth
4240 / 4.0)
4241 + mode_lib->vba.UrgentLatency)));
4242 }
4243 mode_lib->vba.CriticalPoint =
4244 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
4245 * mode_lib->vba.UrgentLatency
4246 / (mode_lib->vba.ReturnBWToDCNPerState
4247 * mode_lib->vba.UrgentLatency
4248 + (mode_lib->vba.ROBBufferSizeInKByte
4249 - mode_lib->vba.PixelChunkSizeInKByte)
4250 * 1024.0);
4251 if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
4252 && mode_lib->vba.CriticalPoint < 4.0) {
4253 mode_lib->vba.ReturnBWPerState[i] =
4254 dml_min(
4255 mode_lib->vba.ReturnBWPerState[i],
4256 dml_pow(
4257 4.0
4258 * mode_lib->vba.ReturnBWToDCNPerState
4259 * (mode_lib->vba.ROBBufferSizeInKByte
4260 - mode_lib->vba.PixelChunkSizeInKByte)
4261 * 1024.0
4262 * mode_lib->vba.ReturnBusWidth
4263 * mode_lib->vba.DCFCLKPerState[i]
4264 * mode_lib->vba.UrgentLatency
4265 / (mode_lib->vba.ReturnBWToDCNPerState
4266 * mode_lib->vba.UrgentLatency
4267 + (mode_lib->vba.ROBBufferSizeInKByte
4268 - mode_lib->vba.PixelChunkSizeInKByte)
4269 * 1024.0),
4270 2));
4271 }
4272 mode_lib->vba.ReturnBWToDCNPerState = dml_min(
4273 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
4274 mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0);
4275 if (mode_lib->vba.DCCEnabledInAnyPlane == true
4276 && mode_lib->vba.ReturnBWToDCNPerState
4277 > mode_lib->vba.DCFCLKPerState[i]
4278 * mode_lib->vba.ReturnBusWidth
4279 / 4.0) {
4280 mode_lib->vba.ReturnBWPerState[i] =
4281 dml_min(
4282 mode_lib->vba.ReturnBWPerState[i],
4283 mode_lib->vba.ReturnBWToDCNPerState * 4.0
4284 * (1.0
4285 - mode_lib->vba.UrgentLatency
4286 / ((mode_lib->vba.ROBBufferSizeInKByte
4287 - mode_lib->vba.PixelChunkSizeInKByte)
4288 * 1024.0
4289 / (mode_lib->vba.ReturnBWToDCNPerState
4290 - mode_lib->vba.DCFCLKPerState[i]
4291 * mode_lib->vba.ReturnBusWidth
4292 / 4.0)
4293 + mode_lib->vba.UrgentLatency)));
4294 }
4295 mode_lib->vba.CriticalPoint =
4296 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
4297 * mode_lib->vba.UrgentLatency
4298 / (mode_lib->vba.ReturnBWToDCNPerState
4299 * mode_lib->vba.UrgentLatency
4300 + (mode_lib->vba.ROBBufferSizeInKByte
4301 - mode_lib->vba.PixelChunkSizeInKByte)
4302 * 1024.0);
4303 if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
4304 && mode_lib->vba.CriticalPoint < 4.0) {
4305 mode_lib->vba.ReturnBWPerState[i] =
4306 dml_min(
4307 mode_lib->vba.ReturnBWPerState[i],
4308 dml_pow(
4309 4.0
4310 * mode_lib->vba.ReturnBWToDCNPerState
4311 * (mode_lib->vba.ROBBufferSizeInKByte
4312 - mode_lib->vba.PixelChunkSizeInKByte)
4313 * 1024.0
4314 * mode_lib->vba.ReturnBusWidth
4315 * mode_lib->vba.DCFCLKPerState[i]
4316 * mode_lib->vba.UrgentLatency
4317 / (mode_lib->vba.ReturnBWToDCNPerState
4318 * mode_lib->vba.UrgentLatency
4319 + (mode_lib->vba.ROBBufferSizeInKByte
4320 - mode_lib->vba.PixelChunkSizeInKByte)
4321 * 1024.0),
4322 2));
4323 }
4324 }
4325 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4326 if ((mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond * 1000.0
4327 <= mode_lib->vba.ReturnBWPerState[i])
4328 && (mode_lib->vba.TotalBandwidthConsumedGBytePerSecond * 1000.0
4329 <= mode_lib->vba.FabricAndDRAMBandwidthPerState[i]
4330 * 1000.0
4331 * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
4332 / 100.0)) {
4333 mode_lib->vba.BandwidthSupport[i] = true;
4334 } else {
4335 mode_lib->vba.BandwidthSupport[i] = false;
4336 }
4337 }
4338 /*Writeback Latency support check*/
4339
4340 mode_lib->vba.WritebackLatencySupport = true;
4341 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4342 if (mode_lib->vba.WritebackEnable[k] == true) {
4343 if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
4344 if (mode_lib->vba.WriteBandwidth[k]
4345 > (mode_lib->vba.WritebackInterfaceLumaBufferSize
4346 + mode_lib->vba.WritebackInterfaceChromaBufferSize)
4347 / mode_lib->vba.WritebackLatency) {
4348 mode_lib->vba.WritebackLatencySupport = false;
4349 }
4350 } else {
4351 if (mode_lib->vba.WriteBandwidth[k]
4352 > 1.5
4353 * dml_min(
4354 mode_lib->vba.WritebackInterfaceLumaBufferSize,
4355 2.0
4356 * mode_lib->vba.WritebackInterfaceChromaBufferSize)
4357 / mode_lib->vba.WritebackLatency) {
4358 mode_lib->vba.WritebackLatencySupport = false;
4359 }
4360 }
4361 }
4362 }
4363 /*Re-ordering Buffer Support Check*/
4364
4365 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4366 mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
4367 (mode_lib->vba.RoundTripPingLatencyCycles + 32.0)
4368 / mode_lib->vba.DCFCLKPerState[i]
4369 + mode_lib->vba.UrgentOutOfOrderReturnPerChannel
4370 * mode_lib->vba.NumberOfChannels
4371 / mode_lib->vba.ReturnBWPerState[i];
4372 if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte)
4373 * 1024.0 / mode_lib->vba.ReturnBWPerState[i]
4374 > mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
4375 mode_lib->vba.ROBSupport[i] = true;
4376 } else {
4377 mode_lib->vba.ROBSupport[i] = false;
4378 }
4379 }
4380 /*Writeback Mode Support Check*/
4381
4382 mode_lib->vba.TotalNumberOfActiveWriteback = 0;
4383 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4384 if (mode_lib->vba.WritebackEnable[k] == true) {
4385 mode_lib->vba.TotalNumberOfActiveWriteback =
4386 mode_lib->vba.TotalNumberOfActiveWriteback + 1;
4387 }
4388 }
4389 mode_lib->vba.WritebackModeSupport = true;
4390 if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
4391 mode_lib->vba.WritebackModeSupport = false;
4392 }
4393 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4394 if (mode_lib->vba.WritebackEnable[k] == true
4395 && mode_lib->vba.Writeback10bpc420Supported != true
4396 && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
4397 mode_lib->vba.WritebackModeSupport = false;
4398 }
4399 }
4400 /*Writeback Scale Ratio and Taps Support Check*/
4401
4402 mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
4403 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4404 if (mode_lib->vba.WritebackEnable[k] == true) {
4405 if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
4406 && (mode_lib->vba.WritebackHRatio[k] != 1.0
4407 || mode_lib->vba.WritebackVRatio[k] != 1.0)) {
4408 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4409 }
4410 if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
4411 || mode_lib->vba.WritebackVRatio[k]
4412 > mode_lib->vba.WritebackMaxVSCLRatio
4413 || mode_lib->vba.WritebackHRatio[k]
4414 < mode_lib->vba.WritebackMinHSCLRatio
4415 || mode_lib->vba.WritebackVRatio[k]
4416 < mode_lib->vba.WritebackMinVSCLRatio
4417 || mode_lib->vba.WritebackLumaHTaps[k]
4418 > mode_lib->vba.WritebackMaxHSCLTaps
4419 || mode_lib->vba.WritebackLumaVTaps[k]
4420 > mode_lib->vba.WritebackMaxVSCLTaps
4421 || mode_lib->vba.WritebackHRatio[k]
4422 > mode_lib->vba.WritebackLumaHTaps[k]
4423 || mode_lib->vba.WritebackVRatio[k]
4424 > mode_lib->vba.WritebackLumaVTaps[k]
4425 || (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
4426 && ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
4427 == 1))
4428 || (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
4429 && (mode_lib->vba.WritebackChromaHTaps[k]
4430 > mode_lib->vba.WritebackMaxHSCLTaps
4431 || mode_lib->vba.WritebackChromaVTaps[k]
4432 > mode_lib->vba.WritebackMaxVSCLTaps
4433 || 2.0
4434 * mode_lib->vba.WritebackHRatio[k]
4435 > mode_lib->vba.WritebackChromaHTaps[k]
4436 || 2.0
4437 * mode_lib->vba.WritebackVRatio[k]
4438 > mode_lib->vba.WritebackChromaVTaps[k]
4439 || (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
4440 && ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
4441 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4442 }
4443 if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
4444 mode_lib->vba.WritebackLumaVExtra =
4445 dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
4446 } else {
4447 mode_lib->vba.WritebackLumaVExtra = -1;
4448 }
4449 if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
4450 && mode_lib->vba.WritebackLumaVTaps[k]
4451 > (mode_lib->vba.WritebackLineBufferLumaBufferSize
4452 + mode_lib->vba.WritebackLineBufferChromaBufferSize)
4453 / 3.0
4454 / mode_lib->vba.WritebackDestinationWidth[k]
4455 - mode_lib->vba.WritebackLumaVExtra)
4456 || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
4457 && mode_lib->vba.WritebackLumaVTaps[k]
4458 > mode_lib->vba.WritebackLineBufferLumaBufferSize
4459 / mode_lib->vba.WritebackDestinationWidth[k]
4460 - mode_lib->vba.WritebackLumaVExtra)
4461 || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
4462 && mode_lib->vba.WritebackLumaVTaps[k]
4463 > mode_lib->vba.WritebackLineBufferLumaBufferSize
4464 * 8.0 / 10.0
4465 / mode_lib->vba.WritebackDestinationWidth[k]
4466 - mode_lib->vba.WritebackLumaVExtra)) {
4467 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4468 }
4469 if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
4470 mode_lib->vba.WritebackChromaVExtra = 0.0;
4471 } else {
4472 mode_lib->vba.WritebackChromaVExtra = -1;
4473 }
4474 if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
4475 && mode_lib->vba.WritebackChromaVTaps[k]
4476 > mode_lib->vba.WritebackLineBufferChromaBufferSize
4477 / mode_lib->vba.WritebackDestinationWidth[k]
4478 - mode_lib->vba.WritebackChromaVExtra)
4479 || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
4480 && mode_lib->vba.WritebackChromaVTaps[k]
4481 > mode_lib->vba.WritebackLineBufferChromaBufferSize
4482 * 8.0 / 10.0
4483 / mode_lib->vba.WritebackDestinationWidth[k]
4484 - mode_lib->vba.WritebackChromaVExtra)) {
4485 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4486 }
4487 }
4488 }
4489 /*Maximum DISPCLK/DPPCLK Support check*/
4490
4491 mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
4492 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4493 if (mode_lib->vba.WritebackEnable[k] == true) {
4494 mode_lib->vba.WritebackRequiredDISPCLK =
4495 dml_max(
4496 mode_lib->vba.WritebackRequiredDISPCLK,
4497 CalculateWriteBackDISPCLK(
4498 mode_lib->vba.WritebackPixelFormat[k],
4499 mode_lib->vba.PixelClock[k],
4500 mode_lib->vba.WritebackHRatio[k],
4501 mode_lib->vba.WritebackVRatio[k],
4502 mode_lib->vba.WritebackLumaHTaps[k],
4503 mode_lib->vba.WritebackLumaVTaps[k],
4504 mode_lib->vba.WritebackChromaHTaps[k],
4505 mode_lib->vba.WritebackChromaVTaps[k],
4506 mode_lib->vba.WritebackDestinationWidth[k],
4507 mode_lib->vba.HTotal[k],
4508 mode_lib->vba.WritebackChromaLineBufferWidth));
4509 }
4510 }
4511 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4512 if (mode_lib->vba.HRatio[k] > 1.0) {
4513 mode_lib->vba.PSCL_FACTOR[k] = dml_min(
4514 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4515 mode_lib->vba.MaxPSCLToLBThroughput
4516 * mode_lib->vba.HRatio[k]
4517 / dml_ceil(
4518 mode_lib->vba.htaps[k]
4519 / 6.0,
4520 1.0));
4521 } else {
4522 mode_lib->vba.PSCL_FACTOR[k] = dml_min(
4523 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4524 mode_lib->vba.MaxPSCLToLBThroughput);
4525 }
4526 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
4527 mode_lib->vba.PSCL_FACTOR_CHROMA[k] = 0.0;
4528 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
4529 mode_lib->vba.PixelClock[k]
4530 * dml_max3(
4531 mode_lib->vba.vtaps[k] / 6.0
4532 * dml_min(
4533 1.0,
4534 mode_lib->vba.HRatio[k]),
4535 mode_lib->vba.HRatio[k]
4536 * mode_lib->vba.VRatio[k]
4537 / mode_lib->vba.PSCL_FACTOR[k],
4538 1.0);
4539 if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
4540 && mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4541 < 2.0 * mode_lib->vba.PixelClock[k]) {
4542 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
4543 * mode_lib->vba.PixelClock[k];
4544 }
4545 } else {
4546 if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
4547 mode_lib->vba.PSCL_FACTOR_CHROMA[k] =
4548 dml_min(
4549 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4550 mode_lib->vba.MaxPSCLToLBThroughput
4551 * mode_lib->vba.HRatio[k]
4552 / 2.0
4553 / dml_ceil(
4554 mode_lib->vba.HTAPsChroma[k]
4555 / 6.0,
4556 1.0));
4557 } else {
4558 mode_lib->vba.PSCL_FACTOR_CHROMA[k] = dml_min(
4559 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4560 mode_lib->vba.MaxPSCLToLBThroughput);
4561 }
4562 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
4563 mode_lib->vba.PixelClock[k]
4564 * dml_max5(
4565 mode_lib->vba.vtaps[k] / 6.0
4566 * dml_min(
4567 1.0,
4568 mode_lib->vba.HRatio[k]),
4569 mode_lib->vba.HRatio[k]
4570 * mode_lib->vba.VRatio[k]
4571 / mode_lib->vba.PSCL_FACTOR[k],
4572 mode_lib->vba.VTAPsChroma[k]
4573 / 6.0
4574 * dml_min(
4575 1.0,
4576 mode_lib->vba.HRatio[k]
4577 / 2.0),
4578 mode_lib->vba.HRatio[k]
4579 * mode_lib->vba.VRatio[k]
4580 / 4.0
4581 / mode_lib->vba.PSCL_FACTOR_CHROMA[k],
4582 1.0);
4583 if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
4584 || mode_lib->vba.HTAPsChroma[k] > 6.0
4585 || mode_lib->vba.VTAPsChroma[k] > 6.0)
4586 && mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4587 < 2.0 * mode_lib->vba.PixelClock[k]) {
4588 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
4589 * mode_lib->vba.PixelClock[k];
4590 }
4591 }
4592 }
4593 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4594 Calculate256BBlockSizes(
4595 mode_lib->vba.SourcePixelFormat[k],
4596 mode_lib->vba.SurfaceTiling[k],
4597 dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
4598 dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
4599 &mode_lib->vba.Read256BlockHeightY[k],
4600 &mode_lib->vba.Read256BlockHeightC[k],
4601 &mode_lib->vba.Read256BlockWidthY[k],
4602 &mode_lib->vba.Read256BlockWidthC[k]);
4603 if (mode_lib->vba.SourceScan[k] == dm_horz) {
4604 mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockHeightY[k];
4605 mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockHeightC[k];
4606 } else {
4607 mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockWidthY[k];
4608 mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockWidthC[k];
4609 }
4610 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
4611 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
4612 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
4613 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
4614 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
4615 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
4616 || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
4617 && (mode_lib->vba.SurfaceTiling[k]
4618 == dm_sw_4kb_s
4619 || mode_lib->vba.SurfaceTiling[k]
4620 == dm_sw_4kb_s_x
4621 || mode_lib->vba.SurfaceTiling[k]
4622 == dm_sw_64kb_s
4623 || mode_lib->vba.SurfaceTiling[k]
4624 == dm_sw_64kb_s_t
4625 || mode_lib->vba.SurfaceTiling[k]
4626 == dm_sw_64kb_s_x
4627 || mode_lib->vba.SurfaceTiling[k]
4628 == dm_sw_var_s
4629 || mode_lib->vba.SurfaceTiling[k]
4630 == dm_sw_var_s_x)
4631 && mode_lib->vba.SourceScan[k] == dm_horz)) {
4632 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4633 } else {
4634 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
4635 / 2.0;
4636 }
4637 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4638 } else {
4639 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
4640 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4641 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4642 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
4643 && mode_lib->vba.SourceScan[k] == dm_horz) {
4644 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
4645 / 2.0;
4646 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4647 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
4648 && mode_lib->vba.SourceScan[k] == dm_horz) {
4649 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]
4650 / 2.0;
4651 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4652 } else {
4653 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4654 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4655 }
4656 }
4657 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
4658 mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
4659 } else {
4660 mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
4661 }
4662 mode_lib->vba.MaximumSwathWidthInDETBuffer =
4663 dml_min(
4664 mode_lib->vba.MaximumSwathWidthSupport,
4665 mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
4666 / (mode_lib->vba.BytePerPixelInDETY[k]
4667 * mode_lib->vba.MinSwathHeightY[k]
4668 + mode_lib->vba.BytePerPixelInDETC[k]
4669 / 2.0
4670 * mode_lib->vba.MinSwathHeightC[k]));
4671 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
4672 mode_lib->vba.MaximumSwathWidthInLineBuffer =
4673 mode_lib->vba.LineBufferSize
4674 * dml_max(mode_lib->vba.HRatio[k], 1.0)
4675 / mode_lib->vba.LBBitPerPixel[k]
4676 / (mode_lib->vba.vtaps[k]
4677 + dml_max(
4678 dml_ceil(
4679 mode_lib->vba.VRatio[k],
4680 1.0)
4681 - 2,
4682 0.0));
4683 } else {
4684 mode_lib->vba.MaximumSwathWidthInLineBuffer =
4685 dml_min(
4686 mode_lib->vba.LineBufferSize
4687 * dml_max(
4688 mode_lib->vba.HRatio[k],
4689 1.0)
4690 / mode_lib->vba.LBBitPerPixel[k]
4691 / (mode_lib->vba.vtaps[k]
4692 + dml_max(
4693 dml_ceil(
4694 mode_lib->vba.VRatio[k],
4695 1.0)
4696 - 2,
4697 0.0)),
4698 2.0 * mode_lib->vba.LineBufferSize
4699 * dml_max(
4700 mode_lib->vba.HRatio[k]
4701 / 2.0,
4702 1.0)
4703 / mode_lib->vba.LBBitPerPixel[k]
4704 / (mode_lib->vba.VTAPsChroma[k]
4705 + dml_max(
4706 dml_ceil(
4707 mode_lib->vba.VRatio[k]
4708 / 2.0,
4709 1.0)
4710 - 2,
4711 0.0)));
4712 }
4713 mode_lib->vba.MaximumSwathWidth[k] = dml_min(
4714 mode_lib->vba.MaximumSwathWidthInDETBuffer,
4715 mode_lib->vba.MaximumSwathWidthInLineBuffer);
4716 }
4717 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4718 mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
4719 mode_lib->vba.MaxDispclk[i],
4720 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
4721 mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
4722 mode_lib->vba.MaxDppclk[i],
4723 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
4724 mode_lib->vba.RequiredDISPCLK[i] = 0.0;
4725 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
4726 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4727 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
4728 mode_lib->vba.PixelClock[k]
4729 * (1.0
4730 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4731 / 100.0)
4732 * (1.0
4733 + mode_lib->vba.DISPCLKRampingMargin
4734 / 100.0);
4735 if (mode_lib->vba.ODMCapability == true
4736 && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4737 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
4738 mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
4739 mode_lib->vba.PlaneRequiredDISPCLK =
4740 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4741 / 2.0;
4742 } else {
4743 mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
4744 mode_lib->vba.PlaneRequiredDISPCLK =
4745 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
4746 }
4747 if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4748 * (1.0
4749 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4750 / 100.0)
4751 <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
4752 && mode_lib->vba.SwathWidthYSingleDPP[k]
4753 <= mode_lib->vba.MaximumSwathWidth[k]
4754 && mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
4755 mode_lib->vba.NoOfDPP[i][k] = 1;
4756 mode_lib->vba.RequiredDPPCLK[i][k] =
4757 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4758 * (1.0
4759 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4760 / 100.0);
4761 } else {
4762 mode_lib->vba.NoOfDPP[i][k] = 2;
4763 mode_lib->vba.RequiredDPPCLK[i][k] =
4764 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4765 * (1.0
4766 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4767 / 100.0)
4768 / 2.0;
4769 }
4770 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4771 mode_lib->vba.RequiredDISPCLK[i],
4772 mode_lib->vba.PlaneRequiredDISPCLK);
4773 if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] / mode_lib->vba.NoOfDPP[i][k]
4774 * (1.0
4775 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4776 / 100.0)
4777 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
4778 || (mode_lib->vba.PlaneRequiredDISPCLK
4779 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
4780 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4781 }
4782 }
4783 mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
4784 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4785 mode_lib->vba.TotalNumberOfActiveDPP[i] =
4786 mode_lib->vba.TotalNumberOfActiveDPP[i]
4787 + mode_lib->vba.NoOfDPP[i][k];
4788 }
4789 if ((mode_lib->vba.MaxDispclk[i] == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
4790 && mode_lib->vba.MaxDppclk[i]
4791 == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])
4792 && (mode_lib->vba.TotalNumberOfActiveDPP[i]
4793 > mode_lib->vba.MaxNumDPP
4794 || mode_lib->vba.DISPCLK_DPPCLK_Support[i] == false)) {
4795 mode_lib->vba.RequiredDISPCLK[i] = 0.0;
4796 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
4797 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4798 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
4799 mode_lib->vba.PixelClock[k]
4800 * (1.0
4801 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4802 / 100.0);
4803 if (mode_lib->vba.ODMCapability == true
4804 && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4805 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
4806 mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
4807 mode_lib->vba.PlaneRequiredDISPCLK =
4808 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4809 / 2.0;
4810 } else {
4811 mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
4812 mode_lib->vba.PlaneRequiredDISPCLK =
4813 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
4814 }
4815 if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4816 * (1.0
4817 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4818 / 100.0)
4819 <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
4820 && mode_lib->vba.SwathWidthYSingleDPP[k]
4821 <= mode_lib->vba.MaximumSwathWidth[k]
4822 && mode_lib->vba.ODMCombineEnablePerState[i][k]
4823 == false) {
4824 mode_lib->vba.NoOfDPP[i][k] = 1;
4825 mode_lib->vba.RequiredDPPCLK[i][k] =
4826 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4827 * (1.0
4828 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4829 / 100.0);
4830 } else {
4831 mode_lib->vba.NoOfDPP[i][k] = 2;
4832 mode_lib->vba.RequiredDPPCLK[i][k] =
4833 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4834 * (1.0
4835 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4836 / 100.0)
4837 / 2.0;
4838 }
4839 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4840 mode_lib->vba.RequiredDISPCLK[i],
4841 mode_lib->vba.PlaneRequiredDISPCLK);
4842 if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4843 / mode_lib->vba.NoOfDPP[i][k]
4844 * (1.0
4845 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4846 / 100.0)
4847 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
4848 || (mode_lib->vba.PlaneRequiredDISPCLK
4849 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
4850 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4851 }
4852 }
4853 mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
4854 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4855 mode_lib->vba.TotalNumberOfActiveDPP[i] =
4856 mode_lib->vba.TotalNumberOfActiveDPP[i]
4857 + mode_lib->vba.NoOfDPP[i][k];
4858 }
4859 }
4860 if (mode_lib->vba.TotalNumberOfActiveDPP[i] > mode_lib->vba.MaxNumDPP) {
4861 mode_lib->vba.RequiredDISPCLK[i] = 0.0;
4862 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
4863 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4864 mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
4865 if (mode_lib->vba.SwathWidthYSingleDPP[k]
4866 <= mode_lib->vba.MaximumSwathWidth[k]) {
4867 mode_lib->vba.NoOfDPP[i][k] = 1;
4868 mode_lib->vba.RequiredDPPCLK[i][k] =
4869 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4870 * (1.0
4871 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4872 / 100.0);
4873 } else {
4874 mode_lib->vba.NoOfDPP[i][k] = 2;
4875 mode_lib->vba.RequiredDPPCLK[i][k] =
4876 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4877 * (1.0
4878 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4879 / 100.0)
4880 / 2.0;
4881 }
4882 if (!(mode_lib->vba.MaxDispclk[i]
4883 == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
4884 && mode_lib->vba.MaxDppclk[i]
4885 == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])) {
4886 mode_lib->vba.PlaneRequiredDISPCLK =
4887 mode_lib->vba.PixelClock[k]
4888 * (1.0
4889 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4890 / 100.0)
4891 * (1.0
4892 + mode_lib->vba.DISPCLKRampingMargin
4893 / 100.0);
4894 } else {
4895 mode_lib->vba.PlaneRequiredDISPCLK =
4896 mode_lib->vba.PixelClock[k]
4897 * (1.0
4898 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4899 / 100.0);
4900 }
4901 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4902 mode_lib->vba.RequiredDISPCLK[i],
4903 mode_lib->vba.PlaneRequiredDISPCLK);
4904 if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4905 / mode_lib->vba.NoOfDPP[i][k]
4906 * (1.0
4907 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4908 / 100.0)
4909 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
4910 || (mode_lib->vba.PlaneRequiredDISPCLK
4911 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
4912 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4913 }
4914 }
4915 mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
4916 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4917 mode_lib->vba.TotalNumberOfActiveDPP[i] =
4918 mode_lib->vba.TotalNumberOfActiveDPP[i]
4919 + mode_lib->vba.NoOfDPP[i][k];
4920 }
4921 }
4922 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4923 mode_lib->vba.RequiredDISPCLK[i],
4924 mode_lib->vba.WritebackRequiredDISPCLK);
4925 if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
4926 < mode_lib->vba.WritebackRequiredDISPCLK) {
4927 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4928 }
4929 }
4930 /*Viewport Size Check*/
4931
4932 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4933 mode_lib->vba.ViewportSizeSupport[i] = true;
4934 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4935 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
4936 if (dml_min(mode_lib->vba.SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
4937 > mode_lib->vba.MaximumSwathWidth[k]) {
4938 mode_lib->vba.ViewportSizeSupport[i] = false;
4939 }
4940 } else {
4941 if (mode_lib->vba.SwathWidthYSingleDPP[k] / 2.0
4942 > mode_lib->vba.MaximumSwathWidth[k]) {
4943 mode_lib->vba.ViewportSizeSupport[i] = false;
4944 }
4945 }
4946 }
4947 }
4948 /*Total Available Pipes Support Check*/
4949
4950 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4951 if (mode_lib->vba.TotalNumberOfActiveDPP[i] <= mode_lib->vba.MaxNumDPP) {
4952 mode_lib->vba.TotalAvailablePipesSupport[i] = true;
4953 } else {
4954 mode_lib->vba.TotalAvailablePipesSupport[i] = false;
4955 }
4956 }
4957 /*Total Available OTG Support Check*/
4958
4959 mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
4960 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4961 if (mode_lib->vba.BlendingAndTiming[k] == k) {
4962 mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
4963 + 1.0;
4964 }
4965 }
4966 if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
4967 mode_lib->vba.NumberOfOTGSupport = true;
4968 } else {
4969 mode_lib->vba.NumberOfOTGSupport = false;
4970 }
4971 /*Display IO and DSC Support Check*/
4972
4973 mode_lib->vba.NonsupportedDSCInputBPC = false;
4974 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4975 if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
4976 || mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
4977 || mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
4978 mode_lib->vba.NonsupportedDSCInputBPC = true;
4979 }
4980 }
4981 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4982 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4983 mode_lib->vba.RequiresDSC[i][k] = 0;
4984 mode_lib->vba.RequiresFEC[i][k] = 0;
4985 if (mode_lib->vba.BlendingAndTiming[k] == k) {
4986 if (mode_lib->vba.Output[k] == dm_hdmi) {
4987 mode_lib->vba.RequiresDSC[i][k] = 0;
4988 mode_lib->vba.RequiresFEC[i][k] = 0;
4989 mode_lib->vba.OutputBppPerState[i][k] =
4990 TruncToValidBPP(dml_min(600.0, mode_lib->vba.PHYCLKPerState[i])
4991 / mode_lib->vba.PixelClockBackEnd[k] * 24,
4992 false,
4993 mode_lib->vba.Output[k],
4994 mode_lib->vba.OutputFormat[k],
4995 mode_lib->vba.DSCInputBitPerComponent[k]);
4996 } else if (mode_lib->vba.Output[k] == dm_dp
4997 || mode_lib->vba.Output[k] == dm_edp) {
4998 if (mode_lib->vba.Output[k] == dm_edp) {
4999 mode_lib->vba.EffectiveFECOverhead = 0.0;
5000 } else {
5001 mode_lib->vba.EffectiveFECOverhead =
5002 mode_lib->vba.FECOverhead;
5003 }
5004 if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
5005 mode_lib->vba.Outbpp =
5006 TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0
5007 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
5008 false,
5009 mode_lib->vba.Output[k],
5010 mode_lib->vba.OutputFormat[k],
5011 mode_lib->vba.DSCInputBitPerComponent[k]);
5012 mode_lib->vba.OutbppDSC =
5013 TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0)
5014 * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0
5015 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
5016 true,
5017 mode_lib->vba.Output[k],
5018 mode_lib->vba.OutputFormat[k],
5019 mode_lib->vba.DSCInputBitPerComponent[k]);
5020 if (mode_lib->vba.DSCEnabled[k] == true) {
5021 mode_lib->vba.RequiresDSC[i][k] = true;
5022 if (mode_lib->vba.Output[k] == dm_dp) {
5023 mode_lib->vba.RequiresFEC[i][k] =
5024 true;
5025 } else {
5026 mode_lib->vba.RequiresFEC[i][k] =
5027 false;
5028 }
5029 mode_lib->vba.Outbpp =
5030 mode_lib->vba.OutbppDSC;
5031 } else {
5032 mode_lib->vba.RequiresDSC[i][k] = false;
5033 mode_lib->vba.RequiresFEC[i][k] = false;
5034 }
5035 mode_lib->vba.OutputBppPerState[i][k] =
5036 mode_lib->vba.Outbpp;
5037 }
5038 if (mode_lib->vba.Outbpp == BPP_INVALID) {
5039 mode_lib->vba.Outbpp =
5040 TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0
5041 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
5042 false,
5043 mode_lib->vba.Output[k],
5044 mode_lib->vba.OutputFormat[k],
5045 mode_lib->vba.DSCInputBitPerComponent[k]);
5046 mode_lib->vba.OutbppDSC =
5047 TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0)
5048 * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0
5049 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
5050 true,
5051 mode_lib->vba.Output[k],
5052 mode_lib->vba.OutputFormat[k],
5053 mode_lib->vba.DSCInputBitPerComponent[k]);
5054 if (mode_lib->vba.DSCEnabled[k] == true) {
5055 mode_lib->vba.RequiresDSC[i][k] = true;
5056 if (mode_lib->vba.Output[k] == dm_dp) {
5057 mode_lib->vba.RequiresFEC[i][k] =
5058 true;
5059 } else {
5060 mode_lib->vba.RequiresFEC[i][k] =
5061 false;
5062 }
5063 mode_lib->vba.Outbpp =
5064 mode_lib->vba.OutbppDSC;
5065 } else {
5066 mode_lib->vba.RequiresDSC[i][k] = false;
5067 mode_lib->vba.RequiresFEC[i][k] = false;
5068 }
5069 mode_lib->vba.OutputBppPerState[i][k] =
5070 mode_lib->vba.Outbpp;
5071 }
5072 if (mode_lib->vba.Outbpp == BPP_INVALID
5073 && mode_lib->vba.PHYCLKPerState[i]
5074 >= 810.0) {
5075 mode_lib->vba.Outbpp =
5076 TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
5077 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
5078 false,
5079 mode_lib->vba.Output[k],
5080 mode_lib->vba.OutputFormat[k],
5081 mode_lib->vba.DSCInputBitPerComponent[k]);
5082 mode_lib->vba.OutbppDSC =
5083 TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0)
5084 * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
5085 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
5086 true,
5087 mode_lib->vba.Output[k],
5088 mode_lib->vba.OutputFormat[k],
5089 mode_lib->vba.DSCInputBitPerComponent[k]);
5090 if (mode_lib->vba.DSCEnabled[k] == true
5091 || mode_lib->vba.Outbpp == BPP_INVALID) {
5092 mode_lib->vba.RequiresDSC[i][k] = true;
5093 if (mode_lib->vba.Output[k] == dm_dp) {
5094 mode_lib->vba.RequiresFEC[i][k] =
5095 true;
5096 } else {
5097 mode_lib->vba.RequiresFEC[i][k] =
5098 false;
5099 }
5100 mode_lib->vba.Outbpp =
5101 mode_lib->vba.OutbppDSC;
5102 } else {
5103 mode_lib->vba.RequiresDSC[i][k] = false;
5104 mode_lib->vba.RequiresFEC[i][k] = false;
5105 }
5106 mode_lib->vba.OutputBppPerState[i][k] =
5107 mode_lib->vba.Outbpp;
5108 }
5109 }
5110 } else {
5111 mode_lib->vba.OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
5112 }
5113 }
5114 }
5115 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5116 mode_lib->vba.DIOSupport[i] = true;
5117 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5118 if (mode_lib->vba.OutputBppPerState[i][k] == BPP_INVALID
5119 || (mode_lib->vba.OutputFormat[k] == dm_420
5120 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP
5121 == true)) {
5122 mode_lib->vba.DIOSupport[i] = false;
5123 }
5124 }
5125 }
5126 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5127 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5128 mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = false;
5129 if (mode_lib->vba.BlendingAndTiming[k] == k) {
5130 if ((mode_lib->vba.Output[k] == dm_dp
5131 || mode_lib->vba.Output[k] == dm_edp)) {
5132 if (mode_lib->vba.OutputFormat[k] == dm_420
5133 || mode_lib->vba.OutputFormat[k]
5134 == dm_n422) {
5135 mode_lib->vba.DSCFormatFactor = 2;
5136 } else {
5137 mode_lib->vba.DSCFormatFactor = 1;
5138 }
5139 if (mode_lib->vba.RequiresDSC[i][k] == true) {
5140 if (mode_lib->vba.ODMCombineEnablePerState[i][k]
5141 == true) {
5142 if (mode_lib->vba.PixelClockBackEnd[k] / 6.0
5143 / mode_lib->vba.DSCFormatFactor
5144 > (1.0
5145 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
5146 / 100.0)
5147 * mode_lib->vba.MaxDSCCLK[i]) {
5148 mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
5149 true;
5150 }
5151 } else {
5152 if (mode_lib->vba.PixelClockBackEnd[k] / 3.0
5153 / mode_lib->vba.DSCFormatFactor
5154 > (1.0
5155 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
5156 / 100.0)
5157 * mode_lib->vba.MaxDSCCLK[i]) {
5158 mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
5159 true;
5160 }
5161 }
5162 }
5163 }
5164 }
5165 }
5166 }
5167 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5168 mode_lib->vba.NotEnoughDSCUnits[i] = false;
5169 mode_lib->vba.TotalDSCUnitsRequired = 0.0;
5170 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5171 if (mode_lib->vba.RequiresDSC[i][k] == true) {
5172 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
5173 mode_lib->vba.TotalDSCUnitsRequired =
5174 mode_lib->vba.TotalDSCUnitsRequired + 2.0;
5175 } else {
5176 mode_lib->vba.TotalDSCUnitsRequired =
5177 mode_lib->vba.TotalDSCUnitsRequired + 1.0;
5178 }
5179 }
5180 }
5181 if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
5182 mode_lib->vba.NotEnoughDSCUnits[i] = true;
5183 }
5184 }
5185 /*DSC Delay per state*/
5186
5187 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5188 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5189 if (mode_lib->vba.BlendingAndTiming[k] != k) {
5190 mode_lib->vba.slices = 0;
5191 } else if (mode_lib->vba.RequiresDSC[i][k] == 0
5192 || mode_lib->vba.RequiresDSC[i][k] == false) {
5193 mode_lib->vba.slices = 0;
5194 } else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
5195 mode_lib->vba.slices = dml_ceil(
5196 mode_lib->vba.PixelClockBackEnd[k] / 400.0,
5197 4.0);
5198 } else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
5199 mode_lib->vba.slices = 8.0;
5200 } else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
5201 mode_lib->vba.slices = 4.0;
5202 } else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
5203 mode_lib->vba.slices = 2.0;
5204 } else {
5205 mode_lib->vba.slices = 1.0;
5206 }
5207 if (mode_lib->vba.OutputBppPerState[i][k] == BPP_BLENDED_PIPE
5208 || mode_lib->vba.OutputBppPerState[i][k] == BPP_INVALID) {
5209 mode_lib->vba.bpp = 0.0;
5210 } else {
5211 mode_lib->vba.bpp = mode_lib->vba.OutputBppPerState[i][k];
5212 }
5213 if (mode_lib->vba.RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
5214 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
5215 mode_lib->vba.DSCDelayPerState[i][k] =
5216 dscceComputeDelay(
5217 mode_lib->vba.DSCInputBitPerComponent[k],
5218 mode_lib->vba.bpp,
5219 dml_ceil(
5220 mode_lib->vba.HActive[k]
5221 / mode_lib->vba.slices,
5222 1.0),
5223 mode_lib->vba.slices,
5224 mode_lib->vba.OutputFormat[k])
5225 + dscComputeDelay(
5226 mode_lib->vba.OutputFormat[k]);
5227 } else {
5228 mode_lib->vba.DSCDelayPerState[i][k] =
5229 2.0
5230 * (dscceComputeDelay(
5231 mode_lib->vba.DSCInputBitPerComponent[k],
5232 mode_lib->vba.bpp,
5233 dml_ceil(
5234 mode_lib->vba.HActive[k]
5235 / mode_lib->vba.slices,
5236 1.0),
5237 mode_lib->vba.slices
5238 / 2,
5239 mode_lib->vba.OutputFormat[k])
5240 + dscComputeDelay(
5241 mode_lib->vba.OutputFormat[k]));
5242 }
5243 mode_lib->vba.DSCDelayPerState[i][k] =
5244 mode_lib->vba.DSCDelayPerState[i][k]
5245 * mode_lib->vba.PixelClock[k]
5246 / mode_lib->vba.PixelClockBackEnd[k];
5247 } else {
5248 mode_lib->vba.DSCDelayPerState[i][k] = 0.0;
5249 }
5250 }
5251 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5252 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
5253 if (mode_lib->vba.BlendingAndTiming[k] == j
5254 && mode_lib->vba.RequiresDSC[i][j] == true) {
5255 mode_lib->vba.DSCDelayPerState[i][k] =
5256 mode_lib->vba.DSCDelayPerState[i][j];
5257 }
5258 }
5259 }
5260 }
5261 /*Urgent Latency Support Check*/
5262
5263 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5264 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5265 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
5266 mode_lib->vba.SwathWidthYPerState[i][k] =
5267 dml_min(
5268 mode_lib->vba.SwathWidthYSingleDPP[k],
5269 dml_round(
5270 mode_lib->vba.HActive[k]
5271 / 2.0
5272 * mode_lib->vba.HRatio[k]));
5273 } else {
5274 mode_lib->vba.SwathWidthYPerState[i][k] =
5275 mode_lib->vba.SwathWidthYSingleDPP[k]
5276 / mode_lib->vba.NoOfDPP[i][k];
5277 }
5278 mode_lib->vba.SwathWidthGranularityY = 256.0
5279 / dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
5280 / mode_lib->vba.MaxSwathHeightY[k];
5281 mode_lib->vba.RoundedUpMaxSwathSizeBytesY = (dml_ceil(
5282 mode_lib->vba.SwathWidthYPerState[i][k] - 1.0,
5283 mode_lib->vba.SwathWidthGranularityY)
5284 + mode_lib->vba.SwathWidthGranularityY)
5285 * mode_lib->vba.BytePerPixelInDETY[k]
5286 * mode_lib->vba.MaxSwathHeightY[k];
5287 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
5288 mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil(
5289 mode_lib->vba.RoundedUpMaxSwathSizeBytesY,
5290 256.0) + 256;
5291 }
5292 if (mode_lib->vba.MaxSwathHeightC[k] > 0.0) {
5293 mode_lib->vba.SwathWidthGranularityC = 256.0
5294 / dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
5295 / mode_lib->vba.MaxSwathHeightC[k];
5296 mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil(
5297 mode_lib->vba.SwathWidthYPerState[i][k] / 2.0 - 1.0,
5298 mode_lib->vba.SwathWidthGranularityC)
5299 + mode_lib->vba.SwathWidthGranularityC)
5300 * mode_lib->vba.BytePerPixelInDETC[k]
5301 * mode_lib->vba.MaxSwathHeightC[k];
5302 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
5303 mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil(
5304 mode_lib->vba.RoundedUpMaxSwathSizeBytesC,
5305 256.0) + 256;
5306 }
5307 } else {
5308 mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0;
5309 }
5310 if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY
5311 + mode_lib->vba.RoundedUpMaxSwathSizeBytesC
5312 <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
5313 mode_lib->vba.SwathHeightYPerState[i][k] =
5314 mode_lib->vba.MaxSwathHeightY[k];
5315 mode_lib->vba.SwathHeightCPerState[i][k] =
5316 mode_lib->vba.MaxSwathHeightC[k];
5317 } else {
5318 mode_lib->vba.SwathHeightYPerState[i][k] =
5319 mode_lib->vba.MinSwathHeightY[k];
5320 mode_lib->vba.SwathHeightCPerState[i][k] =
5321 mode_lib->vba.MinSwathHeightC[k];
5322 }
5323 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
5324 mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
5325 * 1024.0 / mode_lib->vba.BytePerPixelInDETY[k]
5326 / mode_lib->vba.SwathWidthYPerState[i][k];
5327 mode_lib->vba.LinesInDETChroma = 0.0;
5328 } else if (mode_lib->vba.SwathHeightYPerState[i][k]
5329 <= mode_lib->vba.SwathHeightCPerState[i][k]) {
5330 mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
5331 * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETY[k]
5332 / mode_lib->vba.SwathWidthYPerState[i][k];
5333 mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
5334 * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETC[k]
5335 / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
5336 } else {
5337 mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
5338 * 1024.0 * 2.0 / 3.0
5339 / mode_lib->vba.BytePerPixelInDETY[k]
5340 / mode_lib->vba.SwathWidthYPerState[i][k];
5341 mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
5342 * 1024.0 / 3.0 / mode_lib->vba.BytePerPixelInDETY[k]
5343 / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
5344 }
5345 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma =
5346 dml_min(
5347 mode_lib->vba.MaxLineBufferLines,
5348 dml_floor(
5349 mode_lib->vba.LineBufferSize
5350 / mode_lib->vba.LBBitPerPixel[k]
5351 / (mode_lib->vba.SwathWidthYPerState[i][k]
5352 / dml_max(
5353 mode_lib->vba.HRatio[k],
5354 1.0)),
5355 1.0))
5356 - (mode_lib->vba.vtaps[k] - 1.0);
5357 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma =
5358 dml_min(
5359 mode_lib->vba.MaxLineBufferLines,
5360 dml_floor(
5361 mode_lib->vba.LineBufferSize
5362 / mode_lib->vba.LBBitPerPixel[k]
5363 / (mode_lib->vba.SwathWidthYPerState[i][k]
5364 / 2.0
5365 / dml_max(
5366 mode_lib->vba.HRatio[k]
5367 / 2.0,
5368 1.0)),
5369 1.0))
5370 - (mode_lib->vba.VTAPsChroma[k] - 1.0);
5371 mode_lib->vba.EffectiveDETLBLinesLuma =
5372 dml_floor(
5373 mode_lib->vba.LinesInDETLuma
5374 + dml_min(
5375 mode_lib->vba.LinesInDETLuma
5376 * mode_lib->vba.RequiredDISPCLK[i]
5377 * mode_lib->vba.BytePerPixelInDETY[k]
5378 * mode_lib->vba.PSCL_FACTOR[k]
5379 / mode_lib->vba.ReturnBWPerState[i],
5380 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
5381 mode_lib->vba.SwathHeightYPerState[i][k]);
5382 mode_lib->vba.EffectiveDETLBLinesChroma =
5383 dml_floor(
5384 mode_lib->vba.LinesInDETChroma
5385 + dml_min(
5386 mode_lib->vba.LinesInDETChroma
5387 * mode_lib->vba.RequiredDISPCLK[i]
5388 * mode_lib->vba.BytePerPixelInDETC[k]
5389 * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
5390 / mode_lib->vba.ReturnBWPerState[i],
5391 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
5392 mode_lib->vba.SwathHeightCPerState[i][k]);
5393 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
5394 mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
5395 mode_lib->vba.EffectiveDETLBLinesLuma
5396 * (mode_lib->vba.HTotal[k]
5397 / mode_lib->vba.PixelClock[k])
5398 / mode_lib->vba.VRatio[k]
5399 - mode_lib->vba.EffectiveDETLBLinesLuma
5400 * mode_lib->vba.SwathWidthYPerState[i][k]
5401 * dml_ceil(
5402 mode_lib->vba.BytePerPixelInDETY[k],
5403 1.0)
5404 / (mode_lib->vba.ReturnBWPerState[i]
5405 / mode_lib->vba.NoOfDPP[i][k]);
5406 } else {
5407 mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
5408 dml_min(
5409 mode_lib->vba.EffectiveDETLBLinesLuma
5410 * (mode_lib->vba.HTotal[k]
5411 / mode_lib->vba.PixelClock[k])
5412 / mode_lib->vba.VRatio[k]
5413 - mode_lib->vba.EffectiveDETLBLinesLuma
5414 * mode_lib->vba.SwathWidthYPerState[i][k]
5415 * dml_ceil(
5416 mode_lib->vba.BytePerPixelInDETY[k],
5417 1.0)
5418 / (mode_lib->vba.ReturnBWPerState[i]
5419 / mode_lib->vba.NoOfDPP[i][k]),
5420 mode_lib->vba.EffectiveDETLBLinesChroma
5421 * (mode_lib->vba.HTotal[k]
5422 / mode_lib->vba.PixelClock[k])
5423 / (mode_lib->vba.VRatio[k]
5424 / 2.0)
5425 - mode_lib->vba.EffectiveDETLBLinesChroma
5426 * mode_lib->vba.SwathWidthYPerState[i][k]
5427 / 2.0
5428 * dml_ceil(
5429 mode_lib->vba.BytePerPixelInDETC[k],
5430 2.0)
5431 / (mode_lib->vba.ReturnBWPerState[i]
5432 / mode_lib->vba.NoOfDPP[i][k]));
5433 }
5434 }
5435 }
5436 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5437 mode_lib->vba.UrgentLatencySupport[i] = true;
5438 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5439 if (mode_lib->vba.UrgentLatencySupportUsPerState[i][k]
5440 < mode_lib->vba.UrgentLatency / 1.0) {
5441 mode_lib->vba.UrgentLatencySupport[i] = false;
5442 }
5443 }
5444 }
5445 /*Prefetch Check*/
5446
5447 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5448 mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = 0.0;
5449 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5450 if (mode_lib->vba.DCCEnable[k] == true) {
5451 mode_lib->vba.TotalNumberOfDCCActiveDPP[i] =
5452 mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
5453 + mode_lib->vba.NoOfDPP[i][k];
5454 }
5455 }
5456 }
5457 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5458 mode_lib->vba.ProjectedDCFCLKDeepSleep = 8.0;
5459 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5460 mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
5461 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5462 mode_lib->vba.PixelClock[k] / 16.0);
5463 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
5464 if (mode_lib->vba.VRatio[k] <= 1.0) {
5465 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5466 dml_max(
5467 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5468 1.1
5469 * dml_ceil(
5470 mode_lib->vba.BytePerPixelInDETY[k],
5471 1.0)
5472 / 64.0
5473 * mode_lib->vba.HRatio[k]
5474 * mode_lib->vba.PixelClock[k]
5475 / mode_lib->vba.NoOfDPP[i][k]);
5476 } else {
5477 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5478 dml_max(
5479 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5480 1.1
5481 * dml_ceil(
5482 mode_lib->vba.BytePerPixelInDETY[k],
5483 1.0)
5484 / 64.0
5485 * mode_lib->vba.PSCL_FACTOR[k]
5486 * mode_lib->vba.RequiredDPPCLK[i][k]);
5487 }
5488 } else {
5489 if (mode_lib->vba.VRatio[k] <= 1.0) {
5490 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5491 dml_max(
5492 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5493 1.1
5494 * dml_ceil(
5495 mode_lib->vba.BytePerPixelInDETY[k],
5496 1.0)
5497 / 32.0
5498 * mode_lib->vba.HRatio[k]
5499 * mode_lib->vba.PixelClock[k]
5500 / mode_lib->vba.NoOfDPP[i][k]);
5501 } else {
5502 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5503 dml_max(
5504 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5505 1.1
5506 * dml_ceil(
5507 mode_lib->vba.BytePerPixelInDETY[k],
5508 1.0)
5509 / 32.0
5510 * mode_lib->vba.PSCL_FACTOR[k]
5511 * mode_lib->vba.RequiredDPPCLK[i][k]);
5512 }
5513 if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
5514 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5515 dml_max(
5516 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5517 1.1
5518 * dml_ceil(
5519 mode_lib->vba.BytePerPixelInDETC[k],
5520 2.0)
5521 / 32.0
5522 * mode_lib->vba.HRatio[k]
5523 / 2.0
5524 * mode_lib->vba.PixelClock[k]
5525 / mode_lib->vba.NoOfDPP[i][k]);
5526 } else {
5527 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5528 dml_max(
5529 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5530 1.1
5531 * dml_ceil(
5532 mode_lib->vba.BytePerPixelInDETC[k],
5533 2.0)
5534 / 32.0
5535 * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
5536 * mode_lib->vba.RequiredDPPCLK[i][k]);
5537 }
5538 }
5539 }
5540 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5541 mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
5542 mode_lib,
5543 mode_lib->vba.DCCEnable[k],
5544 mode_lib->vba.Read256BlockHeightY[k],
5545 mode_lib->vba.Read256BlockWidthY[k],
5546 mode_lib->vba.SourcePixelFormat[k],
5547 mode_lib->vba.SurfaceTiling[k],
5548 dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
5549 mode_lib->vba.SourceScan[k],
5550 mode_lib->vba.ViewportWidth[k],
5551 mode_lib->vba.ViewportHeight[k],
5552 mode_lib->vba.SwathWidthYPerState[i][k],
5553 mode_lib->vba.VirtualMemoryEnable,
5554 mode_lib->vba.VMMPageSize,
5555 mode_lib->vba.PTEBufferSizeInRequests,
5556 mode_lib->vba.PDEProcessingBufIn64KBReqs,
5557 mode_lib->vba.PitchY[k],
5558 mode_lib->vba.DCCMetaPitchY[k],
5559 &mode_lib->vba.MacroTileWidthY[k],
5560 &mode_lib->vba.MetaRowBytesY,
5561 &mode_lib->vba.DPTEBytesPerRowY,
5562 &mode_lib->vba.PTEBufferSizeNotExceededY[i][k],
5563 &mode_lib->vba.dpte_row_height[k],
5564 &mode_lib->vba.meta_row_height[k]);
5565 mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
5566 mode_lib,
5567 mode_lib->vba.VRatio[k],
5568 mode_lib->vba.vtaps[k],
5569 mode_lib->vba.Interlace[k],
5570 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
5571 mode_lib->vba.SwathHeightYPerState[i][k],
5572 mode_lib->vba.ViewportYStartY[k],
5573 &mode_lib->vba.PrefillY[k],
5574 &mode_lib->vba.MaxNumSwY[k]);
5575 if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
5576 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
5577 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
5578 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
5579 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
5580 mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
5581 mode_lib,
5582 mode_lib->vba.DCCEnable[k],
5583 mode_lib->vba.Read256BlockHeightY[k],
5584 mode_lib->vba.Read256BlockWidthY[k],
5585 mode_lib->vba.SourcePixelFormat[k],
5586 mode_lib->vba.SurfaceTiling[k],
5587 dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
5588 mode_lib->vba.SourceScan[k],
5589 mode_lib->vba.ViewportWidth[k] / 2.0,
5590 mode_lib->vba.ViewportHeight[k] / 2.0,
5591 mode_lib->vba.SwathWidthYPerState[i][k] / 2.0,
5592 mode_lib->vba.VirtualMemoryEnable,
5593 mode_lib->vba.VMMPageSize,
5594 mode_lib->vba.PTEBufferSizeInRequests,
5595 mode_lib->vba.PDEProcessingBufIn64KBReqs,
5596 mode_lib->vba.PitchC[k],
5597 0.0,
5598 &mode_lib->vba.MacroTileWidthC[k],
5599 &mode_lib->vba.MetaRowBytesC,
5600 &mode_lib->vba.DPTEBytesPerRowC,
5601 &mode_lib->vba.PTEBufferSizeNotExceededC[i][k],
5602 &mode_lib->vba.dpte_row_height_chroma[k],
5603 &mode_lib->vba.meta_row_height_chroma[k]);
5604 mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
5605 mode_lib,
5606 mode_lib->vba.VRatio[k] / 2.0,
5607 mode_lib->vba.VTAPsChroma[k],
5608 mode_lib->vba.Interlace[k],
5609 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
5610 mode_lib->vba.SwathHeightCPerState[i][k],
5611 mode_lib->vba.ViewportYStartC[k],
5612 &mode_lib->vba.PrefillC[k],
5613 &mode_lib->vba.MaxNumSwC[k]);
5614 } else {
5615 mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
5616 mode_lib->vba.MetaRowBytesC = 0.0;
5617 mode_lib->vba.DPTEBytesPerRowC = 0.0;
5618 mode_lib->vba.PrefetchLinesC[k] = 0.0;
5619 mode_lib->vba.PTEBufferSizeNotExceededC[i][k] = true;
5620 }
5621 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] =
5622 mode_lib->vba.PDEAndMetaPTEBytesPerFrameY
5623 + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
5624 mode_lib->vba.MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY
5625 + mode_lib->vba.MetaRowBytesC;
5626 mode_lib->vba.DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY
5627 + mode_lib->vba.DPTEBytesPerRowC;
5628 }
5629 mode_lib->vba.ExtraLatency =
5630 mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
5631 + (mode_lib->vba.TotalNumberOfActiveDPP[i]
5632 * mode_lib->vba.PixelChunkSizeInKByte
5633 + mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
5634 * mode_lib->vba.MetaChunkSize)
5635 * 1024.0
5636 / mode_lib->vba.ReturnBWPerState[i];
5637 if (mode_lib->vba.VirtualMemoryEnable == true) {
5638 mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
5639 + mode_lib->vba.TotalNumberOfActiveDPP[i]
5640 * mode_lib->vba.PTEChunkSize * 1024.0
5641 / mode_lib->vba.ReturnBWPerState[i];
5642 }
5643 mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
5644 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5645 if (mode_lib->vba.BlendingAndTiming[k] == k) {
5646 if (mode_lib->vba.WritebackEnable[k] == true) {
5647 mode_lib->vba.WritebackDelay[i][k] =
5648 mode_lib->vba.WritebackLatency
5649 + CalculateWriteBackDelay(
5650 mode_lib->vba.WritebackPixelFormat[k],
5651 mode_lib->vba.WritebackHRatio[k],
5652 mode_lib->vba.WritebackVRatio[k],
5653 mode_lib->vba.WritebackLumaHTaps[k],
5654 mode_lib->vba.WritebackLumaVTaps[k],
5655 mode_lib->vba.WritebackChromaHTaps[k],
5656 mode_lib->vba.WritebackChromaVTaps[k],
5657 mode_lib->vba.WritebackDestinationWidth[k])
5658 / mode_lib->vba.RequiredDISPCLK[i];
5659 } else {
5660 mode_lib->vba.WritebackDelay[i][k] = 0.0;
5661 }
5662 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
5663 if (mode_lib->vba.BlendingAndTiming[j] == k
5664 && mode_lib->vba.WritebackEnable[j]
5665 == true) {
5666 mode_lib->vba.WritebackDelay[i][k] =
5667 dml_max(
5668 mode_lib->vba.WritebackDelay[i][k],
5669 mode_lib->vba.WritebackLatency
5670 + CalculateWriteBackDelay(
5671 mode_lib->vba.WritebackPixelFormat[j],
5672 mode_lib->vba.WritebackHRatio[j],
5673 mode_lib->vba.WritebackVRatio[j],
5674 mode_lib->vba.WritebackLumaHTaps[j],
5675 mode_lib->vba.WritebackLumaVTaps[j],
5676 mode_lib->vba.WritebackChromaHTaps[j],
5677 mode_lib->vba.WritebackChromaVTaps[j],
5678 mode_lib->vba.WritebackDestinationWidth[j])
5679 / mode_lib->vba.RequiredDISPCLK[i]);
5680 }
5681 }
5682 }
5683 }
5684 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5685 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
5686 if (mode_lib->vba.BlendingAndTiming[k] == j) {
5687 mode_lib->vba.WritebackDelay[i][k] =
5688 mode_lib->vba.WritebackDelay[i][j];
5689 }
5690 }
5691 }
5692 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5693 mode_lib->vba.MaximumVStartup[k] =
5694 mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
5695 - dml_max(
5696 1.0,
5697 dml_ceil(
5698 mode_lib->vba.WritebackDelay[i][k]
5699 / (mode_lib->vba.HTotal[k]
5700 / mode_lib->vba.PixelClock[k]),
5701 1.0));
5702 }
5703 mode_lib->vba.TWait = CalculateTWait(
5704 mode_lib->vba.PrefetchMode,
5705 mode_lib->vba.DRAMClockChangeLatency,
5706 mode_lib->vba.UrgentLatency,
5707 mode_lib->vba.SREnterPlusExitTime);
5708 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5709 if (mode_lib->vba.XFCEnabled[k] == true) {
5710 mode_lib->vba.XFCRemoteSurfaceFlipDelay =
5711 CalculateRemoteSurfaceFlipDelay(
5712 mode_lib,
5713 mode_lib->vba.VRatio[k],
5714 mode_lib->vba.SwathWidthYPerState[i][k],
5715 dml_ceil(
5716 mode_lib->vba.BytePerPixelInDETY[k],
5717 1.0),
5718 mode_lib->vba.HTotal[k]
5719 / mode_lib->vba.PixelClock[k],
5720 mode_lib->vba.XFCTSlvVupdateOffset,
5721 mode_lib->vba.XFCTSlvVupdateWidth,
5722 mode_lib->vba.XFCTSlvVreadyOffset,
5723 mode_lib->vba.XFCXBUFLatencyTolerance,
5724 mode_lib->vba.XFCFillBWOverhead,
5725 mode_lib->vba.XFCSlvChunkSize,
5726 mode_lib->vba.XFCBusTransportTime,
5727 mode_lib->vba.TimeCalc,
5728 mode_lib->vba.TWait,
5729 &mode_lib->vba.SrcActiveDrainRate,
5730 &mode_lib->vba.TInitXFill,
5731 &mode_lib->vba.TslvChk);
5732 } else {
5733 mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
5734 }
5735 mode_lib->vba.IsErrorResult[i][k] =
5736 CalculatePrefetchSchedule(
5737 mode_lib,
5738 mode_lib->vba.RequiredDPPCLK[i][k],
5739 mode_lib->vba.RequiredDISPCLK[i],
5740 mode_lib->vba.PixelClock[k],
5741 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5742 mode_lib->vba.DSCDelayPerState[i][k],
5743 mode_lib->vba.NoOfDPP[i][k],
5744 mode_lib->vba.ScalerEnabled[k],
5745 mode_lib->vba.NumberOfCursors[k],
5746 mode_lib->vba.DPPCLKDelaySubtotal,
5747 mode_lib->vba.DPPCLKDelaySCL,
5748 mode_lib->vba.DPPCLKDelaySCLLBOnly,
5749 mode_lib->vba.DPPCLKDelayCNVCFormater,
5750 mode_lib->vba.DPPCLKDelayCNVCCursor,
5751 mode_lib->vba.DISPCLKDelaySubtotal,
5752 mode_lib->vba.SwathWidthYPerState[i][k]
5753 / mode_lib->vba.HRatio[k],
5754 mode_lib->vba.OutputFormat[k],
5755 mode_lib->vba.VTotal[k]
5756 - mode_lib->vba.VActive[k],
5757 mode_lib->vba.HTotal[k],
5758 mode_lib->vba.MaxInterDCNTileRepeaters,
5759 mode_lib->vba.MaximumVStartup[k],
5760 mode_lib->vba.MaxPageTableLevels,
5761 mode_lib->vba.VirtualMemoryEnable,
5762 mode_lib->vba.DynamicMetadataEnable[k],
5763 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
5764 mode_lib->vba.DynamicMetadataTransmittedBytes[k],
5765 mode_lib->vba.DCCEnable[k],
5766 mode_lib->vba.UrgentLatency,
5767 mode_lib->vba.ExtraLatency,
5768 mode_lib->vba.TimeCalc,
5769 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
5770 mode_lib->vba.MetaRowBytes[k],
5771 mode_lib->vba.DPTEBytesPerRow[k],
5772 mode_lib->vba.PrefetchLinesY[k],
5773 mode_lib->vba.SwathWidthYPerState[i][k],
5774 mode_lib->vba.BytePerPixelInDETY[k],
5775 mode_lib->vba.PrefillY[k],
5776 mode_lib->vba.MaxNumSwY[k],
5777 mode_lib->vba.PrefetchLinesC[k],
5778 mode_lib->vba.BytePerPixelInDETC[k],
5779 mode_lib->vba.PrefillC[k],
5780 mode_lib->vba.MaxNumSwC[k],
5781 mode_lib->vba.SwathHeightYPerState[i][k],
5782 mode_lib->vba.SwathHeightCPerState[i][k],
5783 mode_lib->vba.TWait,
5784 mode_lib->vba.XFCEnabled[k],
5785 mode_lib->vba.XFCRemoteSurfaceFlipDelay,
5786 mode_lib->vba.Interlace[k],
5787 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
5788 mode_lib->vba.DSTXAfterScaler,
5789 mode_lib->vba.DSTYAfterScaler,
5790 &mode_lib->vba.LineTimesForPrefetch[k],
5791 &mode_lib->vba.PrefetchBW[k],
5792 &mode_lib->vba.LinesForMetaPTE[k],
5793 &mode_lib->vba.LinesForMetaAndDPTERow[k],
5794 &mode_lib->vba.VRatioPreY[i][k],
5795 &mode_lib->vba.VRatioPreC[i][k],
5796 &mode_lib->vba.RequiredPrefetchPixelDataBW[i][k],
5797 &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
5798 &mode_lib->vba.Tno_bw[k],
5799 &mode_lib->vba.VUpdateOffsetPix[k],
5800 &mode_lib->vba.VUpdateWidthPix[k],
5801 &mode_lib->vba.VReadyOffsetPix[k]);
5802 }
5803 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5804 mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k]
5805 * mode_lib->vba.CursorWidth[k][0]
5806 * mode_lib->vba.CursorBPP[k][0] / 8.0
5807 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
5808 * mode_lib->vba.VRatio[k];
5809 }
5810 mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
5811 mode_lib->vba.prefetch_vm_bw_valid = true;
5812 mode_lib->vba.prefetch_row_bw_valid = true;
5813 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5814 if (mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] == 0.0) {
5815 mode_lib->vba.prefetch_vm_bw[k] = 0.0;
5816 } else if (mode_lib->vba.LinesForMetaPTE[k] > 0.0) {
5817 mode_lib->vba.prefetch_vm_bw[k] =
5818 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
5819 / (mode_lib->vba.LinesForMetaPTE[k]
5820 * mode_lib->vba.HTotal[k]
5821 / mode_lib->vba.PixelClock[k]);
5822 } else {
5823 mode_lib->vba.prefetch_vm_bw[k] = 0.0;
5824 mode_lib->vba.prefetch_vm_bw_valid = false;
5825 }
5826 if (mode_lib->vba.MetaRowBytes[k] + mode_lib->vba.DPTEBytesPerRow[k]
5827 == 0.0) {
5828 mode_lib->vba.prefetch_row_bw[k] = 0.0;
5829 } else if (mode_lib->vba.LinesForMetaAndDPTERow[k] > 0.0) {
5830 mode_lib->vba.prefetch_row_bw[k] = (mode_lib->vba.MetaRowBytes[k]
5831 + mode_lib->vba.DPTEBytesPerRow[k])
5832 / (mode_lib->vba.LinesForMetaAndDPTERow[k]
5833 * mode_lib->vba.HTotal[k]
5834 / mode_lib->vba.PixelClock[k]);
5835 } else {
5836 mode_lib->vba.prefetch_row_bw[k] = 0.0;
5837 mode_lib->vba.prefetch_row_bw_valid = false;
5838 }
5839 mode_lib->vba.MaximumReadBandwidthWithPrefetch =
5840 mode_lib->vba.MaximumReadBandwidthWithPrefetch
5841 + mode_lib->vba.cursor_bw[k]
5842 + dml_max4(
5843 mode_lib->vba.prefetch_vm_bw[k],
5844 mode_lib->vba.prefetch_row_bw[k],
5845 mode_lib->vba.ReadBandwidth[k],
5846 mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]);
5847 }
5848 mode_lib->vba.PrefetchSupported[i] = true;
5849 if (mode_lib->vba.MaximumReadBandwidthWithPrefetch
5850 > mode_lib->vba.ReturnBWPerState[i]
5851 || mode_lib->vba.prefetch_vm_bw_valid == false
5852 || mode_lib->vba.prefetch_row_bw_valid == false) {
5853 mode_lib->vba.PrefetchSupported[i] = false;
5854 }
5855 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5856 if (mode_lib->vba.LineTimesForPrefetch[k] < 2.0
5857 || mode_lib->vba.LinesForMetaPTE[k] >= 8.0
5858 || mode_lib->vba.LinesForMetaAndDPTERow[k] >= 16.0
5859 || mode_lib->vba.IsErrorResult[i][k] == true) {
5860 mode_lib->vba.PrefetchSupported[i] = false;
5861 }
5862 }
5863 mode_lib->vba.VRatioInPrefetchSupported[i] = true;
5864 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5865 if (mode_lib->vba.VRatioPreY[i][k] > 4.0
5866 || mode_lib->vba.VRatioPreC[i][k] > 4.0
5867 || mode_lib->vba.IsErrorResult[i][k] == true) {
5868 mode_lib->vba.VRatioInPrefetchSupported[i] = false;
5869 }
5870 }
5871 if (mode_lib->vba.PrefetchSupported[i] == true
5872 && mode_lib->vba.VRatioInPrefetchSupported[i] == true) {
5873 mode_lib->vba.BandwidthAvailableForImmediateFlip =
5874 mode_lib->vba.ReturnBWPerState[i];
5875 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5876 mode_lib->vba.BandwidthAvailableForImmediateFlip =
5877 mode_lib->vba.BandwidthAvailableForImmediateFlip
5878 - mode_lib->vba.cursor_bw[k]
5879 - dml_max(
5880 mode_lib->vba.ReadBandwidth[k],
5881 mode_lib->vba.PrefetchBW[k]);
5882 }
5883 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5884 mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
5885 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
5886 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
5887 mode_lib->vba.ImmediateFlipBytes[k] =
5888 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
5889 + mode_lib->vba.MetaRowBytes[k]
5890 + mode_lib->vba.DPTEBytesPerRow[k];
5891 }
5892 }
5893 mode_lib->vba.TotImmediateFlipBytes = 0.0;
5894 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5895 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
5896 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
5897 mode_lib->vba.TotImmediateFlipBytes =
5898 mode_lib->vba.TotImmediateFlipBytes
5899 + mode_lib->vba.ImmediateFlipBytes[k];
5900 }
5901 }
5902 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5903 CalculateFlipSchedule(
5904 mode_lib,
5905 mode_lib->vba.ExtraLatency,
5906 mode_lib->vba.UrgentLatency,
5907 mode_lib->vba.MaxPageTableLevels,
5908 mode_lib->vba.VirtualMemoryEnable,
5909 mode_lib->vba.BandwidthAvailableForImmediateFlip,
5910 mode_lib->vba.TotImmediateFlipBytes,
5911 mode_lib->vba.SourcePixelFormat[k],
5912 mode_lib->vba.ImmediateFlipBytes[k],
5913 mode_lib->vba.HTotal[k]
5914 / mode_lib->vba.PixelClock[k],
5915 mode_lib->vba.VRatio[k],
5916 mode_lib->vba.Tno_bw[k],
5917 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
5918 mode_lib->vba.MetaRowBytes[k],
5919 mode_lib->vba.DPTEBytesPerRow[k],
5920 mode_lib->vba.DCCEnable[k],
5921 mode_lib->vba.dpte_row_height[k],
5922 mode_lib->vba.meta_row_height[k],
5923 mode_lib->vba.qual_row_bw[k],
5924 &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
5925 &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
5926 &mode_lib->vba.final_flip_bw[k],
5927 &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
5928 }
5929 mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
5930 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5931 mode_lib->vba.total_dcn_read_bw_with_flip =
5932 mode_lib->vba.total_dcn_read_bw_with_flip
5933 + mode_lib->vba.cursor_bw[k]
5934 + dml_max3(
5935 mode_lib->vba.prefetch_vm_bw[k],
5936 mode_lib->vba.prefetch_row_bw[k],
5937 mode_lib->vba.final_flip_bw[k]
5938 + dml_max(
5939 mode_lib->vba.ReadBandwidth[k],
5940 mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]));
5941 }
5942 mode_lib->vba.ImmediateFlipSupportedForState[i] = true;
5943 if (mode_lib->vba.total_dcn_read_bw_with_flip
5944 > mode_lib->vba.ReturnBWPerState[i]) {
5945 mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
5946 }
5947 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5948 if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
5949 mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
5950 }
5951 }
5952 } else {
5953 mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
5954 }
5955 }
5956 /*PTE Buffer Size Check*/
5957
5958 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5959 mode_lib->vba.PTEBufferSizeNotExceeded[i] = true;
5960 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5961 if (mode_lib->vba.PTEBufferSizeNotExceededY[i][k] == false
5962 || mode_lib->vba.PTEBufferSizeNotExceededC[i][k] == false) {
5963 mode_lib->vba.PTEBufferSizeNotExceeded[i] = false;
5964 }
5965 }
5966 }
5967 /*Cursor Support Check*/
5968
5969 mode_lib->vba.CursorSupport = true;
5970 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5971 if (mode_lib->vba.CursorWidth[k][0] > 0.0) {
5972 if (dml_floor(
5973 dml_floor(
5974 mode_lib->vba.CursorBufferSize
5975 - mode_lib->vba.CursorChunkSize,
5976 mode_lib->vba.CursorChunkSize) * 1024.0
5977 / (mode_lib->vba.CursorWidth[k][0]
5978 * mode_lib->vba.CursorBPP[k][0]
5979 / 8.0),
5980 1.0)
5981 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
5982 / mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatency
5983 || (mode_lib->vba.CursorBPP[k][0] == 64.0
5984 && mode_lib->vba.Cursor64BppSupport == false)) {
5985 mode_lib->vba.CursorSupport = false;
5986 }
5987 }
5988 }
5989 /*Valid Pitch Check*/
5990
5991 mode_lib->vba.PitchSupport = true;
5992 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5993 mode_lib->vba.AlignedYPitch[k] = dml_ceil(
5994 dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
5995 mode_lib->vba.MacroTileWidthY[k]);
5996 if (mode_lib->vba.AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
5997 mode_lib->vba.PitchSupport = false;
5998 }
5999 if (mode_lib->vba.DCCEnable[k] == true) {
6000 mode_lib->vba.AlignedDCCMetaPitch[k] = dml_ceil(
6001 dml_max(
6002 mode_lib->vba.DCCMetaPitchY[k],
6003 mode_lib->vba.ViewportWidth[k]),
6004 64.0 * mode_lib->vba.Read256BlockWidthY[k]);
6005 } else {
6006 mode_lib->vba.AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
6007 }
6008 if (mode_lib->vba.AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
6009 mode_lib->vba.PitchSupport = false;
6010 }
6011 if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
6012 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
6013 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
6014 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
6015 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
6016 mode_lib->vba.AlignedCPitch[k] = dml_ceil(
6017 dml_max(
6018 mode_lib->vba.PitchC[k],
6019 mode_lib->vba.ViewportWidth[k] / 2.0),
6020 mode_lib->vba.MacroTileWidthC[k]);
6021 } else {
6022 mode_lib->vba.AlignedCPitch[k] = mode_lib->vba.PitchC[k];
6023 }
6024 if (mode_lib->vba.AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
6025 mode_lib->vba.PitchSupport = false;
6026 }
6027 }
6028 /*Mode Support, Voltage State and SOC Configuration*/
6029
6030 for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
6031 if (mode_lib->vba.ScaleRatioAndTapsSupport == true
6032 && mode_lib->vba.SourceFormatPixelAndScanSupport == true
6033 && mode_lib->vba.ViewportSizeSupport[i] == true
6034 && mode_lib->vba.BandwidthSupport[i] == true
6035 && mode_lib->vba.DIOSupport[i] == true
6036 && mode_lib->vba.NotEnoughDSCUnits[i] == false
6037 && mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] == false
6038 && mode_lib->vba.UrgentLatencySupport[i] == true
6039 && mode_lib->vba.ROBSupport[i] == true
6040 && mode_lib->vba.DISPCLK_DPPCLK_Support[i] == true
6041 && mode_lib->vba.TotalAvailablePipesSupport[i] == true
6042 && mode_lib->vba.NumberOfOTGSupport == true
6043 && mode_lib->vba.WritebackModeSupport == true
6044 && mode_lib->vba.WritebackLatencySupport == true
6045 && mode_lib->vba.WritebackScaleRatioAndTapsSupport == true
6046 && mode_lib->vba.CursorSupport == true
6047 && mode_lib->vba.PitchSupport == true
6048 && mode_lib->vba.PrefetchSupported[i] == true
6049 && mode_lib->vba.VRatioInPrefetchSupported[i] == true
6050 && mode_lib->vba.PTEBufferSizeNotExceeded[i] == true
6051 && mode_lib->vba.NonsupportedDSCInputBPC == false) {
6052 mode_lib->vba.ModeSupport[i] = true;
6053 } else {
6054 mode_lib->vba.ModeSupport[i] = false;
6055 }
6056 }
6057 for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
6058 if (i == DC__VOLTAGE_STATES || mode_lib->vba.ModeSupport[i] == true) {
6059 mode_lib->vba.VoltageLevel = i;
6060 }
6061 }
6062 mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
6063 mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
6064 mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
6065 mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
6066 mode_lib->vba.FabricAndDRAMBandwidth =
6067 mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
6068 mode_lib->vba.ImmediateFlipSupport =
6069 mode_lib->vba.ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel];
6070 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6071 mode_lib->vba.DPPPerPlane[k] = mode_lib->vba.NoOfDPP[mode_lib->vba.VoltageLevel][k];
6072 }
6073 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6074 if (mode_lib->vba.BlendingAndTiming[k] == k) {
6075 mode_lib->vba.ODMCombineEnabled[k] =
6076 mode_lib->vba.ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
6077 } else {
6078 mode_lib->vba.ODMCombineEnabled[k] = 0;
6079 }
6080 mode_lib->vba.DSCEnabled[k] =
6081 mode_lib->vba.RequiresDSC[mode_lib->vba.VoltageLevel][k];
6082 mode_lib->vba.OutputBpp[k] =
6083 mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k];
6084 }
6085}