Home | History | Annotate | Line # | Download | only in dcn20
      1 /*	$NetBSD: amdgpu_display_mode_vba_20.c,v 1.2 2021/12/18 23:45:04 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2018 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_display_mode_vba_20.c,v 1.2 2021/12/18 23:45:04 riastradh Exp $");
     30 
     31 #include "../display_mode_lib.h"
     32 #include "display_mode_vba_20.h"
     33 #include "../dml_inline_defs.h"
     34 
     35 /*
     36  * NOTE:
     37  *   This file is gcc-parseable HW gospel, coming straight from HW engineers.
     38  *
     39  * It doesn't adhere to Linux kernel style and sometimes will do things in odd
     40  * ways. Unless there is something clearly wrong with it the code should
     41  * remain as-is as it provides us with a guarantee from HW that it is correct.
     42  */
     43 
     44 #define BPP_INVALID 0
     45 #define BPP_BLENDED_PIPE 0xffffffff
     46 #define DCN20_MAX_420_IMAGE_WIDTH 4096
     47 
     48 static double adjust_ReturnBW(
     49 		struct display_mode_lib *mode_lib,
     50 		double ReturnBW,
     51 		bool DCCEnabledAnyPlane,
     52 		double ReturnBandwidthToDCN);
     53 static unsigned int dscceComputeDelay(
     54 		unsigned int bpc,
     55 		double bpp,
     56 		unsigned int sliceWidth,
     57 		unsigned int numSlices,
     58 		enum output_format_class pixelFormat);
     59 static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
     60 // Super monster function with some 45 argument
     61 static bool CalculatePrefetchSchedule(
     62 		struct display_mode_lib *mode_lib,
     63 		double DPPCLK,
     64 		double DISPCLK,
     65 		double PixelClock,
     66 		double DCFCLKDeepSleep,
     67 		unsigned int DSCDelay,
     68 		unsigned int DPPPerPlane,
     69 		bool ScalerEnabled,
     70 		unsigned int NumberOfCursors,
     71 		double DPPCLKDelaySubtotal,
     72 		double DPPCLKDelaySCL,
     73 		double DPPCLKDelaySCLLBOnly,
     74 		double DPPCLKDelayCNVCFormater,
     75 		double DPPCLKDelayCNVCCursor,
     76 		double DISPCLKDelaySubtotal,
     77 		unsigned int ScalerRecoutWidth,
     78 		enum output_format_class OutputFormat,
     79 		unsigned int VBlank,
     80 		unsigned int HTotal,
     81 		unsigned int MaxInterDCNTileRepeaters,
     82 		unsigned int VStartup,
     83 		unsigned int PageTableLevels,
     84 		bool GPUVMEnable,
     85 		bool DynamicMetadataEnable,
     86 		unsigned int DynamicMetadataLinesBeforeActiveRequired,
     87 		unsigned int DynamicMetadataTransmittedBytes,
     88 		bool DCCEnable,
     89 		double UrgentLatencyPixelDataOnly,
     90 		double UrgentExtraLatency,
     91 		double TCalc,
     92 		unsigned int PDEAndMetaPTEBytesFrame,
     93 		unsigned int MetaRowByte,
     94 		unsigned int PixelPTEBytesPerRow,
     95 		double PrefetchSourceLinesY,
     96 		unsigned int SwathWidthY,
     97 		double BytePerPixelDETY,
     98 		double VInitPreFillY,
     99 		unsigned int MaxNumSwathY,
    100 		double PrefetchSourceLinesC,
    101 		double BytePerPixelDETC,
    102 		double VInitPreFillC,
    103 		unsigned int MaxNumSwathC,
    104 		unsigned int SwathHeightY,
    105 		unsigned int SwathHeightC,
    106 		double TWait,
    107 		bool XFCEnabled,
    108 		double XFCRemoteSurfaceFlipDelay,
    109 		bool InterlaceEnable,
    110 		bool ProgressiveToInterlaceUnitInOPP,
    111 		double *DSTXAfterScaler,
    112 		double *DSTYAfterScaler,
    113 		double *DestinationLinesForPrefetch,
    114 		double *PrefetchBandwidth,
    115 		double *DestinationLinesToRequestVMInVBlank,
    116 		double *DestinationLinesToRequestRowInVBlank,
    117 		double *VRatioPrefetchY,
    118 		double *VRatioPrefetchC,
    119 		double *RequiredPrefetchPixDataBW,
    120 		unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
    121 		double *Tno_bw,
    122 		unsigned int *VUpdateOffsetPix,
    123 		double *VUpdateWidthPix,
    124 		double *VReadyOffsetPix);
    125 static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
    126 static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
    127 static double CalculatePrefetchSourceLines(
    128 		struct display_mode_lib *mode_lib,
    129 		double VRatio,
    130 		double vtaps,
    131 		bool Interlace,
    132 		bool ProgressiveToInterlaceUnitInOPP,
    133 		unsigned int SwathHeight,
    134 		unsigned int ViewportYStart,
    135 		double *VInitPreFill,
    136 		unsigned int *MaxNumSwath);
    137 static unsigned int CalculateVMAndRowBytes(
    138 		struct display_mode_lib *mode_lib,
    139 		bool DCCEnable,
    140 		unsigned int BlockHeight256Bytes,
    141 		unsigned int BlockWidth256Bytes,
    142 		enum source_format_class SourcePixelFormat,
    143 		unsigned int SurfaceTiling,
    144 		unsigned int BytePerPixel,
    145 		enum scan_direction_class ScanDirection,
    146 		unsigned int ViewportWidth,
    147 		unsigned int ViewportHeight,
    148 		unsigned int SwathWidthY,
    149 		bool GPUVMEnable,
    150 		unsigned int VMMPageSize,
    151 		unsigned int PTEBufferSizeInRequestsLuma,
    152 		unsigned int PDEProcessingBufIn64KBReqs,
    153 		unsigned int Pitch,
    154 		unsigned int DCCMetaPitch,
    155 		unsigned int *MacroTileWidth,
    156 		unsigned int *MetaRowByte,
    157 		unsigned int *PixelPTEBytesPerRow,
    158 		bool *PTEBufferSizeNotExceeded,
    159 		unsigned int *dpte_row_height,
    160 		unsigned int *meta_row_height);
    161 static double CalculateTWait(
    162 		unsigned int PrefetchMode,
    163 		double DRAMClockChangeLatency,
    164 		double UrgentLatencyPixelDataOnly,
    165 		double SREnterPlusExitTime);
    166 static double CalculateRemoteSurfaceFlipDelay(
    167 		struct display_mode_lib *mode_lib,
    168 		double VRatio,
    169 		double SwathWidth,
    170 		double Bpp,
    171 		double LineTime,
    172 		double XFCTSlvVupdateOffset,
    173 		double XFCTSlvVupdateWidth,
    174 		double XFCTSlvVreadyOffset,
    175 		double XFCXBUFLatencyTolerance,
    176 		double XFCFillBWOverhead,
    177 		double XFCSlvChunkSize,
    178 		double XFCBusTransportTime,
    179 		double TCalc,
    180 		double TWait,
    181 		double *SrcActiveDrainRate,
    182 		double *TInitXFill,
    183 		double *TslvChk);
    184 static void CalculateActiveRowBandwidth(
    185 		bool GPUVMEnable,
    186 		enum source_format_class SourcePixelFormat,
    187 		double VRatio,
    188 		bool DCCEnable,
    189 		double LineTime,
    190 		unsigned int MetaRowByteLuma,
    191 		unsigned int MetaRowByteChroma,
    192 		unsigned int meta_row_height_luma,
    193 		unsigned int meta_row_height_chroma,
    194 		unsigned int PixelPTEBytesPerRowLuma,
    195 		unsigned int PixelPTEBytesPerRowChroma,
    196 		unsigned int dpte_row_height_luma,
    197 		unsigned int dpte_row_height_chroma,
    198 		double *meta_row_bw,
    199 		double *dpte_row_bw,
    200 		double *qual_row_bw);
    201 static void CalculateFlipSchedule(
    202 		struct display_mode_lib *mode_lib,
    203 		double UrgentExtraLatency,
    204 		double UrgentLatencyPixelDataOnly,
    205 		unsigned int GPUVMMaxPageTableLevels,
    206 		bool GPUVMEnable,
    207 		double BandwidthAvailableForImmediateFlip,
    208 		unsigned int TotImmediateFlipBytes,
    209 		enum source_format_class SourcePixelFormat,
    210 		unsigned int ImmediateFlipBytes,
    211 		double LineTime,
    212 		double VRatio,
    213 		double Tno_bw,
    214 		double PDEAndMetaPTEBytesFrame,
    215 		unsigned int MetaRowByte,
    216 		unsigned int PixelPTEBytesPerRow,
    217 		bool DCCEnable,
    218 		unsigned int dpte_row_height,
    219 		unsigned int meta_row_height,
    220 		double qual_row_bw,
    221 		double *DestinationLinesToRequestVMInImmediateFlip,
    222 		double *DestinationLinesToRequestRowInImmediateFlip,
    223 		double *final_flip_bw,
    224 		bool *ImmediateFlipSupportedForPipe);
    225 static double CalculateWriteBackDelay(
    226 		enum source_format_class WritebackPixelFormat,
    227 		double WritebackHRatio,
    228 		double WritebackVRatio,
    229 		unsigned int WritebackLumaHTaps,
    230 		unsigned int WritebackLumaVTaps,
    231 		unsigned int WritebackChromaHTaps,
    232 		unsigned int WritebackChromaVTaps,
    233 		unsigned int WritebackDestinationWidth);
    234 
    235 static void dml20_DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
    236 static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
    237 		struct display_mode_lib *mode_lib);
    238 
    239 void dml20_recalculate(struct display_mode_lib *mode_lib)
    240 {
    241 	ModeSupportAndSystemConfiguration(mode_lib);
    242 	mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
    243 		mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels * mode_lib->vba.DRAMChannelWidth,
    244 		mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000.0;
    245 	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
    246 	dml20_DisplayPipeConfiguration(mode_lib);
    247 	dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
    248 }
    249 
    250 static double adjust_ReturnBW(
    251 		struct display_mode_lib *mode_lib,
    252 		double ReturnBW,
    253 		bool DCCEnabledAnyPlane,
    254 		double ReturnBandwidthToDCN)
    255 {
    256 	double CriticalCompression;
    257 
    258 	if (DCCEnabledAnyPlane
    259 			&& ReturnBandwidthToDCN
    260 					> mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
    261 		ReturnBW =
    262 				dml_min(
    263 						ReturnBW,
    264 						ReturnBandwidthToDCN * 4
    265 								* (1.0
    266 										- mode_lib->vba.UrgentLatencyPixelDataOnly
    267 												/ ((mode_lib->vba.ROBBufferSizeInKByte
    268 														- mode_lib->vba.PixelChunkSizeInKByte)
    269 														* 1024
    270 														/ ReturnBandwidthToDCN
    271 														- mode_lib->vba.DCFCLK
    272 																* mode_lib->vba.ReturnBusWidth
    273 																/ 4)
    274 										+ mode_lib->vba.UrgentLatencyPixelDataOnly));
    275 
    276 	CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
    277 			* mode_lib->vba.UrgentLatencyPixelDataOnly
    278 			/ (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatencyPixelDataOnly
    279 					+ (mode_lib->vba.ROBBufferSizeInKByte
    280 							- mode_lib->vba.PixelChunkSizeInKByte)
    281 							* 1024);
    282 
    283 	if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
    284 		ReturnBW =
    285 				dml_min(
    286 						ReturnBW,
    287 						4.0 * ReturnBandwidthToDCN
    288 								* (mode_lib->vba.ROBBufferSizeInKByte
    289 										- mode_lib->vba.PixelChunkSizeInKByte)
    290 								* 1024
    291 								* mode_lib->vba.ReturnBusWidth
    292 								* mode_lib->vba.DCFCLK
    293 								* mode_lib->vba.UrgentLatencyPixelDataOnly
    294 								/ dml_pow(
    295 										(ReturnBandwidthToDCN
    296 												* mode_lib->vba.UrgentLatencyPixelDataOnly
    297 												+ (mode_lib->vba.ROBBufferSizeInKByte
    298 														- mode_lib->vba.PixelChunkSizeInKByte)
    299 														* 1024),
    300 										2));
    301 
    302 	return ReturnBW;
    303 }
    304 
    305 static unsigned int dscceComputeDelay(
    306 		unsigned int bpc,
    307 		double bpp,
    308 		unsigned int sliceWidth,
    309 		unsigned int numSlices,
    310 		enum output_format_class pixelFormat)
    311 {
    312 	// valid bpc         = source bits per component in the set of {8, 10, 12}
    313 	// valid bpp         = increments of 1/16 of a bit
    314 	//                    min = 6/7/8 in N420/N422/444, respectively
    315 	//                    max = such that compression is 1:1
    316 	//valid sliceWidth  = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
    317 	//valid numSlices   = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
    318 	//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
    319 
    320 	// fixed value
    321 	unsigned int rcModelSize = 8192;
    322 
    323 	// N422/N420 operate at 2 pixels per clock
    324 	unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
    325 			Delay, pixels;
    326 
    327 	if (pixelFormat == dm_n422 || pixelFormat == dm_420)
    328 		pixelsPerClock = 2;
    329 	// #all other modes operate at 1 pixel per clock
    330 	else
    331 		pixelsPerClock = 1;
    332 
    333 	//initial transmit delay as per PPS
    334 	initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
    335 
    336 	//compute ssm delay
    337 	if (bpc == 8)
    338 		D = 81;
    339 	else if (bpc == 10)
    340 		D = 89;
    341 	else
    342 		D = 113;
    343 
    344 	//divide by pixel per cycle to compute slice width as seen by DSC
    345 	w = sliceWidth / pixelsPerClock;
    346 
    347 	//422 mode has an additional cycle of delay
    348 	if (pixelFormat == dm_s422)
    349 		s = 1;
    350 	else
    351 		s = 0;
    352 
    353 	//main calculation for the dscce
    354 	ix = initalXmitDelay + 45;
    355 	wx = (w + 2) / 3;
    356 	p = 3 * wx - w;
    357 	l0 = ix / w;
    358 	a = ix + p * l0;
    359 	ax = (a + 2) / 3 + D + 6 + 1;
    360 	l = (ax + wx - 1) / wx;
    361 	if ((ix % w) == 0 && p != 0)
    362 		lstall = 1;
    363 	else
    364 		lstall = 0;
    365 	Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
    366 
    367 	//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
    368 	pixels = Delay * 3 * pixelsPerClock;
    369 	return pixels;
    370 }
    371 
    372 static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
    373 {
    374 	unsigned int Delay = 0;
    375 
    376 	if (pixelFormat == dm_420) {
    377 		//   sfr
    378 		Delay = Delay + 2;
    379 		//   dsccif
    380 		Delay = Delay + 0;
    381 		//   dscc - input deserializer
    382 		Delay = Delay + 3;
    383 		//   dscc gets pixels every other cycle
    384 		Delay = Delay + 2;
    385 		//   dscc - input cdc fifo
    386 		Delay = Delay + 12;
    387 		//   dscc gets pixels every other cycle
    388 		Delay = Delay + 13;
    389 		//   dscc - cdc uncertainty
    390 		Delay = Delay + 2;
    391 		//   dscc - output cdc fifo
    392 		Delay = Delay + 7;
    393 		//   dscc gets pixels every other cycle
    394 		Delay = Delay + 3;
    395 		//   dscc - cdc uncertainty
    396 		Delay = Delay + 2;
    397 		//   dscc - output serializer
    398 		Delay = Delay + 1;
    399 		//   sft
    400 		Delay = Delay + 1;
    401 	} else if (pixelFormat == dm_n422) {
    402 		//   sfr
    403 		Delay = Delay + 2;
    404 		//   dsccif
    405 		Delay = Delay + 1;
    406 		//   dscc - input deserializer
    407 		Delay = Delay + 5;
    408 		//  dscc - input cdc fifo
    409 		Delay = Delay + 25;
    410 		//   dscc - cdc uncertainty
    411 		Delay = Delay + 2;
    412 		//   dscc - output cdc fifo
    413 		Delay = Delay + 10;
    414 		//   dscc - cdc uncertainty
    415 		Delay = Delay + 2;
    416 		//   dscc - output serializer
    417 		Delay = Delay + 1;
    418 		//   sft
    419 		Delay = Delay + 1;
    420 	} else {
    421 		//   sfr
    422 		Delay = Delay + 2;
    423 		//   dsccif
    424 		Delay = Delay + 0;
    425 		//   dscc - input deserializer
    426 		Delay = Delay + 3;
    427 		//   dscc - input cdc fifo
    428 		Delay = Delay + 12;
    429 		//   dscc - cdc uncertainty
    430 		Delay = Delay + 2;
    431 		//   dscc - output cdc fifo
    432 		Delay = Delay + 7;
    433 		//   dscc - output serializer
    434 		Delay = Delay + 1;
    435 		//   dscc - cdc uncertainty
    436 		Delay = Delay + 2;
    437 		//   sft
    438 		Delay = Delay + 1;
    439 	}
    440 
    441 	return Delay;
    442 }
    443 
    444 static bool CalculatePrefetchSchedule(
    445 		struct display_mode_lib *mode_lib,
    446 		double DPPCLK,
    447 		double DISPCLK,
    448 		double PixelClock,
    449 		double DCFCLKDeepSleep,
    450 		unsigned int DSCDelay,
    451 		unsigned int DPPPerPlane,
    452 		bool ScalerEnabled,
    453 		unsigned int NumberOfCursors,
    454 		double DPPCLKDelaySubtotal,
    455 		double DPPCLKDelaySCL,
    456 		double DPPCLKDelaySCLLBOnly,
    457 		double DPPCLKDelayCNVCFormater,
    458 		double DPPCLKDelayCNVCCursor,
    459 		double DISPCLKDelaySubtotal,
    460 		unsigned int ScalerRecoutWidth,
    461 		enum output_format_class OutputFormat,
    462 		unsigned int VBlank,
    463 		unsigned int HTotal,
    464 		unsigned int MaxInterDCNTileRepeaters,
    465 		unsigned int VStartup,
    466 		unsigned int PageTableLevels,
    467 		bool GPUVMEnable,
    468 		bool DynamicMetadataEnable,
    469 		unsigned int DynamicMetadataLinesBeforeActiveRequired,
    470 		unsigned int DynamicMetadataTransmittedBytes,
    471 		bool DCCEnable,
    472 		double UrgentLatencyPixelDataOnly,
    473 		double UrgentExtraLatency,
    474 		double TCalc,
    475 		unsigned int PDEAndMetaPTEBytesFrame,
    476 		unsigned int MetaRowByte,
    477 		unsigned int PixelPTEBytesPerRow,
    478 		double PrefetchSourceLinesY,
    479 		unsigned int SwathWidthY,
    480 		double BytePerPixelDETY,
    481 		double VInitPreFillY,
    482 		unsigned int MaxNumSwathY,
    483 		double PrefetchSourceLinesC,
    484 		double BytePerPixelDETC,
    485 		double VInitPreFillC,
    486 		unsigned int MaxNumSwathC,
    487 		unsigned int SwathHeightY,
    488 		unsigned int SwathHeightC,
    489 		double TWait,
    490 		bool XFCEnabled,
    491 		double XFCRemoteSurfaceFlipDelay,
    492 		bool InterlaceEnable,
    493 		bool ProgressiveToInterlaceUnitInOPP,
    494 		double *DSTXAfterScaler,
    495 		double *DSTYAfterScaler,
    496 		double *DestinationLinesForPrefetch,
    497 		double *PrefetchBandwidth,
    498 		double *DestinationLinesToRequestVMInVBlank,
    499 		double *DestinationLinesToRequestRowInVBlank,
    500 		double *VRatioPrefetchY,
    501 		double *VRatioPrefetchC,
    502 		double *RequiredPrefetchPixDataBW,
    503 		unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
    504 		double *Tno_bw,
    505 		unsigned int *VUpdateOffsetPix,
    506 		double *VUpdateWidthPix,
    507 		double *VReadyOffsetPix)
    508 {
    509 	bool MyError = false;
    510 	unsigned int DPPCycles, DISPCLKCycles;
    511 	double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
    512 	double Tdm, LineTime, Tsetup;
    513 	double dst_y_prefetch_equ;
    514 	double Tsw_oto;
    515 	double prefetch_bw_oto;
    516 	double Tvm_oto;
    517 	double Tr0_oto;
    518 	double Tpre_oto;
    519 	double dst_y_prefetch_oto;
    520 	double TimeForFetchingMetaPTE = 0;
    521 	double TimeForFetchingRowInVBlank = 0;
    522 	double LinesToRequestPrefetchPixelData = 0;
    523 
    524 	if (ScalerEnabled)
    525 		DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
    526 	else
    527 		DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
    528 
    529 	DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
    530 
    531 	DISPCLKCycles = DISPCLKDelaySubtotal;
    532 
    533 	if (DPPCLK == 0.0 || DISPCLK == 0.0)
    534 		return true;
    535 
    536 	*DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
    537 			+ DSCDelay;
    538 
    539 	if (DPPPerPlane > 1)
    540 		*DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
    541 
    542 	if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
    543 		*DSTYAfterScaler = 1;
    544 	else
    545 		*DSTYAfterScaler = 0;
    546 
    547 	DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
    548 	*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
    549 	*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
    550 
    551 	*VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
    552 	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
    553 	*VUpdateWidthPix = (14.0 / DCFCLKDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
    554 			* PixelClock;
    555 
    556 	*VReadyOffsetPix = dml_max(
    557 			150.0 / DPPCLK,
    558 			TotalRepeaterDelayTime + 20.0 / DCFCLKDeepSleep + 10.0 / DPPCLK)
    559 			* PixelClock;
    560 
    561 	Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
    562 
    563 	LineTime = (double) HTotal / PixelClock;
    564 
    565 	if (DynamicMetadataEnable) {
    566 		double Tdmbf, Tdmec, Tdmsks;
    567 
    568 		Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
    569 		Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
    570 		Tdmec = LineTime;
    571 		if (DynamicMetadataLinesBeforeActiveRequired == 0)
    572 			Tdmsks = VBlank * LineTime / 2.0;
    573 		else
    574 			Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
    575 		if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
    576 			Tdmsks = Tdmsks / 2;
    577 		if (VStartup * LineTime
    578 				< Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
    579 			MyError = true;
    580 			*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
    581 					+ UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
    582 		} else
    583 			*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
    584 	} else
    585 		Tdm = 0;
    586 
    587 	if (GPUVMEnable) {
    588 		if (PageTableLevels == 4)
    589 			*Tno_bw = UrgentExtraLatency + UrgentLatencyPixelDataOnly;
    590 		else if (PageTableLevels == 3)
    591 			*Tno_bw = UrgentExtraLatency;
    592 		else
    593 			*Tno_bw = 0;
    594 	} else if (DCCEnable)
    595 		*Tno_bw = LineTime;
    596 	else
    597 		*Tno_bw = LineTime / 4;
    598 
    599 	dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
    600 			- (Tsetup + Tdm) / LineTime
    601 			- (*DSTYAfterScaler + *DSTXAfterScaler / HTotal);
    602 
    603 	Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
    604 
    605 	prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
    606 			+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
    607 			+ PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
    608 			/ Tsw_oto;
    609 
    610 	if (GPUVMEnable == true) {
    611 		Tvm_oto =
    612 				dml_max(
    613 						*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
    614 						dml_max(
    615 								UrgentExtraLatency
    616 										+ UrgentLatencyPixelDataOnly
    617 												* (PageTableLevels
    618 														- 1),
    619 								LineTime / 4.0));
    620 	} else
    621 		Tvm_oto = LineTime / 4.0;
    622 
    623 	if ((GPUVMEnable == true || DCCEnable == true)) {
    624 		Tr0_oto = dml_max(
    625 				(MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
    626 				dml_max(UrgentLatencyPixelDataOnly, dml_max(LineTime - Tvm_oto, LineTime / 4)));
    627 	} else
    628 		Tr0_oto = LineTime - Tvm_oto;
    629 
    630 	Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
    631 
    632 	dst_y_prefetch_oto = Tpre_oto / LineTime;
    633 
    634 	if (dst_y_prefetch_oto < dst_y_prefetch_equ)
    635 		*DestinationLinesForPrefetch = dst_y_prefetch_oto;
    636 	else
    637 		*DestinationLinesForPrefetch = dst_y_prefetch_equ;
    638 
    639 	*DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
    640 			/ 4;
    641 
    642 	dml_print("DML: VStartup: %d\n", VStartup);
    643 	dml_print("DML: TCalc: %f\n", TCalc);
    644 	dml_print("DML: TWait: %f\n", TWait);
    645 	dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
    646 	dml_print("DML: LineTime: %f\n", LineTime);
    647 	dml_print("DML: Tsetup: %f\n", Tsetup);
    648 	dml_print("DML: Tdm: %f\n", Tdm);
    649 	dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler);
    650 	dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler);
    651 	dml_print("DML: HTotal: %d\n", HTotal);
    652 
    653 	*PrefetchBandwidth = 0;
    654 	*DestinationLinesToRequestVMInVBlank = 0;
    655 	*DestinationLinesToRequestRowInVBlank = 0;
    656 	*VRatioPrefetchY = 0;
    657 	*VRatioPrefetchC = 0;
    658 	*RequiredPrefetchPixDataBW = 0;
    659 	if (*DestinationLinesForPrefetch > 1) {
    660 		*PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
    661 				+ 2 * PixelPTEBytesPerRow
    662 				+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
    663 				+ PrefetchSourceLinesC * SwathWidthY / 2
    664 						* dml_ceil(BytePerPixelDETC, 2))
    665 				/ (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
    666 		if (GPUVMEnable) {
    667 			TimeForFetchingMetaPTE =
    668 					dml_max(
    669 							*Tno_bw
    670 									+ (double) PDEAndMetaPTEBytesFrame
    671 											/ *PrefetchBandwidth,
    672 							dml_max(
    673 									UrgentExtraLatency
    674 											+ UrgentLatencyPixelDataOnly
    675 													* (PageTableLevels
    676 															- 1),
    677 									LineTime / 4));
    678 		} else {
    679 			if (NumberOfCursors > 0 || XFCEnabled)
    680 				TimeForFetchingMetaPTE = LineTime / 4;
    681 			else
    682 				TimeForFetchingMetaPTE = 0.0;
    683 		}
    684 
    685 		if ((GPUVMEnable == true || DCCEnable == true)) {
    686 			TimeForFetchingRowInVBlank =
    687 					dml_max(
    688 							(MetaRowByte + PixelPTEBytesPerRow)
    689 									/ *PrefetchBandwidth,
    690 							dml_max(
    691 									UrgentLatencyPixelDataOnly,
    692 									dml_max(
    693 											LineTime
    694 													- TimeForFetchingMetaPTE,
    695 											LineTime
    696 													/ 4.0)));
    697 		} else {
    698 			if (NumberOfCursors > 0 || XFCEnabled)
    699 				TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
    700 			else
    701 				TimeForFetchingRowInVBlank = 0.0;
    702 		}
    703 
    704 		*DestinationLinesToRequestVMInVBlank = dml_floor(
    705 				4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
    706 				1) / 4.0;
    707 
    708 		*DestinationLinesToRequestRowInVBlank = dml_floor(
    709 				4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
    710 				1) / 4.0;
    711 
    712 		LinesToRequestPrefetchPixelData =
    713 				*DestinationLinesForPrefetch
    714 						- ((NumberOfCursors > 0 || GPUVMEnable
    715 								|| DCCEnable) ?
    716 								(*DestinationLinesToRequestVMInVBlank
    717 										+ *DestinationLinesToRequestRowInVBlank) :
    718 								0.0);
    719 
    720 		if (LinesToRequestPrefetchPixelData > 0) {
    721 
    722 			*VRatioPrefetchY = (double) PrefetchSourceLinesY
    723 					/ LinesToRequestPrefetchPixelData;
    724 			*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
    725 			if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
    726 				if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
    727 					*VRatioPrefetchY =
    728 							dml_max(
    729 									(double) PrefetchSourceLinesY
    730 											/ LinesToRequestPrefetchPixelData,
    731 									(double) MaxNumSwathY
    732 											* SwathHeightY
    733 											/ (LinesToRequestPrefetchPixelData
    734 													- (VInitPreFillY
    735 															- 3.0)
    736 															/ 2.0));
    737 					*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
    738 				} else {
    739 					MyError = true;
    740 					*VRatioPrefetchY = 0;
    741 				}
    742 			}
    743 
    744 			*VRatioPrefetchC = (double) PrefetchSourceLinesC
    745 					/ LinesToRequestPrefetchPixelData;
    746 			*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
    747 
    748 			if ((SwathHeightC > 4)) {
    749 				if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
    750 					*VRatioPrefetchC =
    751 							dml_max(
    752 									*VRatioPrefetchC,
    753 									(double) MaxNumSwathC
    754 											* SwathHeightC
    755 											/ (LinesToRequestPrefetchPixelData
    756 													- (VInitPreFillC
    757 															- 3.0)
    758 															/ 2.0));
    759 					*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
    760 				} else {
    761 					MyError = true;
    762 					*VRatioPrefetchC = 0;
    763 				}
    764 			}
    765 
    766 			*RequiredPrefetchPixDataBW =
    767 					DPPPerPlane
    768 							* ((double) PrefetchSourceLinesY
    769 									/ LinesToRequestPrefetchPixelData
    770 									* dml_ceil(
    771 											BytePerPixelDETY,
    772 											1)
    773 									+ (double) PrefetchSourceLinesC
    774 											/ LinesToRequestPrefetchPixelData
    775 											* dml_ceil(
    776 													BytePerPixelDETC,
    777 													2)
    778 											/ 2)
    779 							* SwathWidthY / LineTime;
    780 		} else {
    781 			MyError = true;
    782 			*VRatioPrefetchY = 0;
    783 			*VRatioPrefetchC = 0;
    784 			*RequiredPrefetchPixDataBW = 0;
    785 		}
    786 
    787 	} else {
    788 		MyError = true;
    789 	}
    790 
    791 	if (MyError) {
    792 		*PrefetchBandwidth = 0;
    793 		TimeForFetchingMetaPTE = 0;
    794 		TimeForFetchingRowInVBlank = 0;
    795 		*DestinationLinesToRequestVMInVBlank = 0;
    796 		*DestinationLinesToRequestRowInVBlank = 0;
    797 		*DestinationLinesForPrefetch = 0;
    798 		LinesToRequestPrefetchPixelData = 0;
    799 		*VRatioPrefetchY = 0;
    800 		*VRatioPrefetchC = 0;
    801 		*RequiredPrefetchPixDataBW = 0;
    802 	}
    803 
    804 	return MyError;
    805 }
    806 
    807 static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
    808 {
    809 	return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
    810 }
    811 
    812 static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
    813 {
    814 	return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
    815 }
    816 
    817 static double CalculatePrefetchSourceLines(
    818 		struct display_mode_lib *mode_lib,
    819 		double VRatio,
    820 		double vtaps,
    821 		bool Interlace,
    822 		bool ProgressiveToInterlaceUnitInOPP,
    823 		unsigned int SwathHeight,
    824 		unsigned int ViewportYStart,
    825 		double *VInitPreFill,
    826 		unsigned int *MaxNumSwath)
    827 {
    828 	unsigned int MaxPartialSwath;
    829 
    830 	if (ProgressiveToInterlaceUnitInOPP)
    831 		*VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
    832 	else
    833 		*VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
    834 
    835 	if (!mode_lib->vba.IgnoreViewportPositioning) {
    836 
    837 		*MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
    838 
    839 		if (*VInitPreFill > 1.0)
    840 			MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
    841 		else
    842 			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
    843 					% SwathHeight;
    844 		MaxPartialSwath = dml_max(1U, MaxPartialSwath);
    845 
    846 	} else {
    847 
    848 		if (ViewportYStart != 0)
    849 			dml_print(
    850 					"WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
    851 
    852 		*MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
    853 
    854 		if (*VInitPreFill > 1.0)
    855 			MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
    856 		else
    857 			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
    858 					% SwathHeight;
    859 	}
    860 
    861 	return *MaxNumSwath * SwathHeight + MaxPartialSwath;
    862 }
    863 
    864 static unsigned int CalculateVMAndRowBytes(
    865 		struct display_mode_lib *mode_lib,
    866 		bool DCCEnable,
    867 		unsigned int BlockHeight256Bytes,
    868 		unsigned int BlockWidth256Bytes,
    869 		enum source_format_class SourcePixelFormat,
    870 		unsigned int SurfaceTiling,
    871 		unsigned int BytePerPixel,
    872 		enum scan_direction_class ScanDirection,
    873 		unsigned int ViewportWidth,
    874 		unsigned int ViewportHeight,
    875 		unsigned int SwathWidth,
    876 		bool GPUVMEnable,
    877 		unsigned int VMMPageSize,
    878 		unsigned int PTEBufferSizeInRequestsLuma,
    879 		unsigned int PDEProcessingBufIn64KBReqs,
    880 		unsigned int Pitch,
    881 		unsigned int DCCMetaPitch,
    882 		unsigned int *MacroTileWidth,
    883 		unsigned int *MetaRowByte,
    884 		unsigned int *PixelPTEBytesPerRow,
    885 		bool *PTEBufferSizeNotExceeded,
    886 		unsigned int *dpte_row_height,
    887 		unsigned int *meta_row_height)
    888 {
    889 	unsigned int MetaRequestHeight;
    890 	unsigned int MetaRequestWidth;
    891 	unsigned int MetaSurfWidth;
    892 	unsigned int MetaSurfHeight;
    893 	unsigned int MPDEBytesFrame;
    894 	unsigned int MetaPTEBytesFrame;
    895 	unsigned int DCCMetaSurfaceBytes;
    896 
    897 	unsigned int MacroTileSizeBytes;
    898 	unsigned int MacroTileHeight;
    899 	unsigned int DPDE0BytesFrame;
    900 	unsigned int ExtraDPDEBytesFrame;
    901 	unsigned int PDEAndMetaPTEBytesFrame;
    902 
    903 	if (DCCEnable == true) {
    904 		MetaRequestHeight = 8 * BlockHeight256Bytes;
    905 		MetaRequestWidth = 8 * BlockWidth256Bytes;
    906 		if (ScanDirection == dm_horz) {
    907 			*meta_row_height = MetaRequestHeight;
    908 			MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
    909 					+ MetaRequestWidth;
    910 			*MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
    911 		} else {
    912 			*meta_row_height = MetaRequestWidth;
    913 			MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
    914 					+ MetaRequestHeight;
    915 			*MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
    916 		}
    917 		if (ScanDirection == dm_horz) {
    918 			DCCMetaSurfaceBytes = DCCMetaPitch
    919 					* (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
    920 							+ 64 * BlockHeight256Bytes) * BytePerPixel
    921 					/ 256;
    922 		} else {
    923 			DCCMetaSurfaceBytes = DCCMetaPitch
    924 					* (dml_ceil(
    925 							(double) ViewportHeight - 1,
    926 							64 * BlockHeight256Bytes)
    927 							+ 64 * BlockHeight256Bytes) * BytePerPixel
    928 					/ 256;
    929 		}
    930 		if (GPUVMEnable == true) {
    931 			MetaPTEBytesFrame = (dml_ceil(
    932 					(double) (DCCMetaSurfaceBytes - VMMPageSize)
    933 							/ (8 * VMMPageSize),
    934 					1) + 1) * 64;
    935 			MPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 1);
    936 		} else {
    937 			MetaPTEBytesFrame = 0;
    938 			MPDEBytesFrame = 0;
    939 		}
    940 	} else {
    941 		MetaPTEBytesFrame = 0;
    942 		MPDEBytesFrame = 0;
    943 		*MetaRowByte = 0;
    944 	}
    945 
    946 	if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) {
    947 		MacroTileSizeBytes = 256;
    948 		MacroTileHeight = BlockHeight256Bytes;
    949 	} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
    950 			|| SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
    951 		MacroTileSizeBytes = 4096;
    952 		MacroTileHeight = 4 * BlockHeight256Bytes;
    953 	} else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
    954 			|| SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
    955 			|| SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
    956 			|| SurfaceTiling == dm_sw_64kb_r_x) {
    957 		MacroTileSizeBytes = 65536;
    958 		MacroTileHeight = 16 * BlockHeight256Bytes;
    959 	} else {
    960 		MacroTileSizeBytes = 262144;
    961 		MacroTileHeight = 32 * BlockHeight256Bytes;
    962 	}
    963 	*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
    964 
    965 	if (GPUVMEnable == true && mode_lib->vba.GPUVMMaxPageTableLevels > 1) {
    966 		if (ScanDirection == dm_horz) {
    967 			DPDE0BytesFrame =
    968 					64
    969 							* (dml_ceil(
    970 									((Pitch
    971 											* (dml_ceil(
    972 													ViewportHeight
    973 															- 1,
    974 													MacroTileHeight)
    975 													+ MacroTileHeight)
    976 											* BytePerPixel)
    977 											- MacroTileSizeBytes)
    978 											/ (8
    979 													* 2097152),
    980 									1) + 1);
    981 		} else {
    982 			DPDE0BytesFrame =
    983 					64
    984 							* (dml_ceil(
    985 									((Pitch
    986 											* (dml_ceil(
    987 													(double) SwathWidth
    988 															- 1,
    989 													MacroTileHeight)
    990 													+ MacroTileHeight)
    991 											* BytePerPixel)
    992 											- MacroTileSizeBytes)
    993 											/ (8
    994 													* 2097152),
    995 									1) + 1);
    996 		}
    997 		ExtraDPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 2);
    998 	} else {
    999 		DPDE0BytesFrame = 0;
   1000 		ExtraDPDEBytesFrame = 0;
   1001 	}
   1002 
   1003 	PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
   1004 			+ ExtraDPDEBytesFrame;
   1005 
   1006 	if (GPUVMEnable == true) {
   1007 		unsigned int PTERequestSize;
   1008 		unsigned int PixelPTEReqHeight;
   1009 		unsigned int PixelPTEReqWidth;
   1010 		double FractionOfPTEReturnDrop;
   1011 		unsigned int EffectivePDEProcessingBufIn64KBReqs;
   1012 
   1013 		if (SurfaceTiling == dm_sw_linear) {
   1014 			PixelPTEReqHeight = 1;
   1015 			PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
   1016 			PTERequestSize = 64;
   1017 			FractionOfPTEReturnDrop = 0;
   1018 		} else if (MacroTileSizeBytes == 4096) {
   1019 			PixelPTEReqHeight = MacroTileHeight;
   1020 			PixelPTEReqWidth = 8 * *MacroTileWidth;
   1021 			PTERequestSize = 64;
   1022 			if (ScanDirection == dm_horz)
   1023 				FractionOfPTEReturnDrop = 0;
   1024 			else
   1025 				FractionOfPTEReturnDrop = 7 / 8;
   1026 		} else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
   1027 			PixelPTEReqHeight = 16 * BlockHeight256Bytes;
   1028 			PixelPTEReqWidth = 16 * BlockWidth256Bytes;
   1029 			PTERequestSize = 128;
   1030 			FractionOfPTEReturnDrop = 0;
   1031 		} else {
   1032 			PixelPTEReqHeight = MacroTileHeight;
   1033 			PixelPTEReqWidth = 8 * *MacroTileWidth;
   1034 			PTERequestSize = 64;
   1035 			FractionOfPTEReturnDrop = 0;
   1036 		}
   1037 
   1038 		if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
   1039 			EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
   1040 		else
   1041 			EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
   1042 
   1043 		if (SurfaceTiling == dm_sw_linear) {
   1044 			*dpte_row_height =
   1045 					dml_min(
   1046 							128,
   1047 							1
   1048 									<< (unsigned int) dml_floor(
   1049 											dml_log2(
   1050 													dml_min(
   1051 															(double) PTEBufferSizeInRequestsLuma
   1052 																	* PixelPTEReqWidth,
   1053 															EffectivePDEProcessingBufIn64KBReqs
   1054 																	* 65536.0
   1055 																	/ BytePerPixel)
   1056 															/ Pitch),
   1057 											1));
   1058 			*PixelPTEBytesPerRow = PTERequestSize
   1059 					* (dml_ceil(
   1060 							(double) (Pitch * *dpte_row_height - 1)
   1061 									/ PixelPTEReqWidth,
   1062 							1) + 1);
   1063 		} else if (ScanDirection == dm_horz) {
   1064 			*dpte_row_height = PixelPTEReqHeight;
   1065 			*PixelPTEBytesPerRow = PTERequestSize
   1066 					* (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
   1067 							+ 1);
   1068 		} else {
   1069 			*dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
   1070 			*PixelPTEBytesPerRow = PTERequestSize
   1071 					* (dml_ceil(
   1072 							((double) SwathWidth - 1)
   1073 									/ PixelPTEReqHeight,
   1074 							1) + 1);
   1075 		}
   1076 		if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
   1077 				<= 64 * PTEBufferSizeInRequestsLuma) {
   1078 			*PTEBufferSizeNotExceeded = true;
   1079 		} else {
   1080 			*PTEBufferSizeNotExceeded = false;
   1081 		}
   1082 	} else {
   1083 		*PixelPTEBytesPerRow = 0;
   1084 		*PTEBufferSizeNotExceeded = true;
   1085 	}
   1086 
   1087 	return PDEAndMetaPTEBytesFrame;
   1088 }
   1089 
   1090 static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
   1091 		struct display_mode_lib *mode_lib)
   1092 {
   1093 	unsigned int j, k;
   1094 
   1095 	mode_lib->vba.WritebackDISPCLK = 0.0;
   1096 	mode_lib->vba.DISPCLKWithRamping = 0;
   1097 	mode_lib->vba.DISPCLKWithoutRamping = 0;
   1098 	mode_lib->vba.GlobalDPPCLK = 0.0;
   1099 
   1100 	// dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
   1101 	//
   1102 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1103 		if (mode_lib->vba.WritebackEnable[k]) {
   1104 			mode_lib->vba.WritebackDISPCLK =
   1105 					dml_max(
   1106 							mode_lib->vba.WritebackDISPCLK,
   1107 							CalculateWriteBackDISPCLK(
   1108 									mode_lib->vba.WritebackPixelFormat[k],
   1109 									mode_lib->vba.PixelClock[k],
   1110 									mode_lib->vba.WritebackHRatio[k],
   1111 									mode_lib->vba.WritebackVRatio[k],
   1112 									mode_lib->vba.WritebackLumaHTaps[k],
   1113 									mode_lib->vba.WritebackLumaVTaps[k],
   1114 									mode_lib->vba.WritebackChromaHTaps[k],
   1115 									mode_lib->vba.WritebackChromaVTaps[k],
   1116 									mode_lib->vba.WritebackDestinationWidth[k],
   1117 									mode_lib->vba.HTotal[k],
   1118 									mode_lib->vba.WritebackChromaLineBufferWidth));
   1119 		}
   1120 	}
   1121 
   1122 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1123 		if (mode_lib->vba.HRatio[k] > 1) {
   1124 			mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
   1125 					mode_lib->vba.MaxDCHUBToPSCLThroughput,
   1126 					mode_lib->vba.MaxPSCLToLBThroughput
   1127 							* mode_lib->vba.HRatio[k]
   1128 							/ dml_ceil(
   1129 									mode_lib->vba.htaps[k]
   1130 											/ 6.0,
   1131 									1));
   1132 		} else {
   1133 			mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
   1134 					mode_lib->vba.MaxDCHUBToPSCLThroughput,
   1135 					mode_lib->vba.MaxPSCLToLBThroughput);
   1136 		}
   1137 
   1138 		mode_lib->vba.DPPCLKUsingSingleDPPLuma =
   1139 				mode_lib->vba.PixelClock[k]
   1140 						* dml_max(
   1141 								mode_lib->vba.vtaps[k] / 6.0
   1142 										* dml_min(
   1143 												1.0,
   1144 												mode_lib->vba.HRatio[k]),
   1145 								dml_max(
   1146 										mode_lib->vba.HRatio[k]
   1147 												* mode_lib->vba.VRatio[k]
   1148 												/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
   1149 										1.0));
   1150 
   1151 		if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
   1152 				&& mode_lib->vba.DPPCLKUsingSingleDPPLuma
   1153 						< 2 * mode_lib->vba.PixelClock[k]) {
   1154 			mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
   1155 		}
   1156 
   1157 		if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
   1158 				&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
   1159 			mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
   1160 			mode_lib->vba.DPPCLKUsingSingleDPP[k] =
   1161 					mode_lib->vba.DPPCLKUsingSingleDPPLuma;
   1162 		} else {
   1163 			if (mode_lib->vba.HRatio[k] > 1) {
   1164 				mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
   1165 						dml_min(
   1166 								mode_lib->vba.MaxDCHUBToPSCLThroughput,
   1167 								mode_lib->vba.MaxPSCLToLBThroughput
   1168 										* mode_lib->vba.HRatio[k]
   1169 										/ 2
   1170 										/ dml_ceil(
   1171 												mode_lib->vba.HTAPsChroma[k]
   1172 														/ 6.0,
   1173 												1.0));
   1174 			} else {
   1175 				mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
   1176 						mode_lib->vba.MaxDCHUBToPSCLThroughput,
   1177 						mode_lib->vba.MaxPSCLToLBThroughput);
   1178 			}
   1179 			mode_lib->vba.DPPCLKUsingSingleDPPChroma =
   1180 					mode_lib->vba.PixelClock[k]
   1181 							* dml_max(
   1182 									mode_lib->vba.VTAPsChroma[k]
   1183 											/ 6.0
   1184 											* dml_min(
   1185 													1.0,
   1186 													mode_lib->vba.HRatio[k]
   1187 															/ 2),
   1188 									dml_max(
   1189 											mode_lib->vba.HRatio[k]
   1190 													* mode_lib->vba.VRatio[k]
   1191 													/ 4
   1192 													/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
   1193 											1.0));
   1194 
   1195 			if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
   1196 					&& mode_lib->vba.DPPCLKUsingSingleDPPChroma
   1197 							< 2 * mode_lib->vba.PixelClock[k]) {
   1198 				mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
   1199 						* mode_lib->vba.PixelClock[k];
   1200 			}
   1201 
   1202 			mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
   1203 					mode_lib->vba.DPPCLKUsingSingleDPPLuma,
   1204 					mode_lib->vba.DPPCLKUsingSingleDPPChroma);
   1205 		}
   1206 	}
   1207 
   1208 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1209 		if (mode_lib->vba.BlendingAndTiming[k] != k)
   1210 			continue;
   1211 		if (mode_lib->vba.ODMCombineEnabled[k]) {
   1212 			mode_lib->vba.DISPCLKWithRamping =
   1213 					dml_max(
   1214 							mode_lib->vba.DISPCLKWithRamping,
   1215 							mode_lib->vba.PixelClock[k] / 2
   1216 									* (1
   1217 											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
   1218 													/ 100)
   1219 									* (1
   1220 											+ mode_lib->vba.DISPCLKRampingMargin
   1221 													/ 100));
   1222 			mode_lib->vba.DISPCLKWithoutRamping =
   1223 					dml_max(
   1224 							mode_lib->vba.DISPCLKWithoutRamping,
   1225 							mode_lib->vba.PixelClock[k] / 2
   1226 									* (1
   1227 											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
   1228 													/ 100));
   1229 		} else if (!mode_lib->vba.ODMCombineEnabled[k]) {
   1230 			mode_lib->vba.DISPCLKWithRamping =
   1231 					dml_max(
   1232 							mode_lib->vba.DISPCLKWithRamping,
   1233 							mode_lib->vba.PixelClock[k]
   1234 									* (1
   1235 											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
   1236 													/ 100)
   1237 									* (1
   1238 											+ mode_lib->vba.DISPCLKRampingMargin
   1239 													/ 100));
   1240 			mode_lib->vba.DISPCLKWithoutRamping =
   1241 					dml_max(
   1242 							mode_lib->vba.DISPCLKWithoutRamping,
   1243 							mode_lib->vba.PixelClock[k]
   1244 									* (1
   1245 											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
   1246 													/ 100));
   1247 		}
   1248 	}
   1249 
   1250 	mode_lib->vba.DISPCLKWithRamping = dml_max(
   1251 			mode_lib->vba.DISPCLKWithRamping,
   1252 			mode_lib->vba.WritebackDISPCLK);
   1253 	mode_lib->vba.DISPCLKWithoutRamping = dml_max(
   1254 			mode_lib->vba.DISPCLKWithoutRamping,
   1255 			mode_lib->vba.WritebackDISPCLK);
   1256 
   1257 	ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
   1258 	mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
   1259 			mode_lib->vba.DISPCLKWithRamping,
   1260 			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
   1261 	mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
   1262 			mode_lib->vba.DISPCLKWithoutRamping,
   1263 			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
   1264 	mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
   1265 			mode_lib->vba.soc.clock_limits[mode_lib->vba.soc.num_states].dispclk_mhz,
   1266 			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
   1267 	if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
   1268 			> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
   1269 		mode_lib->vba.DISPCLK_calculated =
   1270 				mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
   1271 	} else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
   1272 			> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
   1273 		mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
   1274 	} else {
   1275 		mode_lib->vba.DISPCLK_calculated =
   1276 				mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
   1277 	}
   1278 	DTRACE("   dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
   1279 
   1280 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1281 		if (mode_lib->vba.DPPPerPlane[k] == 0) {
   1282 			mode_lib->vba.DPPCLK_calculated[k] = 0;
   1283 		} else {
   1284 			mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
   1285 					/ mode_lib->vba.DPPPerPlane[k]
   1286 					* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
   1287 		}
   1288 		mode_lib->vba.GlobalDPPCLK = dml_max(
   1289 				mode_lib->vba.GlobalDPPCLK,
   1290 				mode_lib->vba.DPPCLK_calculated[k]);
   1291 	}
   1292 	mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
   1293 			mode_lib->vba.GlobalDPPCLK,
   1294 			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
   1295 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1296 		mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
   1297 				* dml_ceil(
   1298 						mode_lib->vba.DPPCLK_calculated[k] * 255
   1299 								/ mode_lib->vba.GlobalDPPCLK,
   1300 						1);
   1301 		DTRACE("   dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
   1302 	}
   1303 
   1304 	// Urgent Watermark
   1305 	mode_lib->vba.DCCEnabledAnyPlane = false;
   1306 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
   1307 		if (mode_lib->vba.DCCEnable[k])
   1308 			mode_lib->vba.DCCEnabledAnyPlane = true;
   1309 
   1310 	mode_lib->vba.ReturnBandwidthToDCN = dml_min(
   1311 			mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
   1312 			mode_lib->vba.FabricAndDRAMBandwidth * 1000)
   1313 			* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
   1314 
   1315 	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
   1316 	mode_lib->vba.ReturnBW = adjust_ReturnBW(
   1317 			mode_lib,
   1318 			mode_lib->vba.ReturnBW,
   1319 			mode_lib->vba.DCCEnabledAnyPlane,
   1320 			mode_lib->vba.ReturnBandwidthToDCN);
   1321 
   1322 	// Let's do this calculation again??
   1323 	mode_lib->vba.ReturnBandwidthToDCN = dml_min(
   1324 			mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
   1325 			mode_lib->vba.FabricAndDRAMBandwidth * 1000);
   1326 	mode_lib->vba.ReturnBW = adjust_ReturnBW(
   1327 			mode_lib,
   1328 			mode_lib->vba.ReturnBW,
   1329 			mode_lib->vba.DCCEnabledAnyPlane,
   1330 			mode_lib->vba.ReturnBandwidthToDCN);
   1331 
   1332 	DTRACE("   dcfclk_mhz         = %f", mode_lib->vba.DCFCLK);
   1333 	DTRACE("   return_bw_to_dcn   = %f", mode_lib->vba.ReturnBandwidthToDCN);
   1334 	DTRACE("   return_bus_bw      = %f", mode_lib->vba.ReturnBW);
   1335 
   1336 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1337 		bool MainPlaneDoesODMCombine = false;
   1338 
   1339 		if (mode_lib->vba.SourceScan[k] == dm_horz)
   1340 			mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
   1341 		else
   1342 			mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
   1343 
   1344 		if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
   1345 			MainPlaneDoesODMCombine = true;
   1346 		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
   1347 			if (mode_lib->vba.BlendingAndTiming[k] == j
   1348 					&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
   1349 				MainPlaneDoesODMCombine = true;
   1350 
   1351 		if (MainPlaneDoesODMCombine == true)
   1352 			mode_lib->vba.SwathWidthY[k] = dml_min(
   1353 					(double) mode_lib->vba.SwathWidthSingleDPPY[k],
   1354 					dml_round(
   1355 							mode_lib->vba.HActive[k] / 2.0
   1356 									* mode_lib->vba.HRatio[k]));
   1357 		else {
   1358 			if (mode_lib->vba.DPPPerPlane[k] == 0) {
   1359 				mode_lib->vba.SwathWidthY[k] = 0;
   1360 			} else {
   1361 				mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
   1362 						/ mode_lib->vba.DPPPerPlane[k];
   1363 			}
   1364 		}
   1365 	}
   1366 
   1367 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1368 		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
   1369 			mode_lib->vba.BytePerPixelDETY[k] = 8;
   1370 			mode_lib->vba.BytePerPixelDETC[k] = 0;
   1371 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
   1372 			mode_lib->vba.BytePerPixelDETY[k] = 4;
   1373 			mode_lib->vba.BytePerPixelDETC[k] = 0;
   1374 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
   1375 			mode_lib->vba.BytePerPixelDETY[k] = 2;
   1376 			mode_lib->vba.BytePerPixelDETC[k] = 0;
   1377 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
   1378 			mode_lib->vba.BytePerPixelDETY[k] = 1;
   1379 			mode_lib->vba.BytePerPixelDETC[k] = 0;
   1380 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
   1381 			mode_lib->vba.BytePerPixelDETY[k] = 1;
   1382 			mode_lib->vba.BytePerPixelDETC[k] = 2;
   1383 		} else { // dm_420_10
   1384 			mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
   1385 			mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
   1386 		}
   1387 	}
   1388 
   1389 	mode_lib->vba.TotalDataReadBandwidth = 0.0;
   1390 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1391 		mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
   1392 				* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
   1393 				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
   1394 				* mode_lib->vba.VRatio[k];
   1395 		mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
   1396 				/ 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
   1397 				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
   1398 				* mode_lib->vba.VRatio[k] / 2;
   1399 		DTRACE(
   1400 				"   read_bw[%i] = %fBps",
   1401 				k,
   1402 				mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1403 						+ mode_lib->vba.ReadBandwidthPlaneChroma[k]);
   1404 		mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1405 				+ mode_lib->vba.ReadBandwidthPlaneChroma[k];
   1406 	}
   1407 
   1408 	mode_lib->vba.TotalDCCActiveDPP = 0;
   1409 	mode_lib->vba.TotalActiveDPP = 0;
   1410 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1411 		mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
   1412 				+ mode_lib->vba.DPPPerPlane[k];
   1413 		if (mode_lib->vba.DCCEnable[k])
   1414 			mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
   1415 					+ mode_lib->vba.DPPPerPlane[k];
   1416 	}
   1417 
   1418 	mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
   1419 			(mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
   1420 					+ mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly
   1421 							* mode_lib->vba.NumberOfChannels
   1422 							/ mode_lib->vba.ReturnBW;
   1423 
   1424 	mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
   1425 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1426 		double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma;
   1427 
   1428 		if (mode_lib->vba.VRatio[k] <= 1.0)
   1429 			mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
   1430 					(double) mode_lib->vba.SwathWidthY[k]
   1431 							* mode_lib->vba.DPPPerPlane[k]
   1432 							/ mode_lib->vba.HRatio[k]
   1433 							/ mode_lib->vba.PixelClock[k];
   1434 		else
   1435 			mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
   1436 					(double) mode_lib->vba.SwathWidthY[k]
   1437 							/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
   1438 							/ mode_lib->vba.DPPCLK[k];
   1439 
   1440 		DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k]
   1441 				* mode_lib->vba.SwathHeightY[k]
   1442 				* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
   1443 				/ (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1444 						/ mode_lib->vba.TotalDataReadBandwidth);
   1445 		mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(
   1446 				mode_lib->vba.LastPixelOfLineExtraWatermark,
   1447 				DataFabricLineDeliveryTimeLuma
   1448 						- mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]);
   1449 
   1450 		if (mode_lib->vba.BytePerPixelDETC[k] == 0)
   1451 			mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0;
   1452 		else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0)
   1453 			mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
   1454 					mode_lib->vba.SwathWidthY[k] / 2.0
   1455 							* mode_lib->vba.DPPPerPlane[k]
   1456 							/ (mode_lib->vba.HRatio[k] / 2.0)
   1457 							/ mode_lib->vba.PixelClock[k];
   1458 		else
   1459 			mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
   1460 					mode_lib->vba.SwathWidthY[k] / 2.0
   1461 							/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
   1462 							/ mode_lib->vba.DPPCLK[k];
   1463 
   1464 		DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0
   1465 				* mode_lib->vba.SwathHeightC[k]
   1466 				* dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
   1467 				/ (mode_lib->vba.ReturnBW
   1468 						* mode_lib->vba.ReadBandwidthPlaneChroma[k]
   1469 						/ mode_lib->vba.TotalDataReadBandwidth);
   1470 		mode_lib->vba.LastPixelOfLineExtraWatermark =
   1471 				dml_max(
   1472 						mode_lib->vba.LastPixelOfLineExtraWatermark,
   1473 						DataFabricLineDeliveryTimeChroma
   1474 								- mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
   1475 	}
   1476 
   1477 	mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
   1478 			+ (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
   1479 					+ mode_lib->vba.TotalDCCActiveDPP
   1480 							* mode_lib->vba.MetaChunkSize) * 1024.0
   1481 					/ mode_lib->vba.ReturnBW;
   1482 
   1483 	if (mode_lib->vba.GPUVMEnable)
   1484 		mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
   1485 				* mode_lib->vba.PTEGroupSize / mode_lib->vba.ReturnBW;
   1486 
   1487 	mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatencyPixelDataOnly
   1488 			+ mode_lib->vba.LastPixelOfLineExtraWatermark
   1489 			+ mode_lib->vba.UrgentExtraLatency;
   1490 
   1491 	DTRACE("   urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
   1492 	DTRACE("   wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
   1493 
   1494 	mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
   1495 
   1496 	mode_lib->vba.TotalActiveWriteback = 0;
   1497 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1498 		if (mode_lib->vba.WritebackEnable[k])
   1499 			mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + mode_lib->vba.ActiveWritebacksPerPlane[k];
   1500 	}
   1501 
   1502 	if (mode_lib->vba.TotalActiveWriteback <= 1)
   1503 		mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
   1504 	else
   1505 		mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
   1506 				+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
   1507 						/ mode_lib->vba.SOCCLK;
   1508 
   1509 	DTRACE("   wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
   1510 
   1511 	// NB P-State/DRAM Clock Change Watermark
   1512 	mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
   1513 			+ mode_lib->vba.UrgentWatermark;
   1514 
   1515 	DTRACE("   wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
   1516 
   1517 	DTRACE("   calculating wb pstate watermark");
   1518 	DTRACE("      total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
   1519 	DTRACE("      socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
   1520 
   1521 	if (mode_lib->vba.TotalActiveWriteback <= 1)
   1522 		mode_lib->vba.WritebackDRAMClockChangeWatermark =
   1523 				mode_lib->vba.DRAMClockChangeLatency
   1524 						+ mode_lib->vba.WritebackLatency;
   1525 	else
   1526 		mode_lib->vba.WritebackDRAMClockChangeWatermark =
   1527 				mode_lib->vba.DRAMClockChangeLatency
   1528 						+ mode_lib->vba.WritebackLatency
   1529 						+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
   1530 								/ mode_lib->vba.SOCCLK;
   1531 
   1532 	DTRACE("   wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
   1533 
   1534 	// Stutter Efficiency
   1535 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1536 		mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
   1537 				/ mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
   1538 		mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
   1539 				mode_lib->vba.LinesInDETY[k],
   1540 				mode_lib->vba.SwathHeightY[k]);
   1541 		mode_lib->vba.FullDETBufferingTimeY[k] =
   1542 				mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
   1543 						* (mode_lib->vba.HTotal[k]
   1544 								/ mode_lib->vba.PixelClock[k])
   1545 						/ mode_lib->vba.VRatio[k];
   1546 		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
   1547 			mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k]
   1548 					/ mode_lib->vba.BytePerPixelDETC[k]
   1549 					/ (mode_lib->vba.SwathWidthY[k] / 2);
   1550 			mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(
   1551 					mode_lib->vba.LinesInDETC[k],
   1552 					mode_lib->vba.SwathHeightC[k]);
   1553 			mode_lib->vba.FullDETBufferingTimeC[k] =
   1554 					mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
   1555 							* (mode_lib->vba.HTotal[k]
   1556 									/ mode_lib->vba.PixelClock[k])
   1557 							/ (mode_lib->vba.VRatio[k] / 2);
   1558 		} else {
   1559 			mode_lib->vba.LinesInDETC[k] = 0;
   1560 			mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
   1561 			mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
   1562 		}
   1563 	}
   1564 
   1565 	mode_lib->vba.MinFullDETBufferingTime = 999999.0;
   1566 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1567 		if (mode_lib->vba.FullDETBufferingTimeY[k]
   1568 				< mode_lib->vba.MinFullDETBufferingTime) {
   1569 			mode_lib->vba.MinFullDETBufferingTime =
   1570 					mode_lib->vba.FullDETBufferingTimeY[k];
   1571 			mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
   1572 					(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
   1573 							/ mode_lib->vba.PixelClock[k];
   1574 		}
   1575 		if (mode_lib->vba.FullDETBufferingTimeC[k]
   1576 				< mode_lib->vba.MinFullDETBufferingTime) {
   1577 			mode_lib->vba.MinFullDETBufferingTime =
   1578 					mode_lib->vba.FullDETBufferingTimeC[k];
   1579 			mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
   1580 					(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
   1581 							/ mode_lib->vba.PixelClock[k];
   1582 		}
   1583 	}
   1584 
   1585 	mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
   1586 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1587 		if (mode_lib->vba.DCCEnable[k]) {
   1588 			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
   1589 					mode_lib->vba.AverageReadBandwidthGBytePerSecond
   1590 							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1591 									/ mode_lib->vba.DCCRate[k]
   1592 									/ 1000
   1593 							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
   1594 									/ mode_lib->vba.DCCRate[k]
   1595 									/ 1000;
   1596 		} else {
   1597 			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
   1598 					mode_lib->vba.AverageReadBandwidthGBytePerSecond
   1599 							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1600 									/ 1000
   1601 							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
   1602 									/ 1000;
   1603 		}
   1604 		if (mode_lib->vba.DCCEnable[k]) {
   1605 			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
   1606 					mode_lib->vba.AverageReadBandwidthGBytePerSecond
   1607 							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1608 									/ 1000 / 256
   1609 							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
   1610 									/ 1000 / 256;
   1611 		}
   1612 		if (mode_lib->vba.GPUVMEnable) {
   1613 			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
   1614 					mode_lib->vba.AverageReadBandwidthGBytePerSecond
   1615 							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
   1616 									/ 1000 / 512
   1617 							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
   1618 									/ 1000 / 512;
   1619 		}
   1620 	}
   1621 
   1622 	mode_lib->vba.PartOfBurstThatFitsInROB =
   1623 			dml_min(
   1624 					mode_lib->vba.MinFullDETBufferingTime
   1625 							* mode_lib->vba.TotalDataReadBandwidth,
   1626 					mode_lib->vba.ROBBufferSizeInKByte * 1024
   1627 							* mode_lib->vba.TotalDataReadBandwidth
   1628 							/ (mode_lib->vba.AverageReadBandwidthGBytePerSecond
   1629 									* 1000));
   1630 	mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
   1631 			* (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
   1632 			/ mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
   1633 			+ (mode_lib->vba.MinFullDETBufferingTime
   1634 					* mode_lib->vba.TotalDataReadBandwidth
   1635 					- mode_lib->vba.PartOfBurstThatFitsInROB)
   1636 					/ (mode_lib->vba.DCFCLK * 64);
   1637 	if (mode_lib->vba.TotalActiveWriteback == 0) {
   1638 		mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
   1639 				- (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
   1640 						/ mode_lib->vba.MinFullDETBufferingTime) * 100;
   1641 	} else {
   1642 		mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
   1643 	}
   1644 
   1645 	mode_lib->vba.SmallestVBlank = 999999;
   1646 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1647 		if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
   1648 			mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
   1649 					- mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
   1650 					/ mode_lib->vba.PixelClock[k];
   1651 		} else {
   1652 			mode_lib->vba.VBlankTime = 0;
   1653 		}
   1654 		mode_lib->vba.SmallestVBlank = dml_min(
   1655 				mode_lib->vba.SmallestVBlank,
   1656 				mode_lib->vba.VBlankTime);
   1657 	}
   1658 
   1659 	mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
   1660 			* (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
   1661 					- mode_lib->vba.SmallestVBlank)
   1662 			+ mode_lib->vba.SmallestVBlank)
   1663 			/ mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
   1664 
   1665 	// dml_ml->vba.DCFCLK Deep Sleep
   1666 	mode_lib->vba.DCFCLKDeepSleep = 8.0;
   1667 
   1668 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
   1669 		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
   1670 			mode_lib->vba.DCFCLKDeepSleepPerPlane[k] =
   1671 					dml_max(
   1672 							1.1 * mode_lib->vba.SwathWidthY[k]
   1673 									* dml_ceil(
   1674 											mode_lib->vba.BytePerPixelDETY[k],
   1675 											1) / 32
   1676 									/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
   1677 							1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
   1678 									* dml_ceil(
   1679 											mode_lib->vba.BytePerPixelDETC[k],
   1680 											2) / 32
   1681 									/ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
   1682 		} else
   1683 			mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = 1.1 * mode_lib->vba.SwathWidthY[k]
   1684 					* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
   1685 					/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
   1686 		mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(
   1687 				mode_lib->vba.DCFCLKDeepSleepPerPlane[k],
   1688 				mode_lib->vba.PixelClock[k] / 16.0);
   1689 		mode_lib->vba.DCFCLKDeepSleep = dml_max(
   1690 				mode_lib->vba.DCFCLKDeepSleep,
   1691 				mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
   1692 
   1693 		DTRACE(
   1694 				"   dcfclk_deepsleep_per_plane[%i] = %fMHz",
   1695 				k,
   1696 				mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
   1697 	}
   1698 
   1699 	DTRACE("   dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFCLKDeepSleep);
   1700 
   1701 	// Stutter Watermark
   1702 	mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
   1703 			+ mode_lib->vba.LastPixelOfLineExtraWatermark
   1704 			+ mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFCLKDeepSleep;
   1705 	mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
   1706 			+ mode_lib->vba.LastPixelOfLineExtraWatermark
   1707 			+ mode_lib->vba.UrgentExtraLatency;
   1708 
   1709 	DTRACE("   wm_cstate_exit       = %fus", mode_lib->vba.StutterExitWatermark);
   1710 	DTRACE("   wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
   1711 
   1712 	// Urgent Latency Supported
   1713 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1714 		mode_lib->vba.EffectiveDETPlusLBLinesLuma =
   1715 				dml_floor(
   1716 						mode_lib->vba.LinesInDETY[k]
   1717 								+ dml_min(
   1718 										mode_lib->vba.LinesInDETY[k]
   1719 												* mode_lib->vba.DPPCLK[k]
   1720 												* mode_lib->vba.BytePerPixelDETY[k]
   1721 												* mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
   1722 												/ (mode_lib->vba.ReturnBW
   1723 														/ mode_lib->vba.DPPPerPlane[k]),
   1724 										(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
   1725 						mode_lib->vba.SwathHeightY[k]);
   1726 
   1727 		mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
   1728 				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
   1729 				/ mode_lib->vba.VRatio[k]
   1730 				- mode_lib->vba.EffectiveDETPlusLBLinesLuma
   1731 						* mode_lib->vba.SwathWidthY[k]
   1732 						* mode_lib->vba.BytePerPixelDETY[k]
   1733 						/ (mode_lib->vba.ReturnBW
   1734 								/ mode_lib->vba.DPPPerPlane[k]);
   1735 
   1736 		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
   1737 			mode_lib->vba.EffectiveDETPlusLBLinesChroma =
   1738 					dml_floor(
   1739 							mode_lib->vba.LinesInDETC[k]
   1740 									+ dml_min(
   1741 											mode_lib->vba.LinesInDETC[k]
   1742 													* mode_lib->vba.DPPCLK[k]
   1743 													* mode_lib->vba.BytePerPixelDETC[k]
   1744 													* mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
   1745 													/ (mode_lib->vba.ReturnBW
   1746 															/ mode_lib->vba.DPPPerPlane[k]),
   1747 											(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
   1748 							mode_lib->vba.SwathHeightC[k]);
   1749 			mode_lib->vba.UrgentLatencySupportUsChroma =
   1750 					mode_lib->vba.EffectiveDETPlusLBLinesChroma
   1751 							* (mode_lib->vba.HTotal[k]
   1752 									/ mode_lib->vba.PixelClock[k])
   1753 							/ (mode_lib->vba.VRatio[k] / 2)
   1754 							- mode_lib->vba.EffectiveDETPlusLBLinesChroma
   1755 									* (mode_lib->vba.SwathWidthY[k]
   1756 											/ 2)
   1757 									* mode_lib->vba.BytePerPixelDETC[k]
   1758 									/ (mode_lib->vba.ReturnBW
   1759 											/ mode_lib->vba.DPPPerPlane[k]);
   1760 			mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
   1761 					mode_lib->vba.UrgentLatencySupportUsLuma,
   1762 					mode_lib->vba.UrgentLatencySupportUsChroma);
   1763 		} else {
   1764 			mode_lib->vba.UrgentLatencySupportUs[k] =
   1765 					mode_lib->vba.UrgentLatencySupportUsLuma;
   1766 		}
   1767 	}
   1768 
   1769 	mode_lib->vba.MinUrgentLatencySupportUs = 999999;
   1770 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1771 		mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
   1772 				mode_lib->vba.MinUrgentLatencySupportUs,
   1773 				mode_lib->vba.UrgentLatencySupportUs[k]);
   1774 	}
   1775 
   1776 	// Non-Urgent Latency Tolerance
   1777 	mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
   1778 			- mode_lib->vba.UrgentWatermark;
   1779 
   1780 	// DSCCLK
   1781 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1782 		if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
   1783 			mode_lib->vba.DSCCLK_calculated[k] = 0.0;
   1784 		} else {
   1785 			if (mode_lib->vba.OutputFormat[k] == dm_420
   1786 					|| mode_lib->vba.OutputFormat[k] == dm_n422)
   1787 				mode_lib->vba.DSCFormatFactor = 2;
   1788 			else
   1789 				mode_lib->vba.DSCFormatFactor = 1;
   1790 			if (mode_lib->vba.ODMCombineEnabled[k])
   1791 				mode_lib->vba.DSCCLK_calculated[k] =
   1792 						mode_lib->vba.PixelClockBackEnd[k] / 6
   1793 								/ mode_lib->vba.DSCFormatFactor
   1794 								/ (1
   1795 										- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
   1796 												/ 100);
   1797 			else
   1798 				mode_lib->vba.DSCCLK_calculated[k] =
   1799 						mode_lib->vba.PixelClockBackEnd[k] / 3
   1800 								/ mode_lib->vba.DSCFormatFactor
   1801 								/ (1
   1802 										- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
   1803 												/ 100);
   1804 		}
   1805 	}
   1806 
   1807 	// DSC Delay
   1808 	// TODO
   1809 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1810 		double bpp = mode_lib->vba.OutputBpp[k];
   1811 		unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
   1812 
   1813 		if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
   1814 			if (!mode_lib->vba.ODMCombineEnabled[k]) {
   1815 				mode_lib->vba.DSCDelay[k] =
   1816 						dscceComputeDelay(
   1817 								mode_lib->vba.DSCInputBitPerComponent[k],
   1818 								bpp,
   1819 								dml_ceil(
   1820 										(double) mode_lib->vba.HActive[k]
   1821 												/ mode_lib->vba.NumberOfDSCSlices[k],
   1822 										1),
   1823 								slices,
   1824 								mode_lib->vba.OutputFormat[k])
   1825 								+ dscComputeDelay(
   1826 										mode_lib->vba.OutputFormat[k]);
   1827 			} else {
   1828 				mode_lib->vba.DSCDelay[k] =
   1829 						2
   1830 								* (dscceComputeDelay(
   1831 										mode_lib->vba.DSCInputBitPerComponent[k],
   1832 										bpp,
   1833 										dml_ceil(
   1834 												(double) mode_lib->vba.HActive[k]
   1835 														/ mode_lib->vba.NumberOfDSCSlices[k],
   1836 												1),
   1837 										slices / 2.0,
   1838 										mode_lib->vba.OutputFormat[k])
   1839 										+ dscComputeDelay(
   1840 												mode_lib->vba.OutputFormat[k]));
   1841 			}
   1842 			mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k]
   1843 					* mode_lib->vba.PixelClock[k]
   1844 					/ mode_lib->vba.PixelClockBackEnd[k];
   1845 		} else {
   1846 			mode_lib->vba.DSCDelay[k] = 0;
   1847 		}
   1848 	}
   1849 
   1850 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
   1851 		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes
   1852 			if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
   1853 					&& mode_lib->vba.DSCEnabled[j])
   1854 				mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
   1855 
   1856 	// Prefetch
   1857 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1858 		unsigned int PDEAndMetaPTEBytesFrameY;
   1859 		unsigned int PixelPTEBytesPerRowY;
   1860 		unsigned int MetaRowByteY;
   1861 		unsigned int MetaRowByteC;
   1862 		unsigned int PDEAndMetaPTEBytesFrameC;
   1863 		unsigned int PixelPTEBytesPerRowC;
   1864 
   1865 		Calculate256BBlockSizes(
   1866 				mode_lib->vba.SourcePixelFormat[k],
   1867 				mode_lib->vba.SurfaceTiling[k],
   1868 				dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
   1869 				dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
   1870 				&mode_lib->vba.BlockHeight256BytesY[k],
   1871 				&mode_lib->vba.BlockHeight256BytesC[k],
   1872 				&mode_lib->vba.BlockWidth256BytesY[k],
   1873 				&mode_lib->vba.BlockWidth256BytesC[k]);
   1874 		PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
   1875 				mode_lib,
   1876 				mode_lib->vba.DCCEnable[k],
   1877 				mode_lib->vba.BlockHeight256BytesY[k],
   1878 				mode_lib->vba.BlockWidth256BytesY[k],
   1879 				mode_lib->vba.SourcePixelFormat[k],
   1880 				mode_lib->vba.SurfaceTiling[k],
   1881 				dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
   1882 				mode_lib->vba.SourceScan[k],
   1883 				mode_lib->vba.ViewportWidth[k],
   1884 				mode_lib->vba.ViewportHeight[k],
   1885 				mode_lib->vba.SwathWidthY[k],
   1886 				mode_lib->vba.GPUVMEnable,
   1887 				mode_lib->vba.VMMPageSize,
   1888 				mode_lib->vba.PTEBufferSizeInRequestsLuma,
   1889 				mode_lib->vba.PDEProcessingBufIn64KBReqs,
   1890 				mode_lib->vba.PitchY[k],
   1891 				mode_lib->vba.DCCMetaPitchY[k],
   1892 				&mode_lib->vba.MacroTileWidthY[k],
   1893 				&MetaRowByteY,
   1894 				&PixelPTEBytesPerRowY,
   1895 				&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel][0],
   1896 				&mode_lib->vba.dpte_row_height[k],
   1897 				&mode_lib->vba.meta_row_height[k]);
   1898 		mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
   1899 				mode_lib,
   1900 				mode_lib->vba.VRatio[k],
   1901 				mode_lib->vba.vtaps[k],
   1902 				mode_lib->vba.Interlace[k],
   1903 				mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
   1904 				mode_lib->vba.SwathHeightY[k],
   1905 				mode_lib->vba.ViewportYStartY[k],
   1906 				&mode_lib->vba.VInitPreFillY[k],
   1907 				&mode_lib->vba.MaxNumSwathY[k]);
   1908 
   1909 		if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
   1910 				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
   1911 				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
   1912 				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
   1913 			PDEAndMetaPTEBytesFrameC =
   1914 					CalculateVMAndRowBytes(
   1915 							mode_lib,
   1916 							mode_lib->vba.DCCEnable[k],
   1917 							mode_lib->vba.BlockHeight256BytesC[k],
   1918 							mode_lib->vba.BlockWidth256BytesC[k],
   1919 							mode_lib->vba.SourcePixelFormat[k],
   1920 							mode_lib->vba.SurfaceTiling[k],
   1921 							dml_ceil(
   1922 									mode_lib->vba.BytePerPixelDETC[k],
   1923 									2),
   1924 							mode_lib->vba.SourceScan[k],
   1925 							mode_lib->vba.ViewportWidth[k] / 2,
   1926 							mode_lib->vba.ViewportHeight[k] / 2,
   1927 							mode_lib->vba.SwathWidthY[k] / 2,
   1928 							mode_lib->vba.GPUVMEnable,
   1929 							mode_lib->vba.VMMPageSize,
   1930 							mode_lib->vba.PTEBufferSizeInRequestsLuma,
   1931 							mode_lib->vba.PDEProcessingBufIn64KBReqs,
   1932 							mode_lib->vba.PitchC[k],
   1933 							0,
   1934 							&mode_lib->vba.MacroTileWidthC[k],
   1935 							&MetaRowByteC,
   1936 							&PixelPTEBytesPerRowC,
   1937 							&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel][0],
   1938 							&mode_lib->vba.dpte_row_height_chroma[k],
   1939 							&mode_lib->vba.meta_row_height_chroma[k]);
   1940 			mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
   1941 					mode_lib,
   1942 					mode_lib->vba.VRatio[k] / 2,
   1943 					mode_lib->vba.VTAPsChroma[k],
   1944 					mode_lib->vba.Interlace[k],
   1945 					mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
   1946 					mode_lib->vba.SwathHeightC[k],
   1947 					mode_lib->vba.ViewportYStartC[k],
   1948 					&mode_lib->vba.VInitPreFillC[k],
   1949 					&mode_lib->vba.MaxNumSwathC[k]);
   1950 		} else {
   1951 			PixelPTEBytesPerRowC = 0;
   1952 			PDEAndMetaPTEBytesFrameC = 0;
   1953 			MetaRowByteC = 0;
   1954 			mode_lib->vba.MaxNumSwathC[k] = 0;
   1955 			mode_lib->vba.PrefetchSourceLinesC[k] = 0;
   1956 		}
   1957 
   1958 		mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
   1959 		mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
   1960 				+ PDEAndMetaPTEBytesFrameC;
   1961 		mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
   1962 
   1963 		CalculateActiveRowBandwidth(
   1964 				mode_lib->vba.GPUVMEnable,
   1965 				mode_lib->vba.SourcePixelFormat[k],
   1966 				mode_lib->vba.VRatio[k],
   1967 				mode_lib->vba.DCCEnable[k],
   1968 				mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
   1969 				MetaRowByteY,
   1970 				MetaRowByteC,
   1971 				mode_lib->vba.meta_row_height[k],
   1972 				mode_lib->vba.meta_row_height_chroma[k],
   1973 				PixelPTEBytesPerRowY,
   1974 				PixelPTEBytesPerRowC,
   1975 				mode_lib->vba.dpte_row_height[k],
   1976 				mode_lib->vba.dpte_row_height_chroma[k],
   1977 				&mode_lib->vba.meta_row_bw[k],
   1978 				&mode_lib->vba.dpte_row_bw[k],
   1979 				&mode_lib->vba.qual_row_bw[k]);
   1980 	}
   1981 
   1982 	mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFCLKDeepSleep;
   1983 
   1984 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   1985 		if (mode_lib->vba.BlendingAndTiming[k] == k) {
   1986 			if (mode_lib->vba.WritebackEnable[k] == true) {
   1987 				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
   1988 						mode_lib->vba.WritebackLatency
   1989 								+ CalculateWriteBackDelay(
   1990 										mode_lib->vba.WritebackPixelFormat[k],
   1991 										mode_lib->vba.WritebackHRatio[k],
   1992 										mode_lib->vba.WritebackVRatio[k],
   1993 										mode_lib->vba.WritebackLumaHTaps[k],
   1994 										mode_lib->vba.WritebackLumaVTaps[k],
   1995 										mode_lib->vba.WritebackChromaHTaps[k],
   1996 										mode_lib->vba.WritebackChromaVTaps[k],
   1997 										mode_lib->vba.WritebackDestinationWidth[k])
   1998 										/ mode_lib->vba.DISPCLK;
   1999 			} else
   2000 				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
   2001 			for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
   2002 				if (mode_lib->vba.BlendingAndTiming[j] == k
   2003 						&& mode_lib->vba.WritebackEnable[j] == true) {
   2004 					mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
   2005 							dml_max(
   2006 									mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
   2007 									mode_lib->vba.WritebackLatency
   2008 											+ CalculateWriteBackDelay(
   2009 													mode_lib->vba.WritebackPixelFormat[j],
   2010 													mode_lib->vba.WritebackHRatio[j],
   2011 													mode_lib->vba.WritebackVRatio[j],
   2012 													mode_lib->vba.WritebackLumaHTaps[j],
   2013 													mode_lib->vba.WritebackLumaVTaps[j],
   2014 													mode_lib->vba.WritebackChromaHTaps[j],
   2015 													mode_lib->vba.WritebackChromaVTaps[j],
   2016 													mode_lib->vba.WritebackDestinationWidth[j])
   2017 													/ mode_lib->vba.DISPCLK);
   2018 				}
   2019 			}
   2020 		}
   2021 	}
   2022 
   2023 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
   2024 		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
   2025 			if (mode_lib->vba.BlendingAndTiming[k] == j)
   2026 				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
   2027 						mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
   2028 
   2029 	mode_lib->vba.VStartupLines = 13;
   2030 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2031 		mode_lib->vba.MaxVStartupLines[k] =
   2032 				mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
   2033 						- dml_max(
   2034 								1.0,
   2035 								dml_ceil(
   2036 										mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
   2037 												/ (mode_lib->vba.HTotal[k]
   2038 														/ mode_lib->vba.PixelClock[k]),
   2039 										1));
   2040 	}
   2041 
   2042 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
   2043 		mode_lib->vba.MaximumMaxVStartupLines = dml_max(
   2044 				mode_lib->vba.MaximumMaxVStartupLines,
   2045 				mode_lib->vba.MaxVStartupLines[k]);
   2046 
   2047 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2048 		mode_lib->vba.cursor_bw[k] = 0.0;
   2049 		for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
   2050 			mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
   2051 					* mode_lib->vba.CursorBPP[k][j] / 8.0
   2052 					/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
   2053 					* mode_lib->vba.VRatio[k];
   2054 	}
   2055 
   2056 	do {
   2057 		double MaxTotalRDBandwidth = 0;
   2058 		bool DestinationLineTimesForPrefetchLessThan2 = false;
   2059 		bool VRatioPrefetchMoreThan4 = false;
   2060 		bool prefetch_vm_bw_valid = true;
   2061 		bool prefetch_row_bw_valid = true;
   2062 		double TWait = CalculateTWait(
   2063 				mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
   2064 				mode_lib->vba.DRAMClockChangeLatency,
   2065 				mode_lib->vba.UrgentLatencyPixelDataOnly,
   2066 				mode_lib->vba.SREnterPlusExitTime);
   2067 
   2068 		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2069 			if (mode_lib->vba.XFCEnabled[k] == true) {
   2070 				mode_lib->vba.XFCRemoteSurfaceFlipDelay =
   2071 						CalculateRemoteSurfaceFlipDelay(
   2072 								mode_lib,
   2073 								mode_lib->vba.VRatio[k],
   2074 								mode_lib->vba.SwathWidthY[k],
   2075 								dml_ceil(
   2076 										mode_lib->vba.BytePerPixelDETY[k],
   2077 										1),
   2078 								mode_lib->vba.HTotal[k]
   2079 										/ mode_lib->vba.PixelClock[k],
   2080 								mode_lib->vba.XFCTSlvVupdateOffset,
   2081 								mode_lib->vba.XFCTSlvVupdateWidth,
   2082 								mode_lib->vba.XFCTSlvVreadyOffset,
   2083 								mode_lib->vba.XFCXBUFLatencyTolerance,
   2084 								mode_lib->vba.XFCFillBWOverhead,
   2085 								mode_lib->vba.XFCSlvChunkSize,
   2086 								mode_lib->vba.XFCBusTransportTime,
   2087 								mode_lib->vba.TCalc,
   2088 								TWait,
   2089 								&mode_lib->vba.SrcActiveDrainRate,
   2090 								&mode_lib->vba.TInitXFill,
   2091 								&mode_lib->vba.TslvChk);
   2092 			} else {
   2093 				mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
   2094 			}
   2095 			mode_lib->vba.ErrorResult[k] =
   2096 					CalculatePrefetchSchedule(
   2097 							mode_lib,
   2098 							mode_lib->vba.DPPCLK[k],
   2099 							mode_lib->vba.DISPCLK,
   2100 							mode_lib->vba.PixelClock[k],
   2101 							mode_lib->vba.DCFCLKDeepSleep,
   2102 							mode_lib->vba.DSCDelay[k],
   2103 							mode_lib->vba.DPPPerPlane[k],
   2104 							mode_lib->vba.ScalerEnabled[k],
   2105 							mode_lib->vba.NumberOfCursors[k],
   2106 							mode_lib->vba.DPPCLKDelaySubtotal,
   2107 							mode_lib->vba.DPPCLKDelaySCL,
   2108 							mode_lib->vba.DPPCLKDelaySCLLBOnly,
   2109 							mode_lib->vba.DPPCLKDelayCNVCFormater,
   2110 							mode_lib->vba.DPPCLKDelayCNVCCursor,
   2111 							mode_lib->vba.DISPCLKDelaySubtotal,
   2112 							(unsigned int) (mode_lib->vba.SwathWidthY[k]
   2113 									/ mode_lib->vba.HRatio[k]),
   2114 							mode_lib->vba.OutputFormat[k],
   2115 							mode_lib->vba.VTotal[k]
   2116 									- mode_lib->vba.VActive[k],
   2117 							mode_lib->vba.HTotal[k],
   2118 							mode_lib->vba.MaxInterDCNTileRepeaters,
   2119 							dml_min(
   2120 									mode_lib->vba.VStartupLines,
   2121 									mode_lib->vba.MaxVStartupLines[k]),
   2122 							mode_lib->vba.GPUVMMaxPageTableLevels,
   2123 							mode_lib->vba.GPUVMEnable,
   2124 							mode_lib->vba.DynamicMetadataEnable[k],
   2125 							mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
   2126 							mode_lib->vba.DynamicMetadataTransmittedBytes[k],
   2127 							mode_lib->vba.DCCEnable[k],
   2128 							mode_lib->vba.UrgentLatencyPixelDataOnly,
   2129 							mode_lib->vba.UrgentExtraLatency,
   2130 							mode_lib->vba.TCalc,
   2131 							mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
   2132 							mode_lib->vba.MetaRowByte[k],
   2133 							mode_lib->vba.PixelPTEBytesPerRow[k],
   2134 							mode_lib->vba.PrefetchSourceLinesY[k],
   2135 							mode_lib->vba.SwathWidthY[k],
   2136 							mode_lib->vba.BytePerPixelDETY[k],
   2137 							mode_lib->vba.VInitPreFillY[k],
   2138 							mode_lib->vba.MaxNumSwathY[k],
   2139 							mode_lib->vba.PrefetchSourceLinesC[k],
   2140 							mode_lib->vba.BytePerPixelDETC[k],
   2141 							mode_lib->vba.VInitPreFillC[k],
   2142 							mode_lib->vba.MaxNumSwathC[k],
   2143 							mode_lib->vba.SwathHeightY[k],
   2144 							mode_lib->vba.SwathHeightC[k],
   2145 							TWait,
   2146 							mode_lib->vba.XFCEnabled[k],
   2147 							mode_lib->vba.XFCRemoteSurfaceFlipDelay,
   2148 							mode_lib->vba.Interlace[k],
   2149 							mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
   2150 							&mode_lib->vba.DSTXAfterScaler[k],
   2151 							&mode_lib->vba.DSTYAfterScaler[k],
   2152 							&mode_lib->vba.DestinationLinesForPrefetch[k],
   2153 							&mode_lib->vba.PrefetchBandwidth[k],
   2154 							&mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
   2155 							&mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
   2156 							&mode_lib->vba.VRatioPrefetchY[k],
   2157 							&mode_lib->vba.VRatioPrefetchC[k],
   2158 							&mode_lib->vba.RequiredPrefetchPixDataBWLuma[k],
   2159 							&mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
   2160 							&mode_lib->vba.Tno_bw[k],
   2161 							&mode_lib->vba.VUpdateOffsetPix[k],
   2162 							&mode_lib->vba.VUpdateWidthPix[k],
   2163 							&mode_lib->vba.VReadyOffsetPix[k]);
   2164 			if (mode_lib->vba.BlendingAndTiming[k] == k) {
   2165 				mode_lib->vba.VStartup[k] = dml_min(
   2166 						mode_lib->vba.VStartupLines,
   2167 						mode_lib->vba.MaxVStartupLines[k]);
   2168 				if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
   2169 						!= 0) {
   2170 					mode_lib->vba.VStartup[k] =
   2171 							mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
   2172 				}
   2173 			} else {
   2174 				mode_lib->vba.VStartup[k] =
   2175 						dml_min(
   2176 								mode_lib->vba.VStartupLines,
   2177 								mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
   2178 			}
   2179 		}
   2180 
   2181 		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2182 
   2183 			if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
   2184 				mode_lib->vba.prefetch_vm_bw[k] = 0;
   2185 			else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
   2186 				mode_lib->vba.prefetch_vm_bw[k] =
   2187 						(double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
   2188 								/ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
   2189 										* mode_lib->vba.HTotal[k]
   2190 										/ mode_lib->vba.PixelClock[k]);
   2191 			} else {
   2192 				mode_lib->vba.prefetch_vm_bw[k] = 0;
   2193 				prefetch_vm_bw_valid = false;
   2194 			}
   2195 			if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
   2196 					== 0)
   2197 				mode_lib->vba.prefetch_row_bw[k] = 0;
   2198 			else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
   2199 				mode_lib->vba.prefetch_row_bw[k] =
   2200 						(double) (mode_lib->vba.MetaRowByte[k]
   2201 								+ mode_lib->vba.PixelPTEBytesPerRow[k])
   2202 								/ (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
   2203 										* mode_lib->vba.HTotal[k]
   2204 										/ mode_lib->vba.PixelClock[k]);
   2205 			} else {
   2206 				mode_lib->vba.prefetch_row_bw[k] = 0;
   2207 				prefetch_row_bw_valid = false;
   2208 			}
   2209 
   2210 			MaxTotalRDBandwidth =
   2211 					MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
   2212 							+ dml_max(
   2213 									mode_lib->vba.prefetch_vm_bw[k],
   2214 									dml_max(
   2215 											mode_lib->vba.prefetch_row_bw[k],
   2216 											dml_max(
   2217 													mode_lib->vba.ReadBandwidthPlaneLuma[k]
   2218 															+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
   2219 													mode_lib->vba.RequiredPrefetchPixDataBWLuma[k])
   2220 													+ mode_lib->vba.meta_row_bw[k]
   2221 													+ mode_lib->vba.dpte_row_bw[k]));
   2222 
   2223 			if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
   2224 				DestinationLineTimesForPrefetchLessThan2 = true;
   2225 			if (mode_lib->vba.VRatioPrefetchY[k] > 4
   2226 					|| mode_lib->vba.VRatioPrefetchC[k] > 4)
   2227 				VRatioPrefetchMoreThan4 = true;
   2228 		}
   2229 
   2230 		if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
   2231 				&& prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
   2232 				&& !DestinationLineTimesForPrefetchLessThan2)
   2233 			mode_lib->vba.PrefetchModeSupported = true;
   2234 		else {
   2235 			mode_lib->vba.PrefetchModeSupported = false;
   2236 			dml_print(
   2237 					"DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
   2238 		}
   2239 
   2240 		if (mode_lib->vba.PrefetchModeSupported == true) {
   2241 			double final_flip_bw[DC__NUM_DPP__MAX];
   2242 			unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
   2243 			double total_dcn_read_bw_with_flip = 0;
   2244 
   2245 			mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
   2246 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2247 				mode_lib->vba.BandwidthAvailableForImmediateFlip =
   2248 						mode_lib->vba.BandwidthAvailableForImmediateFlip
   2249 								- mode_lib->vba.cursor_bw[k]
   2250 								- dml_max(
   2251 										mode_lib->vba.ReadBandwidthPlaneLuma[k]
   2252 												+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
   2253 												+ mode_lib->vba.qual_row_bw[k],
   2254 										mode_lib->vba.PrefetchBandwidth[k]);
   2255 			}
   2256 
   2257 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2258 				ImmediateFlipBytes[k] = 0;
   2259 				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
   2260 						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
   2261 					ImmediateFlipBytes[k] =
   2262 							mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
   2263 									+ mode_lib->vba.MetaRowByte[k]
   2264 									+ mode_lib->vba.PixelPTEBytesPerRow[k];
   2265 				}
   2266 			}
   2267 			mode_lib->vba.TotImmediateFlipBytes = 0;
   2268 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2269 				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
   2270 						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
   2271 					mode_lib->vba.TotImmediateFlipBytes =
   2272 							mode_lib->vba.TotImmediateFlipBytes
   2273 									+ ImmediateFlipBytes[k];
   2274 				}
   2275 			}
   2276 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2277 				CalculateFlipSchedule(
   2278 						mode_lib,
   2279 						mode_lib->vba.UrgentExtraLatency,
   2280 						mode_lib->vba.UrgentLatencyPixelDataOnly,
   2281 						mode_lib->vba.GPUVMMaxPageTableLevels,
   2282 						mode_lib->vba.GPUVMEnable,
   2283 						mode_lib->vba.BandwidthAvailableForImmediateFlip,
   2284 						mode_lib->vba.TotImmediateFlipBytes,
   2285 						mode_lib->vba.SourcePixelFormat[k],
   2286 						ImmediateFlipBytes[k],
   2287 						mode_lib->vba.HTotal[k]
   2288 								/ mode_lib->vba.PixelClock[k],
   2289 						mode_lib->vba.VRatio[k],
   2290 						mode_lib->vba.Tno_bw[k],
   2291 						mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
   2292 						mode_lib->vba.MetaRowByte[k],
   2293 						mode_lib->vba.PixelPTEBytesPerRow[k],
   2294 						mode_lib->vba.DCCEnable[k],
   2295 						mode_lib->vba.dpte_row_height[k],
   2296 						mode_lib->vba.meta_row_height[k],
   2297 						mode_lib->vba.qual_row_bw[k],
   2298 						&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
   2299 						&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
   2300 						&final_flip_bw[k],
   2301 						&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
   2302 			}
   2303 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2304 				total_dcn_read_bw_with_flip =
   2305 						total_dcn_read_bw_with_flip
   2306 								+ mode_lib->vba.cursor_bw[k]
   2307 								+ dml_max(
   2308 										mode_lib->vba.prefetch_vm_bw[k],
   2309 										dml_max(
   2310 												mode_lib->vba.prefetch_row_bw[k],
   2311 												final_flip_bw[k]
   2312 														+ dml_max(
   2313 																mode_lib->vba.ReadBandwidthPlaneLuma[k]
   2314 																		+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
   2315 																mode_lib->vba.RequiredPrefetchPixDataBWLuma[k])));
   2316 			}
   2317 			mode_lib->vba.ImmediateFlipSupported = true;
   2318 			if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
   2319 				mode_lib->vba.ImmediateFlipSupported = false;
   2320 			}
   2321 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2322 				if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
   2323 					mode_lib->vba.ImmediateFlipSupported = false;
   2324 				}
   2325 			}
   2326 		} else {
   2327 			mode_lib->vba.ImmediateFlipSupported = false;
   2328 		}
   2329 
   2330 		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2331 			if (mode_lib->vba.ErrorResult[k]) {
   2332 				mode_lib->vba.PrefetchModeSupported = false;
   2333 				dml_print(
   2334 						"DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
   2335 			}
   2336 		}
   2337 
   2338 		mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
   2339 	} while (!((mode_lib->vba.PrefetchModeSupported
   2340 			&& (!mode_lib->vba.ImmediateFlipSupport
   2341 					|| mode_lib->vba.ImmediateFlipSupported))
   2342 			|| mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
   2343 
   2344 	//Display Pipeline Delivery Time in Prefetch
   2345 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2346 		if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
   2347 			mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
   2348 					mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
   2349 							/ mode_lib->vba.HRatio[k]
   2350 							/ mode_lib->vba.PixelClock[k];
   2351 		} else {
   2352 			mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
   2353 					mode_lib->vba.SwathWidthY[k]
   2354 							/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
   2355 							/ mode_lib->vba.DPPCLK[k];
   2356 		}
   2357 		if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
   2358 			mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
   2359 		} else {
   2360 			if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
   2361 				mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
   2362 						mode_lib->vba.SwathWidthY[k]
   2363 								* mode_lib->vba.DPPPerPlane[k]
   2364 								/ mode_lib->vba.HRatio[k]
   2365 								/ mode_lib->vba.PixelClock[k];
   2366 			} else {
   2367 				mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
   2368 						mode_lib->vba.SwathWidthY[k]
   2369 								/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
   2370 								/ mode_lib->vba.DPPCLK[k];
   2371 			}
   2372 		}
   2373 	}
   2374 
   2375 	// Min TTUVBlank
   2376 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2377 		if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
   2378 			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
   2379 			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
   2380 			mode_lib->vba.MinTTUVBlank[k] = dml_max(
   2381 					mode_lib->vba.DRAMClockChangeWatermark,
   2382 					dml_max(
   2383 							mode_lib->vba.StutterEnterPlusExitWatermark,
   2384 							mode_lib->vba.UrgentWatermark));
   2385 		} else if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 1) {
   2386 			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
   2387 			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
   2388 			mode_lib->vba.MinTTUVBlank[k] = dml_max(
   2389 					mode_lib->vba.StutterEnterPlusExitWatermark,
   2390 					mode_lib->vba.UrgentWatermark);
   2391 		} else {
   2392 			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
   2393 			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
   2394 			mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
   2395 		}
   2396 		if (!mode_lib->vba.DynamicMetadataEnable[k])
   2397 			mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
   2398 					+ mode_lib->vba.MinTTUVBlank[k];
   2399 	}
   2400 
   2401 	// DCC Configuration
   2402 	mode_lib->vba.ActiveDPPs = 0;
   2403 	// NB P-State/DRAM Clock Change Support
   2404 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2405 		mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
   2406 	}
   2407 
   2408 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2409 		double EffectiveLBLatencyHidingY;
   2410 		double EffectiveLBLatencyHidingC;
   2411 		double DPPOutputBufferLinesY;
   2412 		double DPPOutputBufferLinesC;
   2413 		double DPPOPPBufferingY;
   2414 		double MaxDETBufferingTimeY;
   2415 		double ActiveDRAMClockChangeLatencyMarginY;
   2416 
   2417 		mode_lib->vba.LBLatencyHidingSourceLinesY =
   2418 				dml_min(
   2419 						mode_lib->vba.MaxLineBufferLines,
   2420 						(unsigned int) dml_floor(
   2421 								(double) mode_lib->vba.LineBufferSize
   2422 										/ mode_lib->vba.LBBitPerPixel[k]
   2423 										/ (mode_lib->vba.SwathWidthY[k]
   2424 												/ dml_max(
   2425 														mode_lib->vba.HRatio[k],
   2426 														1.0)),
   2427 								1)) - (mode_lib->vba.vtaps[k] - 1);
   2428 
   2429 		mode_lib->vba.LBLatencyHidingSourceLinesC =
   2430 				dml_min(
   2431 						mode_lib->vba.MaxLineBufferLines,
   2432 						(unsigned int) dml_floor(
   2433 								(double) mode_lib->vba.LineBufferSize
   2434 										/ mode_lib->vba.LBBitPerPixel[k]
   2435 										/ (mode_lib->vba.SwathWidthY[k]
   2436 												/ 2.0
   2437 												/ dml_max(
   2438 														mode_lib->vba.HRatio[k]
   2439 																/ 2,
   2440 														1.0)),
   2441 								1))
   2442 						- (mode_lib->vba.VTAPsChroma[k] - 1);
   2443 
   2444 		EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
   2445 				/ mode_lib->vba.VRatio[k]
   2446 				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
   2447 
   2448 		EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
   2449 				/ (mode_lib->vba.VRatio[k] / 2)
   2450 				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
   2451 
   2452 		if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
   2453 			DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
   2454 					/ mode_lib->vba.SwathWidthY[k];
   2455 		} else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
   2456 			DPPOutputBufferLinesY = 0.5;
   2457 		} else {
   2458 			DPPOutputBufferLinesY = 1;
   2459 		}
   2460 
   2461 		if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
   2462 			DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
   2463 					/ (mode_lib->vba.SwathWidthY[k] / 2);
   2464 		} else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
   2465 			DPPOutputBufferLinesC = 0.5;
   2466 		} else {
   2467 			DPPOutputBufferLinesC = 1;
   2468 		}
   2469 
   2470 		DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
   2471 				* (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
   2472 		MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
   2473 				+ (mode_lib->vba.LinesInDETY[k]
   2474 						- mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
   2475 						/ mode_lib->vba.SwathHeightY[k]
   2476 						* (mode_lib->vba.HTotal[k]
   2477 								/ mode_lib->vba.PixelClock[k]);
   2478 
   2479 		ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
   2480 				+ MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
   2481 
   2482 		if (mode_lib->vba.ActiveDPPs > 1) {
   2483 			ActiveDRAMClockChangeLatencyMarginY =
   2484 					ActiveDRAMClockChangeLatencyMarginY
   2485 							- (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
   2486 									* mode_lib->vba.SwathHeightY[k]
   2487 									* (mode_lib->vba.HTotal[k]
   2488 											/ mode_lib->vba.PixelClock[k]);
   2489 		}
   2490 
   2491 		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
   2492 			double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
   2493 					/ mode_lib->vba.PixelClock[k])
   2494 					* (DPPOutputBufferLinesC
   2495 							+ mode_lib->vba.OPPOutputBufferLines);
   2496 			double MaxDETBufferingTimeC =
   2497 					mode_lib->vba.FullDETBufferingTimeC[k]
   2498 							+ (mode_lib->vba.LinesInDETC[k]
   2499 									- mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
   2500 									/ mode_lib->vba.SwathHeightC[k]
   2501 									* (mode_lib->vba.HTotal[k]
   2502 											/ mode_lib->vba.PixelClock[k]);
   2503 			double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
   2504 					+ EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
   2505 					- mode_lib->vba.DRAMClockChangeWatermark;
   2506 
   2507 			if (mode_lib->vba.ActiveDPPs > 1) {
   2508 				ActiveDRAMClockChangeLatencyMarginC =
   2509 						ActiveDRAMClockChangeLatencyMarginC
   2510 								- (1
   2511 										- 1
   2512 												/ (mode_lib->vba.ActiveDPPs
   2513 														- 1))
   2514 										* mode_lib->vba.SwathHeightC[k]
   2515 										* (mode_lib->vba.HTotal[k]
   2516 												/ mode_lib->vba.PixelClock[k]);
   2517 			}
   2518 			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
   2519 					ActiveDRAMClockChangeLatencyMarginY,
   2520 					ActiveDRAMClockChangeLatencyMarginC);
   2521 		} else {
   2522 			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
   2523 					ActiveDRAMClockChangeLatencyMarginY;
   2524 		}
   2525 
   2526 		if (mode_lib->vba.WritebackEnable[k]) {
   2527 			double WritebackDRAMClockChangeLatencyMargin;
   2528 
   2529 			if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
   2530 				WritebackDRAMClockChangeLatencyMargin =
   2531 						(double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
   2532 								+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
   2533 								/ (mode_lib->vba.WritebackDestinationWidth[k]
   2534 										* mode_lib->vba.WritebackDestinationHeight[k]
   2535 										/ (mode_lib->vba.WritebackSourceHeight[k]
   2536 												* mode_lib->vba.HTotal[k]
   2537 												/ mode_lib->vba.PixelClock[k])
   2538 										* 4)
   2539 								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
   2540 			} else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
   2541 				WritebackDRAMClockChangeLatencyMargin =
   2542 						dml_min(
   2543 								(double) mode_lib->vba.WritebackInterfaceLumaBufferSize
   2544 										* 8.0 / 10,
   2545 								2.0
   2546 										* mode_lib->vba.WritebackInterfaceChromaBufferSize
   2547 										* 8 / 10)
   2548 								/ (mode_lib->vba.WritebackDestinationWidth[k]
   2549 										* mode_lib->vba.WritebackDestinationHeight[k]
   2550 										/ (mode_lib->vba.WritebackSourceHeight[k]
   2551 												* mode_lib->vba.HTotal[k]
   2552 												/ mode_lib->vba.PixelClock[k]))
   2553 								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
   2554 			} else {
   2555 				WritebackDRAMClockChangeLatencyMargin =
   2556 						dml_min(
   2557 								(double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
   2558 								2.0
   2559 										* mode_lib->vba.WritebackInterfaceChromaBufferSize)
   2560 								/ (mode_lib->vba.WritebackDestinationWidth[k]
   2561 										* mode_lib->vba.WritebackDestinationHeight[k]
   2562 										/ (mode_lib->vba.WritebackSourceHeight[k]
   2563 												* mode_lib->vba.HTotal[k]
   2564 												/ mode_lib->vba.PixelClock[k]))
   2565 								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
   2566 			}
   2567 			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
   2568 					mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
   2569 					WritebackDRAMClockChangeLatencyMargin);
   2570 		}
   2571 	}
   2572 
   2573 	mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
   2574 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2575 		if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
   2576 				< mode_lib->vba.MinActiveDRAMClockChangeMargin) {
   2577 			mode_lib->vba.MinActiveDRAMClockChangeMargin =
   2578 					mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
   2579 		}
   2580 	}
   2581 
   2582 	mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
   2583 			mode_lib->vba.MinActiveDRAMClockChangeMargin
   2584 					+ mode_lib->vba.DRAMClockChangeLatency;
   2585 
   2586 	if (mode_lib->vba.DRAMClockChangeSupportsVActive &&
   2587 			mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) {
   2588 		mode_lib->vba.DRAMClockChangeWatermark += 25;
   2589 		mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
   2590 	} else {
   2591 		if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
   2592 			mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vblank;
   2593 			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2594 				if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
   2595 					mode_lib->vba.DRAMClockChangeSupport[0][0] =
   2596 							dm_dram_clock_change_unsupported;
   2597 				}
   2598 			}
   2599 		} else {
   2600 			mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_unsupported;
   2601 		}
   2602 	}
   2603 	for (k = 0; k <= mode_lib->vba.soc.num_states; k++)
   2604 		for (j = 0; j < 2; j++)
   2605 			mode_lib->vba.DRAMClockChangeSupport[k][j] = mode_lib->vba.DRAMClockChangeSupport[0][0];
   2606 
   2607 	//XFC Parameters:
   2608 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2609 		if (mode_lib->vba.XFCEnabled[k] == true) {
   2610 			double TWait;
   2611 
   2612 			mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
   2613 			mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
   2614 			mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
   2615 			TWait = CalculateTWait(
   2616 					mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
   2617 					mode_lib->vba.DRAMClockChangeLatency,
   2618 					mode_lib->vba.UrgentLatencyPixelDataOnly,
   2619 					mode_lib->vba.SREnterPlusExitTime);
   2620 			mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
   2621 					mode_lib,
   2622 					mode_lib->vba.VRatio[k],
   2623 					mode_lib->vba.SwathWidthY[k],
   2624 					dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
   2625 					mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
   2626 					mode_lib->vba.XFCTSlvVupdateOffset,
   2627 					mode_lib->vba.XFCTSlvVupdateWidth,
   2628 					mode_lib->vba.XFCTSlvVreadyOffset,
   2629 					mode_lib->vba.XFCXBUFLatencyTolerance,
   2630 					mode_lib->vba.XFCFillBWOverhead,
   2631 					mode_lib->vba.XFCSlvChunkSize,
   2632 					mode_lib->vba.XFCBusTransportTime,
   2633 					mode_lib->vba.TCalc,
   2634 					TWait,
   2635 					&mode_lib->vba.SrcActiveDrainRate,
   2636 					&mode_lib->vba.TInitXFill,
   2637 					&mode_lib->vba.TslvChk);
   2638 			mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
   2639 					dml_floor(
   2640 							mode_lib->vba.XFCRemoteSurfaceFlipDelay
   2641 									/ (mode_lib->vba.HTotal[k]
   2642 											/ mode_lib->vba.PixelClock[k]),
   2643 							1);
   2644 			mode_lib->vba.XFCTransferDelay[k] =
   2645 					dml_ceil(
   2646 							mode_lib->vba.XFCBusTransportTime
   2647 									/ (mode_lib->vba.HTotal[k]
   2648 											/ mode_lib->vba.PixelClock[k]),
   2649 							1);
   2650 			mode_lib->vba.XFCPrechargeDelay[k] =
   2651 					dml_ceil(
   2652 							(mode_lib->vba.XFCBusTransportTime
   2653 									+ mode_lib->vba.TInitXFill
   2654 									+ mode_lib->vba.TslvChk)
   2655 									/ (mode_lib->vba.HTotal[k]
   2656 											/ mode_lib->vba.PixelClock[k]),
   2657 							1);
   2658 			mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
   2659 					* mode_lib->vba.SrcActiveDrainRate;
   2660 			mode_lib->vba.FinalFillMargin =
   2661 					(mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
   2662 							+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
   2663 							* mode_lib->vba.HTotal[k]
   2664 							/ mode_lib->vba.PixelClock[k]
   2665 							* mode_lib->vba.SrcActiveDrainRate
   2666 							+ mode_lib->vba.XFCFillConstant;
   2667 			mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
   2668 					* mode_lib->vba.SrcActiveDrainRate
   2669 					+ mode_lib->vba.FinalFillMargin;
   2670 			mode_lib->vba.RemainingFillLevel = dml_max(
   2671 					0.0,
   2672 					mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
   2673 			mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
   2674 					/ (mode_lib->vba.SrcActiveDrainRate
   2675 							* mode_lib->vba.XFCFillBWOverhead / 100);
   2676 			mode_lib->vba.XFCPrefetchMargin[k] =
   2677 					mode_lib->vba.XFCRemoteSurfaceFlipDelay
   2678 							+ mode_lib->vba.TFinalxFill
   2679 							+ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
   2680 									+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
   2681 									* mode_lib->vba.HTotal[k]
   2682 									/ mode_lib->vba.PixelClock[k];
   2683 		} else {
   2684 			mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
   2685 			mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
   2686 			mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
   2687 			mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
   2688 			mode_lib->vba.XFCPrechargeDelay[k] = 0;
   2689 			mode_lib->vba.XFCTransferDelay[k] = 0;
   2690 			mode_lib->vba.XFCPrefetchMargin[k] = 0;
   2691 		}
   2692 	}
   2693 	{
   2694 		unsigned int VStartupMargin = 0;
   2695 		bool FirstMainPlane = true;
   2696 
   2697 		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2698 			if (mode_lib->vba.BlendingAndTiming[k] == k) {
   2699 				unsigned int Margin = (mode_lib->vba.MaxVStartupLines[k] - mode_lib->vba.VStartup[k])
   2700 						* mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k];
   2701 
   2702 				if (FirstMainPlane) {
   2703 					VStartupMargin = Margin;
   2704 					FirstMainPlane = false;
   2705 				} else
   2706 					VStartupMargin = dml_min(VStartupMargin, Margin);
   2707 		}
   2708 
   2709 		if (mode_lib->vba.UseMaximumVStartup) {
   2710 			if (mode_lib->vba.VTotal_Max[k] == mode_lib->vba.VTotal[k]) {
   2711 				//only use max vstart if it is not drr or lateflip.
   2712 				mode_lib->vba.VStartup[k] = mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]];
   2713 			}
   2714 		}
   2715 	}
   2716 }
   2717 }
   2718 
   2719 static void dml20_DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
   2720 {
   2721 	double BytePerPixDETY;
   2722 	double BytePerPixDETC;
   2723 	double Read256BytesBlockHeightY;
   2724 	double Read256BytesBlockHeightC;
   2725 	double Read256BytesBlockWidthY;
   2726 	double Read256BytesBlockWidthC;
   2727 	double MaximumSwathHeightY;
   2728 	double MaximumSwathHeightC;
   2729 	double MinimumSwathHeightY;
   2730 	double MinimumSwathHeightC;
   2731 	double SwathWidth;
   2732 	double SwathWidthGranularityY;
   2733 	double SwathWidthGranularityC;
   2734 	double RoundedUpMaxSwathSizeBytesY;
   2735 	double RoundedUpMaxSwathSizeBytesC;
   2736 	unsigned int j, k;
   2737 
   2738 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   2739 		bool MainPlaneDoesODMCombine = false;
   2740 
   2741 		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
   2742 			BytePerPixDETY = 8;
   2743 			BytePerPixDETC = 0;
   2744 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
   2745 			BytePerPixDETY = 4;
   2746 			BytePerPixDETC = 0;
   2747 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
   2748 			BytePerPixDETY = 2;
   2749 			BytePerPixDETC = 0;
   2750 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
   2751 			BytePerPixDETY = 1;
   2752 			BytePerPixDETC = 0;
   2753 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
   2754 			BytePerPixDETY = 1;
   2755 			BytePerPixDETC = 2;
   2756 		} else {
   2757 			BytePerPixDETY = 4.0 / 3.0;
   2758 			BytePerPixDETC = 8.0 / 3.0;
   2759 		}
   2760 
   2761 		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
   2762 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
   2763 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
   2764 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
   2765 			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
   2766 				Read256BytesBlockHeightY = 1;
   2767 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
   2768 				Read256BytesBlockHeightY = 4;
   2769 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
   2770 					|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
   2771 				Read256BytesBlockHeightY = 8;
   2772 			} else {
   2773 				Read256BytesBlockHeightY = 16;
   2774 			}
   2775 			Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
   2776 					/ Read256BytesBlockHeightY;
   2777 			Read256BytesBlockHeightC = 0;
   2778 			Read256BytesBlockWidthC = 0;
   2779 		} else {
   2780 			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
   2781 				Read256BytesBlockHeightY = 1;
   2782 				Read256BytesBlockHeightC = 1;
   2783 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
   2784 				Read256BytesBlockHeightY = 16;
   2785 				Read256BytesBlockHeightC = 8;
   2786 			} else {
   2787 				Read256BytesBlockHeightY = 8;
   2788 				Read256BytesBlockHeightC = 8;
   2789 			}
   2790 			Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
   2791 					/ Read256BytesBlockHeightY;
   2792 			Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
   2793 					/ Read256BytesBlockHeightC;
   2794 		}
   2795 
   2796 		if (mode_lib->vba.SourceScan[k] == dm_horz) {
   2797 			MaximumSwathHeightY = Read256BytesBlockHeightY;
   2798 			MaximumSwathHeightC = Read256BytesBlockHeightC;
   2799 		} else {
   2800 			MaximumSwathHeightY = Read256BytesBlockWidthY;
   2801 			MaximumSwathHeightC = Read256BytesBlockWidthC;
   2802 		}
   2803 
   2804 		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
   2805 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
   2806 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
   2807 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
   2808 			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
   2809 					|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
   2810 							&& (mode_lib->vba.SurfaceTiling[k]
   2811 									== dm_sw_4kb_s
   2812 									|| mode_lib->vba.SurfaceTiling[k]
   2813 											== dm_sw_4kb_s_x
   2814 									|| mode_lib->vba.SurfaceTiling[k]
   2815 											== dm_sw_64kb_s
   2816 									|| mode_lib->vba.SurfaceTiling[k]
   2817 											== dm_sw_64kb_s_t
   2818 									|| mode_lib->vba.SurfaceTiling[k]
   2819 											== dm_sw_64kb_s_x
   2820 									|| mode_lib->vba.SurfaceTiling[k]
   2821 											== dm_sw_var_s
   2822 									|| mode_lib->vba.SurfaceTiling[k]
   2823 											== dm_sw_var_s_x)
   2824 							&& mode_lib->vba.SourceScan[k] == dm_horz)) {
   2825 				MinimumSwathHeightY = MaximumSwathHeightY;
   2826 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
   2827 					&& mode_lib->vba.SourceScan[k] != dm_horz) {
   2828 				MinimumSwathHeightY = MaximumSwathHeightY;
   2829 			} else {
   2830 				MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
   2831 			}
   2832 			MinimumSwathHeightC = MaximumSwathHeightC;
   2833 		} else {
   2834 			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
   2835 				MinimumSwathHeightY = MaximumSwathHeightY;
   2836 				MinimumSwathHeightC = MaximumSwathHeightC;
   2837 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
   2838 					&& mode_lib->vba.SourceScan[k] == dm_horz) {
   2839 				MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
   2840 				MinimumSwathHeightC = MaximumSwathHeightC;
   2841 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
   2842 					&& mode_lib->vba.SourceScan[k] == dm_horz) {
   2843 				MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
   2844 				MinimumSwathHeightY = MaximumSwathHeightY;
   2845 			} else {
   2846 				MinimumSwathHeightY = MaximumSwathHeightY;
   2847 				MinimumSwathHeightC = MaximumSwathHeightC;
   2848 			}
   2849 		}
   2850 
   2851 		if (mode_lib->vba.SourceScan[k] == dm_horz) {
   2852 			SwathWidth = mode_lib->vba.ViewportWidth[k];
   2853 		} else {
   2854 			SwathWidth = mode_lib->vba.ViewportHeight[k];
   2855 		}
   2856 
   2857 		if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
   2858 			MainPlaneDoesODMCombine = true;
   2859 		}
   2860 		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
   2861 			if (mode_lib->vba.BlendingAndTiming[k] == j
   2862 					&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
   2863 				MainPlaneDoesODMCombine = true;
   2864 			}
   2865 		}
   2866 
   2867 		if (MainPlaneDoesODMCombine == true) {
   2868 			SwathWidth = dml_min(
   2869 					SwathWidth,
   2870 					mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
   2871 		} else {
   2872 			if (mode_lib->vba.DPPPerPlane[k] == 0)
   2873 				SwathWidth = 0;
   2874 			else
   2875 				SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
   2876 		}
   2877 
   2878 		SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
   2879 		RoundedUpMaxSwathSizeBytesY = (dml_ceil(
   2880 				(double) (SwathWidth - 1),
   2881 				SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
   2882 				* MaximumSwathHeightY;
   2883 		if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
   2884 			RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
   2885 					+ 256;
   2886 		}
   2887 		if (MaximumSwathHeightC > 0) {
   2888 			SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
   2889 					/ MaximumSwathHeightC;
   2890 			RoundedUpMaxSwathSizeBytesC = (dml_ceil(
   2891 					(double) (SwathWidth / 2.0 - 1),
   2892 					SwathWidthGranularityC) + SwathWidthGranularityC)
   2893 					* BytePerPixDETC * MaximumSwathHeightC;
   2894 			if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
   2895 				RoundedUpMaxSwathSizeBytesC = dml_ceil(
   2896 						RoundedUpMaxSwathSizeBytesC,
   2897 						256) + 256;
   2898 			}
   2899 		} else
   2900 			RoundedUpMaxSwathSizeBytesC = 0.0;
   2901 
   2902 		if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
   2903 				<= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
   2904 			mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
   2905 			mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
   2906 		} else {
   2907 			mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
   2908 			mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
   2909 		}
   2910 
   2911 		if (mode_lib->vba.SwathHeightC[k] == 0) {
   2912 			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
   2913 			mode_lib->vba.DETBufferSizeC[k] = 0;
   2914 		} else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
   2915 			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
   2916 					* 1024.0 / 2;
   2917 			mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
   2918 					* 1024.0 / 2;
   2919 		} else {
   2920 			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
   2921 					* 1024.0 * 2 / 3;
   2922 			mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
   2923 					* 1024.0 / 3;
   2924 		}
   2925 	}
   2926 }
   2927 
   2928 static double CalculateTWait(
   2929 		unsigned int PrefetchMode,
   2930 		double DRAMClockChangeLatency,
   2931 		double UrgentLatencyPixelDataOnly,
   2932 		double SREnterPlusExitTime)
   2933 {
   2934 	if (PrefetchMode == 0) {
   2935 		return dml_max(
   2936 				DRAMClockChangeLatency + UrgentLatencyPixelDataOnly,
   2937 				dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly));
   2938 	} else if (PrefetchMode == 1) {
   2939 		return dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly);
   2940 	} else {
   2941 		return UrgentLatencyPixelDataOnly;
   2942 	}
   2943 }
   2944 
   2945 static double CalculateRemoteSurfaceFlipDelay(
   2946 		struct display_mode_lib *mode_lib,
   2947 		double VRatio,
   2948 		double SwathWidth,
   2949 		double Bpp,
   2950 		double LineTime,
   2951 		double XFCTSlvVupdateOffset,
   2952 		double XFCTSlvVupdateWidth,
   2953 		double XFCTSlvVreadyOffset,
   2954 		double XFCXBUFLatencyTolerance,
   2955 		double XFCFillBWOverhead,
   2956 		double XFCSlvChunkSize,
   2957 		double XFCBusTransportTime,
   2958 		double TCalc,
   2959 		double TWait,
   2960 		double *SrcActiveDrainRate,
   2961 		double *TInitXFill,
   2962 		double *TslvChk)
   2963 {
   2964 	double TSlvSetup, AvgfillRate, result;
   2965 
   2966 	*SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
   2967 	TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
   2968 	*TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
   2969 	AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
   2970 	*TslvChk = XFCSlvChunkSize / AvgfillRate;
   2971 	dml_print(
   2972 			"DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
   2973 			*SrcActiveDrainRate);
   2974 	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
   2975 	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
   2976 	dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
   2977 	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
   2978 	result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
   2979 	dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
   2980 	return result;
   2981 }
   2982 
   2983 static double CalculateWriteBackDelay(
   2984 		enum source_format_class WritebackPixelFormat,
   2985 		double WritebackHRatio,
   2986 		double WritebackVRatio,
   2987 		unsigned int WritebackLumaHTaps,
   2988 		unsigned int WritebackLumaVTaps,
   2989 		unsigned int WritebackChromaHTaps,
   2990 		unsigned int WritebackChromaVTaps,
   2991 		unsigned int WritebackDestinationWidth)
   2992 {
   2993 	double CalculateWriteBackDelay =
   2994 			dml_max(
   2995 					dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
   2996 					WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
   2997 							* dml_ceil(
   2998 									WritebackDestinationWidth
   2999 											/ 4.0,
   3000 									1)
   3001 							+ dml_ceil(1.0 / WritebackVRatio, 1)
   3002 									* (dml_ceil(
   3003 											WritebackLumaVTaps
   3004 													/ 4.0,
   3005 											1) + 4));
   3006 
   3007 	if (WritebackPixelFormat != dm_444_32) {
   3008 		CalculateWriteBackDelay =
   3009 				dml_max(
   3010 						CalculateWriteBackDelay,
   3011 						dml_max(
   3012 								dml_ceil(
   3013 										WritebackChromaHTaps
   3014 												/ 2.0,
   3015 										1)
   3016 										/ (2
   3017 												* WritebackHRatio),
   3018 								WritebackChromaVTaps
   3019 										* dml_ceil(
   3020 												1
   3021 														/ (2
   3022 																* WritebackVRatio),
   3023 												1)
   3024 										* dml_ceil(
   3025 												WritebackDestinationWidth
   3026 														/ 2.0
   3027 														/ 2.0,
   3028 												1)
   3029 										+ dml_ceil(
   3030 												1
   3031 														/ (2
   3032 																* WritebackVRatio),
   3033 												1)
   3034 												* (dml_ceil(
   3035 														WritebackChromaVTaps
   3036 																/ 4.0,
   3037 														1)
   3038 														+ 4)));
   3039 	}
   3040 	return CalculateWriteBackDelay;
   3041 }
   3042 
   3043 static void CalculateActiveRowBandwidth(
   3044 		bool GPUVMEnable,
   3045 		enum source_format_class SourcePixelFormat,
   3046 		double VRatio,
   3047 		bool DCCEnable,
   3048 		double LineTime,
   3049 		unsigned int MetaRowByteLuma,
   3050 		unsigned int MetaRowByteChroma,
   3051 		unsigned int meta_row_height_luma,
   3052 		unsigned int meta_row_height_chroma,
   3053 		unsigned int PixelPTEBytesPerRowLuma,
   3054 		unsigned int PixelPTEBytesPerRowChroma,
   3055 		unsigned int dpte_row_height_luma,
   3056 		unsigned int dpte_row_height_chroma,
   3057 		double *meta_row_bw,
   3058 		double *dpte_row_bw,
   3059 		double *qual_row_bw)
   3060 {
   3061 	if (DCCEnable != true) {
   3062 		*meta_row_bw = 0;
   3063 	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
   3064 		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
   3065 				+ VRatio / 2 * MetaRowByteChroma
   3066 						/ (meta_row_height_chroma * LineTime);
   3067 	} else {
   3068 		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
   3069 	}
   3070 
   3071 	if (GPUVMEnable != true) {
   3072 		*dpte_row_bw = 0;
   3073 	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
   3074 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
   3075 				+ VRatio / 2 * PixelPTEBytesPerRowChroma
   3076 						/ (dpte_row_height_chroma * LineTime);
   3077 	} else {
   3078 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
   3079 	}
   3080 
   3081 	if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
   3082 		*qual_row_bw = *meta_row_bw + *dpte_row_bw;
   3083 	} else {
   3084 		*qual_row_bw = 0;
   3085 	}
   3086 }
   3087 
   3088 static void CalculateFlipSchedule(
   3089 		struct display_mode_lib *mode_lib,
   3090 		double UrgentExtraLatency,
   3091 		double UrgentLatencyPixelDataOnly,
   3092 		unsigned int GPUVMMaxPageTableLevels,
   3093 		bool GPUVMEnable,
   3094 		double BandwidthAvailableForImmediateFlip,
   3095 		unsigned int TotImmediateFlipBytes,
   3096 		enum source_format_class SourcePixelFormat,
   3097 		unsigned int ImmediateFlipBytes,
   3098 		double LineTime,
   3099 		double VRatio,
   3100 		double Tno_bw,
   3101 		double PDEAndMetaPTEBytesFrame,
   3102 		unsigned int MetaRowByte,
   3103 		unsigned int PixelPTEBytesPerRow,
   3104 		bool DCCEnable,
   3105 		unsigned int dpte_row_height,
   3106 		unsigned int meta_row_height,
   3107 		double qual_row_bw,
   3108 		double *DestinationLinesToRequestVMInImmediateFlip,
   3109 		double *DestinationLinesToRequestRowInImmediateFlip,
   3110 		double *final_flip_bw,
   3111 		bool *ImmediateFlipSupportedForPipe)
   3112 {
   3113 	double min_row_time = 0.0;
   3114 
   3115 	if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
   3116 		*DestinationLinesToRequestVMInImmediateFlip = 0.0;
   3117 		*DestinationLinesToRequestRowInImmediateFlip = 0.0;
   3118 		*final_flip_bw = qual_row_bw;
   3119 		*ImmediateFlipSupportedForPipe = true;
   3120 	} else {
   3121 		double TimeForFetchingMetaPTEImmediateFlip;
   3122 		double TimeForFetchingRowInVBlankImmediateFlip;
   3123 
   3124 		if (GPUVMEnable == true) {
   3125 			mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
   3126 					* ImmediateFlipBytes / TotImmediateFlipBytes;
   3127 			TimeForFetchingMetaPTEImmediateFlip =
   3128 					dml_max(
   3129 							Tno_bw
   3130 									+ PDEAndMetaPTEBytesFrame
   3131 											/ mode_lib->vba.ImmediateFlipBW[0],
   3132 							dml_max(
   3133 									UrgentExtraLatency
   3134 											+ UrgentLatencyPixelDataOnly
   3135 													* (GPUVMMaxPageTableLevels
   3136 															- 1),
   3137 									LineTime / 4.0));
   3138 		} else {
   3139 			TimeForFetchingMetaPTEImmediateFlip = 0;
   3140 		}
   3141 
   3142 		*DestinationLinesToRequestVMInImmediateFlip = dml_floor(
   3143 				4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
   3144 				1) / 4.0;
   3145 
   3146 		if ((GPUVMEnable == true || DCCEnable == true)) {
   3147 			mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
   3148 					* ImmediateFlipBytes / TotImmediateFlipBytes;
   3149 			TimeForFetchingRowInVBlankImmediateFlip = dml_max(
   3150 					(MetaRowByte + PixelPTEBytesPerRow)
   3151 							/ mode_lib->vba.ImmediateFlipBW[0],
   3152 					dml_max(UrgentLatencyPixelDataOnly, LineTime / 4.0));
   3153 		} else {
   3154 			TimeForFetchingRowInVBlankImmediateFlip = 0;
   3155 		}
   3156 
   3157 		*DestinationLinesToRequestRowInImmediateFlip = dml_floor(
   3158 				4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
   3159 				1) / 4.0;
   3160 
   3161 		if (GPUVMEnable == true) {
   3162 			*final_flip_bw =
   3163 					dml_max(
   3164 							PDEAndMetaPTEBytesFrame
   3165 									/ (*DestinationLinesToRequestVMInImmediateFlip
   3166 											* LineTime),
   3167 							(MetaRowByte + PixelPTEBytesPerRow)
   3168 									/ (TimeForFetchingRowInVBlankImmediateFlip
   3169 											* LineTime));
   3170 		} else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
   3171 			*final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
   3172 					/ (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
   3173 		} else {
   3174 			*final_flip_bw = 0;
   3175 		}
   3176 
   3177 		if (GPUVMEnable && !DCCEnable)
   3178 			min_row_time = dpte_row_height * LineTime / VRatio;
   3179 		else if (!GPUVMEnable && DCCEnable)
   3180 			min_row_time = meta_row_height * LineTime / VRatio;
   3181 		else
   3182 			min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
   3183 					/ VRatio;
   3184 
   3185 		if (*DestinationLinesToRequestVMInImmediateFlip >= 8
   3186 				|| *DestinationLinesToRequestRowInImmediateFlip >= 16
   3187 				|| TimeForFetchingMetaPTEImmediateFlip
   3188 						+ 2 * TimeForFetchingRowInVBlankImmediateFlip
   3189 						> min_row_time)
   3190 			*ImmediateFlipSupportedForPipe = false;
   3191 		else
   3192 			*ImmediateFlipSupportedForPipe = true;
   3193 	}
   3194 }
   3195 
   3196 static unsigned int TruncToValidBPP(
   3197 		double DecimalBPP,
   3198 		bool DSCEnabled,
   3199 		enum output_encoder_class Output,
   3200 		enum output_format_class Format,
   3201 		unsigned int DSCInputBitPerComponent)
   3202 {
   3203 	if (Output == dm_hdmi) {
   3204 		if (Format == dm_420) {
   3205 			if (DecimalBPP >= 18)
   3206 				return 18;
   3207 			else if (DecimalBPP >= 15)
   3208 				return 15;
   3209 			else if (DecimalBPP >= 12)
   3210 				return 12;
   3211 			else
   3212 				return BPP_INVALID;
   3213 		} else if (Format == dm_444) {
   3214 			if (DecimalBPP >= 36)
   3215 				return 36;
   3216 			else if (DecimalBPP >= 30)
   3217 				return 30;
   3218 			else if (DecimalBPP >= 24)
   3219 				return 24;
   3220 			else if (DecimalBPP >= 18)
   3221 				return 18;
   3222 			else
   3223 				return BPP_INVALID;
   3224 		} else {
   3225 			if (DecimalBPP / 1.5 >= 24)
   3226 				return 24;
   3227 			else if (DecimalBPP / 1.5 >= 20)
   3228 				return 20;
   3229 			else if (DecimalBPP / 1.5 >= 16)
   3230 				return 16;
   3231 			else
   3232 				return BPP_INVALID;
   3233 		}
   3234 	} else {
   3235 		if (DSCEnabled) {
   3236 			if (Format == dm_420) {
   3237 				if (DecimalBPP < 6)
   3238 					return BPP_INVALID;
   3239 				else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
   3240 					return 1.5 * DSCInputBitPerComponent - 1 / 16;
   3241 				else
   3242 					return dml_floor(16 * DecimalBPP, 1) / 16;
   3243 			} else if (Format == dm_n422) {
   3244 				if (DecimalBPP < 7)
   3245 					return BPP_INVALID;
   3246 				else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
   3247 					return 2 * DSCInputBitPerComponent - 1 / 16;
   3248 				else
   3249 					return dml_floor(16 * DecimalBPP, 1) / 16;
   3250 			} else {
   3251 				if (DecimalBPP < 8)
   3252 					return BPP_INVALID;
   3253 				else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
   3254 					return 3 * DSCInputBitPerComponent - 1 / 16;
   3255 				else
   3256 					return dml_floor(16 * DecimalBPP, 1) / 16;
   3257 			}
   3258 		} else if (Format == dm_420) {
   3259 			if (DecimalBPP >= 18)
   3260 				return 18;
   3261 			else if (DecimalBPP >= 15)
   3262 				return 15;
   3263 			else if (DecimalBPP >= 12)
   3264 				return 12;
   3265 			else
   3266 				return BPP_INVALID;
   3267 		} else if (Format == dm_s422 || Format == dm_n422) {
   3268 			if (DecimalBPP >= 24)
   3269 				return 24;
   3270 			else if (DecimalBPP >= 20)
   3271 				return 20;
   3272 			else if (DecimalBPP >= 16)
   3273 				return 16;
   3274 			else
   3275 				return BPP_INVALID;
   3276 		} else {
   3277 			if (DecimalBPP >= 36)
   3278 				return 36;
   3279 			else if (DecimalBPP >= 30)
   3280 				return 30;
   3281 			else if (DecimalBPP >= 24)
   3282 				return 24;
   3283 			else if (DecimalBPP >= 18)
   3284 				return 18;
   3285 			else
   3286 				return BPP_INVALID;
   3287 		}
   3288 	}
   3289 }
   3290 
   3291 void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
   3292 {
   3293 	struct vba_vars_st *locals = &mode_lib->vba;
   3294 
   3295 	int i;
   3296 	unsigned int j, k, m;
   3297 
   3298 	/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
   3299 
   3300 	/*Scale Ratio, taps Support Check*/
   3301 
   3302 	mode_lib->vba.ScaleRatioAndTapsSupport = true;
   3303 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3304 		if (mode_lib->vba.ScalerEnabled[k] == false
   3305 				&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
   3306 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
   3307 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
   3308 						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
   3309 						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
   3310 						|| mode_lib->vba.HRatio[k] != 1.0
   3311 						|| mode_lib->vba.htaps[k] != 1.0
   3312 						|| mode_lib->vba.VRatio[k] != 1.0
   3313 						|| mode_lib->vba.vtaps[k] != 1.0)) {
   3314 			mode_lib->vba.ScaleRatioAndTapsSupport = false;
   3315 		} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
   3316 				|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
   3317 				|| (mode_lib->vba.htaps[k] > 1.0
   3318 						&& (mode_lib->vba.htaps[k] % 2) == 1)
   3319 				|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
   3320 				|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
   3321 				|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
   3322 				|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
   3323 				|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
   3324 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
   3325 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
   3326 						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
   3327 						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
   3328 						&& (mode_lib->vba.HRatio[k] / 2.0
   3329 								> mode_lib->vba.HTAPsChroma[k]
   3330 								|| mode_lib->vba.VRatio[k] / 2.0
   3331 										> mode_lib->vba.VTAPsChroma[k]))) {
   3332 			mode_lib->vba.ScaleRatioAndTapsSupport = false;
   3333 		}
   3334 	}
   3335 	/*Source Format, Pixel Format and Scan Support Check*/
   3336 
   3337 	mode_lib->vba.SourceFormatPixelAndScanSupport = true;
   3338 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3339 		if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
   3340 				&& mode_lib->vba.SourceScan[k] != dm_horz)
   3341 				|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
   3342 						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
   3343 						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
   3344 						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
   3345 						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
   3346 						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
   3347 						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
   3348 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
   3349 				|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
   3350 						&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
   3351 								|| mode_lib->vba.SourcePixelFormat[k]
   3352 										== dm_420_8
   3353 								|| mode_lib->vba.SourcePixelFormat[k]
   3354 										== dm_420_10))
   3355 				|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
   3356 						|| mode_lib->vba.SurfaceTiling[k]
   3357 								== dm_sw_gfx7_2d_thin_l_vp)
   3358 						&& !((mode_lib->vba.SourcePixelFormat[k]
   3359 								== dm_444_64
   3360 								|| mode_lib->vba.SourcePixelFormat[k]
   3361 										== dm_444_32)
   3362 								&& mode_lib->vba.SourceScan[k]
   3363 										== dm_horz
   3364 								&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
   3365 										== true
   3366 								&& mode_lib->vba.DCCEnable[k]
   3367 										== false))
   3368 						|| (mode_lib->vba.DCCEnable[k] == true
   3369 								&& (mode_lib->vba.SurfaceTiling[k]
   3370 										== dm_sw_linear
   3371 										|| mode_lib->vba.SourcePixelFormat[k]
   3372 												== dm_420_8
   3373 										|| mode_lib->vba.SourcePixelFormat[k]
   3374 												== dm_420_10)))) {
   3375 			mode_lib->vba.SourceFormatPixelAndScanSupport = false;
   3376 		}
   3377 	}
   3378 	/*Bandwidth Support Check*/
   3379 
   3380 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3381 		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
   3382 			locals->BytePerPixelInDETY[k] = 8.0;
   3383 			locals->BytePerPixelInDETC[k] = 0.0;
   3384 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
   3385 			locals->BytePerPixelInDETY[k] = 4.0;
   3386 			locals->BytePerPixelInDETC[k] = 0.0;
   3387 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
   3388 				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
   3389 			locals->BytePerPixelInDETY[k] = 2.0;
   3390 			locals->BytePerPixelInDETC[k] = 0.0;
   3391 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
   3392 			locals->BytePerPixelInDETY[k] = 1.0;
   3393 			locals->BytePerPixelInDETC[k] = 0.0;
   3394 		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
   3395 			locals->BytePerPixelInDETY[k] = 1.0;
   3396 			locals->BytePerPixelInDETC[k] = 2.0;
   3397 		} else {
   3398 			locals->BytePerPixelInDETY[k] = 4.0 / 3;
   3399 			locals->BytePerPixelInDETC[k] = 8.0 / 3;
   3400 		}
   3401 		if (mode_lib->vba.SourceScan[k] == dm_horz) {
   3402 			locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
   3403 		} else {
   3404 			locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
   3405 		}
   3406 	}
   3407 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3408 		locals->ReadBandwidthLuma[k] = locals->SwathWidthYSingleDPP[k] * dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
   3409 				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
   3410 		locals->ReadBandwidthChroma[k] = locals->SwathWidthYSingleDPP[k] / 2 * dml_ceil(locals->BytePerPixelInDETC[k], 2.0)
   3411 				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k] / 2.0;
   3412 		locals->ReadBandwidth[k] = locals->ReadBandwidthLuma[k] + locals->ReadBandwidthChroma[k];
   3413 	}
   3414 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3415 		if (mode_lib->vba.WritebackEnable[k] == true
   3416 				&& mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
   3417 			locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
   3418 					* mode_lib->vba.WritebackDestinationHeight[k]
   3419 					/ (mode_lib->vba.WritebackSourceHeight[k]
   3420 							* mode_lib->vba.HTotal[k]
   3421 							/ mode_lib->vba.PixelClock[k]) * 4.0;
   3422 		} else if (mode_lib->vba.WritebackEnable[k] == true
   3423 				&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
   3424 			locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
   3425 					* mode_lib->vba.WritebackDestinationHeight[k]
   3426 					/ (mode_lib->vba.WritebackSourceHeight[k]
   3427 							* mode_lib->vba.HTotal[k]
   3428 							/ mode_lib->vba.PixelClock[k]) * 3.0;
   3429 		} else if (mode_lib->vba.WritebackEnable[k] == true) {
   3430 			locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
   3431 					* mode_lib->vba.WritebackDestinationHeight[k]
   3432 					/ (mode_lib->vba.WritebackSourceHeight[k]
   3433 							* mode_lib->vba.HTotal[k]
   3434 							/ mode_lib->vba.PixelClock[k]) * 1.5;
   3435 		} else {
   3436 			locals->WriteBandwidth[k] = 0.0;
   3437 		}
   3438 	}
   3439 	mode_lib->vba.DCCEnabledInAnyPlane = false;
   3440 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3441 		if (mode_lib->vba.DCCEnable[k] == true) {
   3442 			mode_lib->vba.DCCEnabledInAnyPlane = true;
   3443 		}
   3444 	}
   3445 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   3446 		locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
   3447 				mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
   3448 						* mode_lib->vba.DRAMChannelWidth,
   3449 				mode_lib->vba.FabricClockPerState[i]
   3450 						* mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000;
   3451 		locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth * locals->DCFCLKPerState[i],
   3452 				locals->FabricAndDRAMBandwidthPerState[i] * 1000)
   3453 				* locals->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
   3454 
   3455 		locals->ReturnBWPerState[i][0] = locals->ReturnBWToDCNPerState;
   3456 
   3457 		if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
   3458 			locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
   3459 					locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
   3460 					((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
   3461 					/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
   3462 					* locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
   3463 		}
   3464 		locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
   3465 				locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
   3466 				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
   3467 
   3468 		if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
   3469 			locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
   3470 				4 * locals->ReturnBWToDCNPerState *
   3471 				(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
   3472 				* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
   3473 				dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
   3474 				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
   3475 		}
   3476 
   3477 		locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth *
   3478 				locals->DCFCLKPerState[i], locals->FabricAndDRAMBandwidthPerState[i] * 1000);
   3479 
   3480 		if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
   3481 			locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
   3482 					locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
   3483 					((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
   3484 					/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
   3485 					* locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
   3486 		}
   3487 		locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
   3488 				locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
   3489 				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
   3490 
   3491 		if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
   3492 			locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
   3493 				4 * locals->ReturnBWToDCNPerState *
   3494 				(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
   3495 				* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
   3496 				dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
   3497 				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
   3498 		}
   3499 	}
   3500 	/*Writeback Latency support check*/
   3501 
   3502 	mode_lib->vba.WritebackLatencySupport = true;
   3503 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3504 		if (mode_lib->vba.WritebackEnable[k] == true) {
   3505 			if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
   3506 				if (locals->WriteBandwidth[k]
   3507 						> (mode_lib->vba.WritebackInterfaceLumaBufferSize
   3508 								+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
   3509 								/ mode_lib->vba.WritebackLatency) {
   3510 					mode_lib->vba.WritebackLatencySupport = false;
   3511 				}
   3512 			} else {
   3513 				if (locals->WriteBandwidth[k]
   3514 						> 1.5
   3515 								* dml_min(
   3516 										mode_lib->vba.WritebackInterfaceLumaBufferSize,
   3517 										2.0
   3518 												* mode_lib->vba.WritebackInterfaceChromaBufferSize)
   3519 								/ mode_lib->vba.WritebackLatency) {
   3520 					mode_lib->vba.WritebackLatencySupport = false;
   3521 				}
   3522 			}
   3523 		}
   3524 	}
   3525 	/*Re-ordering Buffer Support Check*/
   3526 
   3527 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   3528 		locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
   3529 				(mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
   3530 				+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i][0];
   3531 		if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i][0]
   3532 				> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
   3533 			locals->ROBSupport[i][0] = true;
   3534 		} else {
   3535 			locals->ROBSupport[i][0] = false;
   3536 		}
   3537 	}
   3538 	/*Writeback Mode Support Check*/
   3539 
   3540 	mode_lib->vba.TotalNumberOfActiveWriteback = 0;
   3541 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3542 		if (mode_lib->vba.WritebackEnable[k] == true) {
   3543 			if (mode_lib->vba.ActiveWritebacksPerPlane[k] == 0)
   3544 				mode_lib->vba.ActiveWritebacksPerPlane[k] = 1;
   3545 			mode_lib->vba.TotalNumberOfActiveWriteback =
   3546 					mode_lib->vba.TotalNumberOfActiveWriteback
   3547 							+ mode_lib->vba.ActiveWritebacksPerPlane[k];
   3548 		}
   3549 	}
   3550 	mode_lib->vba.WritebackModeSupport = true;
   3551 	if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
   3552 		mode_lib->vba.WritebackModeSupport = false;
   3553 	}
   3554 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3555 		if (mode_lib->vba.WritebackEnable[k] == true
   3556 				&& mode_lib->vba.Writeback10bpc420Supported != true
   3557 				&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
   3558 			mode_lib->vba.WritebackModeSupport = false;
   3559 		}
   3560 	}
   3561 	/*Writeback Scale Ratio and Taps Support Check*/
   3562 
   3563 	mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
   3564 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3565 		if (mode_lib->vba.WritebackEnable[k] == true) {
   3566 			if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
   3567 					&& (mode_lib->vba.WritebackHRatio[k] != 1.0
   3568 							|| mode_lib->vba.WritebackVRatio[k] != 1.0)) {
   3569 				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
   3570 			}
   3571 			if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
   3572 					|| mode_lib->vba.WritebackVRatio[k]
   3573 							> mode_lib->vba.WritebackMaxVSCLRatio
   3574 					|| mode_lib->vba.WritebackHRatio[k]
   3575 							< mode_lib->vba.WritebackMinHSCLRatio
   3576 					|| mode_lib->vba.WritebackVRatio[k]
   3577 							< mode_lib->vba.WritebackMinVSCLRatio
   3578 					|| mode_lib->vba.WritebackLumaHTaps[k]
   3579 							> mode_lib->vba.WritebackMaxHSCLTaps
   3580 					|| mode_lib->vba.WritebackLumaVTaps[k]
   3581 							> mode_lib->vba.WritebackMaxVSCLTaps
   3582 					|| mode_lib->vba.WritebackHRatio[k]
   3583 							> mode_lib->vba.WritebackLumaHTaps[k]
   3584 					|| mode_lib->vba.WritebackVRatio[k]
   3585 							> mode_lib->vba.WritebackLumaVTaps[k]
   3586 					|| (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
   3587 							&& ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
   3588 									== 1))
   3589 					|| (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
   3590 							&& (mode_lib->vba.WritebackChromaHTaps[k]
   3591 									> mode_lib->vba.WritebackMaxHSCLTaps
   3592 									|| mode_lib->vba.WritebackChromaVTaps[k]
   3593 											> mode_lib->vba.WritebackMaxVSCLTaps
   3594 									|| 2.0
   3595 											* mode_lib->vba.WritebackHRatio[k]
   3596 											> mode_lib->vba.WritebackChromaHTaps[k]
   3597 									|| 2.0
   3598 											* mode_lib->vba.WritebackVRatio[k]
   3599 											> mode_lib->vba.WritebackChromaVTaps[k]
   3600 									|| (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
   3601 										&& ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
   3602 				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
   3603 			}
   3604 			if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
   3605 				mode_lib->vba.WritebackLumaVExtra =
   3606 						dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
   3607 			} else {
   3608 				mode_lib->vba.WritebackLumaVExtra = -1;
   3609 			}
   3610 			if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
   3611 					&& mode_lib->vba.WritebackLumaVTaps[k]
   3612 							> (mode_lib->vba.WritebackLineBufferLumaBufferSize
   3613 									+ mode_lib->vba.WritebackLineBufferChromaBufferSize)
   3614 									/ 3.0
   3615 									/ mode_lib->vba.WritebackDestinationWidth[k]
   3616 									- mode_lib->vba.WritebackLumaVExtra)
   3617 					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
   3618 							&& mode_lib->vba.WritebackLumaVTaps[k]
   3619 									> mode_lib->vba.WritebackLineBufferLumaBufferSize
   3620 											* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
   3621 											- mode_lib->vba.WritebackLumaVExtra)
   3622 					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
   3623 							&& mode_lib->vba.WritebackLumaVTaps[k]
   3624 									> mode_lib->vba.WritebackLineBufferLumaBufferSize
   3625 											* 8.0 / 10.0
   3626 											/ mode_lib->vba.WritebackDestinationWidth[k]
   3627 											- mode_lib->vba.WritebackLumaVExtra)) {
   3628 				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
   3629 			}
   3630 			if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
   3631 				mode_lib->vba.WritebackChromaVExtra = 0.0;
   3632 			} else {
   3633 				mode_lib->vba.WritebackChromaVExtra = -1;
   3634 			}
   3635 			if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
   3636 					&& mode_lib->vba.WritebackChromaVTaps[k]
   3637 							> mode_lib->vba.WritebackLineBufferChromaBufferSize
   3638 									* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
   3639 									- mode_lib->vba.WritebackChromaVExtra)
   3640 					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
   3641 							&& mode_lib->vba.WritebackChromaVTaps[k]
   3642 									> mode_lib->vba.WritebackLineBufferChromaBufferSize
   3643 											* 8.0 / 10.0
   3644 											/ mode_lib->vba.WritebackDestinationWidth[k]
   3645 											- mode_lib->vba.WritebackChromaVExtra)) {
   3646 				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
   3647 			}
   3648 		}
   3649 	}
   3650 	/*Maximum DISPCLK/DPPCLK Support check*/
   3651 
   3652 	mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
   3653 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3654 		if (mode_lib->vba.WritebackEnable[k] == true) {
   3655 			mode_lib->vba.WritebackRequiredDISPCLK =
   3656 					dml_max(
   3657 							mode_lib->vba.WritebackRequiredDISPCLK,
   3658 							CalculateWriteBackDISPCLK(
   3659 									mode_lib->vba.WritebackPixelFormat[k],
   3660 									mode_lib->vba.PixelClock[k],
   3661 									mode_lib->vba.WritebackHRatio[k],
   3662 									mode_lib->vba.WritebackVRatio[k],
   3663 									mode_lib->vba.WritebackLumaHTaps[k],
   3664 									mode_lib->vba.WritebackLumaVTaps[k],
   3665 									mode_lib->vba.WritebackChromaHTaps[k],
   3666 									mode_lib->vba.WritebackChromaVTaps[k],
   3667 									mode_lib->vba.WritebackDestinationWidth[k],
   3668 									mode_lib->vba.HTotal[k],
   3669 									mode_lib->vba.WritebackChromaLineBufferWidth));
   3670 		}
   3671 	}
   3672 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3673 		if (mode_lib->vba.HRatio[k] > 1.0) {
   3674 			locals->PSCL_FACTOR[k] = dml_min(
   3675 					mode_lib->vba.MaxDCHUBToPSCLThroughput,
   3676 					mode_lib->vba.MaxPSCLToLBThroughput
   3677 							* mode_lib->vba.HRatio[k]
   3678 							/ dml_ceil(
   3679 									mode_lib->vba.htaps[k]
   3680 											/ 6.0,
   3681 									1.0));
   3682 		} else {
   3683 			locals->PSCL_FACTOR[k] = dml_min(
   3684 					mode_lib->vba.MaxDCHUBToPSCLThroughput,
   3685 					mode_lib->vba.MaxPSCLToLBThroughput);
   3686 		}
   3687 		if (locals->BytePerPixelInDETC[k] == 0.0) {
   3688 			locals->PSCL_FACTOR_CHROMA[k] = 0.0;
   3689 			locals->MinDPPCLKUsingSingleDPP[k] =
   3690 					mode_lib->vba.PixelClock[k]
   3691 							* dml_max3(
   3692 									mode_lib->vba.vtaps[k] / 6.0
   3693 											* dml_min(
   3694 													1.0,
   3695 													mode_lib->vba.HRatio[k]),
   3696 									mode_lib->vba.HRatio[k]
   3697 											* mode_lib->vba.VRatio[k]
   3698 											/ locals->PSCL_FACTOR[k],
   3699 									1.0);
   3700 			if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
   3701 					&& locals->MinDPPCLKUsingSingleDPP[k]
   3702 							< 2.0 * mode_lib->vba.PixelClock[k]) {
   3703 				locals->MinDPPCLKUsingSingleDPP[k] = 2.0
   3704 						* mode_lib->vba.PixelClock[k];
   3705 			}
   3706 		} else {
   3707 			if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
   3708 				locals->PSCL_FACTOR_CHROMA[k] =
   3709 						dml_min(
   3710 								mode_lib->vba.MaxDCHUBToPSCLThroughput,
   3711 								mode_lib->vba.MaxPSCLToLBThroughput
   3712 										* mode_lib->vba.HRatio[k]
   3713 										/ 2.0
   3714 										/ dml_ceil(
   3715 												mode_lib->vba.HTAPsChroma[k]
   3716 														/ 6.0,
   3717 												1.0));
   3718 			} else {
   3719 				locals->PSCL_FACTOR_CHROMA[k] = dml_min(
   3720 						mode_lib->vba.MaxDCHUBToPSCLThroughput,
   3721 						mode_lib->vba.MaxPSCLToLBThroughput);
   3722 			}
   3723 			locals->MinDPPCLKUsingSingleDPP[k] =
   3724 					mode_lib->vba.PixelClock[k]
   3725 							* dml_max5(
   3726 									mode_lib->vba.vtaps[k] / 6.0
   3727 											* dml_min(
   3728 													1.0,
   3729 													mode_lib->vba.HRatio[k]),
   3730 									mode_lib->vba.HRatio[k]
   3731 											* mode_lib->vba.VRatio[k]
   3732 											/ locals->PSCL_FACTOR[k],
   3733 									mode_lib->vba.VTAPsChroma[k]
   3734 											/ 6.0
   3735 											* dml_min(
   3736 													1.0,
   3737 													mode_lib->vba.HRatio[k]
   3738 															/ 2.0),
   3739 									mode_lib->vba.HRatio[k]
   3740 											* mode_lib->vba.VRatio[k]
   3741 											/ 4.0
   3742 											/ locals->PSCL_FACTOR_CHROMA[k],
   3743 									1.0);
   3744 			if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
   3745 					|| mode_lib->vba.HTAPsChroma[k] > 6.0
   3746 					|| mode_lib->vba.VTAPsChroma[k] > 6.0)
   3747 					&& locals->MinDPPCLKUsingSingleDPP[k]
   3748 							< 2.0 * mode_lib->vba.PixelClock[k]) {
   3749 				locals->MinDPPCLKUsingSingleDPP[k] = 2.0
   3750 						* mode_lib->vba.PixelClock[k];
   3751 			}
   3752 		}
   3753 	}
   3754 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3755 		Calculate256BBlockSizes(
   3756 				mode_lib->vba.SourcePixelFormat[k],
   3757 				mode_lib->vba.SurfaceTiling[k],
   3758 				dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
   3759 				dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
   3760 				&locals->Read256BlockHeightY[k],
   3761 				&locals->Read256BlockHeightC[k],
   3762 				&locals->Read256BlockWidthY[k],
   3763 				&locals->Read256BlockWidthC[k]);
   3764 		if (mode_lib->vba.SourceScan[k] == dm_horz) {
   3765 			locals->MaxSwathHeightY[k] = locals->Read256BlockHeightY[k];
   3766 			locals->MaxSwathHeightC[k] = locals->Read256BlockHeightC[k];
   3767 		} else {
   3768 			locals->MaxSwathHeightY[k] = locals->Read256BlockWidthY[k];
   3769 			locals->MaxSwathHeightC[k] = locals->Read256BlockWidthC[k];
   3770 		}
   3771 		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
   3772 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
   3773 				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
   3774 				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
   3775 				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
   3776 			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
   3777 					|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
   3778 							&& (mode_lib->vba.SurfaceTiling[k]
   3779 									== dm_sw_4kb_s
   3780 									|| mode_lib->vba.SurfaceTiling[k]
   3781 											== dm_sw_4kb_s_x
   3782 									|| mode_lib->vba.SurfaceTiling[k]
   3783 											== dm_sw_64kb_s
   3784 									|| mode_lib->vba.SurfaceTiling[k]
   3785 											== dm_sw_64kb_s_t
   3786 									|| mode_lib->vba.SurfaceTiling[k]
   3787 											== dm_sw_64kb_s_x
   3788 									|| mode_lib->vba.SurfaceTiling[k]
   3789 											== dm_sw_var_s
   3790 									|| mode_lib->vba.SurfaceTiling[k]
   3791 											== dm_sw_var_s_x)
   3792 							&& mode_lib->vba.SourceScan[k] == dm_horz)) {
   3793 				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
   3794 			} else {
   3795 				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
   3796 						/ 2.0;
   3797 			}
   3798 			locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
   3799 		} else {
   3800 			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
   3801 				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
   3802 				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
   3803 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
   3804 					&& mode_lib->vba.SourceScan[k] == dm_horz) {
   3805 				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
   3806 						/ 2.0;
   3807 				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
   3808 			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
   3809 					&& mode_lib->vba.SourceScan[k] == dm_horz) {
   3810 				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k]
   3811 						/ 2.0;
   3812 				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
   3813 			} else {
   3814 				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
   3815 				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
   3816 			}
   3817 		}
   3818 		if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
   3819 			mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
   3820 		} else {
   3821 			mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
   3822 		}
   3823 		mode_lib->vba.MaximumSwathWidthInDETBuffer =
   3824 				dml_min(
   3825 						mode_lib->vba.MaximumSwathWidthSupport,
   3826 						mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
   3827 								/ (locals->BytePerPixelInDETY[k]
   3828 										* locals->MinSwathHeightY[k]
   3829 										+ locals->BytePerPixelInDETC[k]
   3830 												/ 2.0
   3831 												* locals->MinSwathHeightC[k]));
   3832 		if (locals->BytePerPixelInDETC[k] == 0.0) {
   3833 			mode_lib->vba.MaximumSwathWidthInLineBuffer =
   3834 					mode_lib->vba.LineBufferSize
   3835 							* dml_max(mode_lib->vba.HRatio[k], 1.0)
   3836 							/ mode_lib->vba.LBBitPerPixel[k]
   3837 							/ (mode_lib->vba.vtaps[k]
   3838 									+ dml_max(
   3839 											dml_ceil(
   3840 													mode_lib->vba.VRatio[k],
   3841 													1.0)
   3842 													- 2,
   3843 											0.0));
   3844 		} else {
   3845 			mode_lib->vba.MaximumSwathWidthInLineBuffer =
   3846 					dml_min(
   3847 							mode_lib->vba.LineBufferSize
   3848 									* dml_max(
   3849 											mode_lib->vba.HRatio[k],
   3850 											1.0)
   3851 									/ mode_lib->vba.LBBitPerPixel[k]
   3852 									/ (mode_lib->vba.vtaps[k]
   3853 											+ dml_max(
   3854 													dml_ceil(
   3855 															mode_lib->vba.VRatio[k],
   3856 															1.0)
   3857 															- 2,
   3858 													0.0)),
   3859 							2.0 * mode_lib->vba.LineBufferSize
   3860 									* dml_max(
   3861 											mode_lib->vba.HRatio[k]
   3862 													/ 2.0,
   3863 											1.0)
   3864 									/ mode_lib->vba.LBBitPerPixel[k]
   3865 									/ (mode_lib->vba.VTAPsChroma[k]
   3866 											+ dml_max(
   3867 													dml_ceil(
   3868 															mode_lib->vba.VRatio[k]
   3869 																	/ 2.0,
   3870 															1.0)
   3871 															- 2,
   3872 													0.0)));
   3873 		}
   3874 		locals->MaximumSwathWidth[k] = dml_min(
   3875 				mode_lib->vba.MaximumSwathWidthInDETBuffer,
   3876 				mode_lib->vba.MaximumSwathWidthInLineBuffer);
   3877 	}
   3878 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   3879 		for (j = 0; j < 2; j++) {
   3880 			mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
   3881 				mode_lib->vba.MaxDispclk[i],
   3882 				mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
   3883 			mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
   3884 				mode_lib->vba.MaxDppclk[i],
   3885 				mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
   3886 			locals->RequiredDISPCLK[i][j] = 0.0;
   3887 			locals->DISPCLK_DPPCLK_Support[i][j] = true;
   3888 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3889 				mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
   3890 						mode_lib->vba.PixelClock[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
   3891 								* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
   3892 				if (mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine >= mode_lib->vba.MaxDispclk[i]
   3893 						&& i == mode_lib->vba.soc.num_states)
   3894 					mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = mode_lib->vba.PixelClock[k]
   3895 							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
   3896 
   3897 				mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
   3898 					* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
   3899 				if (mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine >= mode_lib->vba.MaxDispclk[i]
   3900 						&& i == mode_lib->vba.soc.num_states)
   3901 					mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
   3902 							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
   3903 
   3904 				locals->ODMCombineEnablePerState[i][k] = false;
   3905 				mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
   3906 				if (mode_lib->vba.ODMCapability) {
   3907 					if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
   3908 						locals->ODMCombineEnablePerState[i][k] = true;
   3909 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
   3910 					} else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
   3911 						locals->ODMCombineEnablePerState[i][k] = true;
   3912 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
   3913 					}
   3914 				}
   3915 
   3916 				if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
   3917 						&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
   3918 						&& locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
   3919 					locals->NoOfDPP[i][j][k] = 1;
   3920 					locals->RequiredDPPCLK[i][j][k] =
   3921 						locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
   3922 				} else {
   3923 					locals->NoOfDPP[i][j][k] = 2;
   3924 					locals->RequiredDPPCLK[i][j][k] =
   3925 						locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
   3926 				}
   3927 				locals->RequiredDISPCLK[i][j] = dml_max(
   3928 						locals->RequiredDISPCLK[i][j],
   3929 						mode_lib->vba.PlaneRequiredDISPCLK);
   3930 				if ((locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
   3931 						> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
   3932 						|| (mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
   3933 					locals->DISPCLK_DPPCLK_Support[i][j] = false;
   3934 				}
   3935 			}
   3936 			locals->TotalNumberOfActiveDPP[i][j] = 0.0;
   3937 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
   3938 				locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
   3939 			if (j == 1) {
   3940 				while (locals->TotalNumberOfActiveDPP[i][j] < mode_lib->vba.MaxNumDPP
   3941 						&& locals->TotalNumberOfActiveDPP[i][j] < 2 * mode_lib->vba.NumberOfActivePlanes) {
   3942 					double BWOfNonSplitPlaneOfMaximumBandwidth;
   3943 					unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
   3944 
   3945 					BWOfNonSplitPlaneOfMaximumBandwidth = 0;
   3946 					NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
   3947 					for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
   3948 						if (locals->ReadBandwidth[k] > BWOfNonSplitPlaneOfMaximumBandwidth && locals->NoOfDPP[i][j][k] == 1) {
   3949 							BWOfNonSplitPlaneOfMaximumBandwidth = locals->ReadBandwidth[k];
   3950 							NumberOfNonSplitPlaneOfMaximumBandwidth = k;
   3951 						}
   3952 					}
   3953 					locals->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
   3954 					locals->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
   3955 						locals->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
   3956 							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
   3957 					locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + 1;
   3958 				}
   3959 			}
   3960 			if (locals->TotalNumberOfActiveDPP[i][j] > mode_lib->vba.MaxNumDPP) {
   3961 				locals->RequiredDISPCLK[i][j] = 0.0;
   3962 				locals->DISPCLK_DPPCLK_Support[i][j] = true;
   3963 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   3964 					locals->ODMCombineEnablePerState[i][k] = false;
   3965 					if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
   3966 						locals->NoOfDPP[i][j][k] = 1;
   3967 						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
   3968 							* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
   3969 					} else {
   3970 						locals->NoOfDPP[i][j][k] = 2;
   3971 						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
   3972 										* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
   3973 					}
   3974 					if (i != mode_lib->vba.soc.num_states) {
   3975 						mode_lib->vba.PlaneRequiredDISPCLK =
   3976 								mode_lib->vba.PixelClock[k]
   3977 										* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
   3978 										* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
   3979 					} else {
   3980 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PixelClock[k]
   3981 							* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
   3982 					}
   3983 					locals->RequiredDISPCLK[i][j] = dml_max(
   3984 							locals->RequiredDISPCLK[i][j],
   3985 							mode_lib->vba.PlaneRequiredDISPCLK);
   3986 					if (locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
   3987 							> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
   3988 							|| mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)
   3989 						locals->DISPCLK_DPPCLK_Support[i][j] = false;
   3990 				}
   3991 				locals->TotalNumberOfActiveDPP[i][j] = 0.0;
   3992 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
   3993 					locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
   3994 			}
   3995 			locals->RequiredDISPCLK[i][j] = dml_max(
   3996 					locals->RequiredDISPCLK[i][j],
   3997 					mode_lib->vba.WritebackRequiredDISPCLK);
   3998 			if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
   3999 					< mode_lib->vba.WritebackRequiredDISPCLK) {
   4000 				locals->DISPCLK_DPPCLK_Support[i][j] = false;
   4001 			}
   4002 		}
   4003 	}
   4004 	/*Viewport Size Check*/
   4005 
   4006 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4007 		locals->ViewportSizeSupport[i][0] = true;
   4008 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4009 			if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
   4010 				if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
   4011 						> locals->MaximumSwathWidth[k]) {
   4012 					locals->ViewportSizeSupport[i][0] = false;
   4013 				}
   4014 			} else {
   4015 				if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
   4016 					locals->ViewportSizeSupport[i][0] = false;
   4017 				}
   4018 			}
   4019 		}
   4020 	}
   4021 	/*Total Available Pipes Support Check*/
   4022 
   4023 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4024 		for (j = 0; j < 2; j++) {
   4025 			if (locals->TotalNumberOfActiveDPP[i][j] <= mode_lib->vba.MaxNumDPP)
   4026 				locals->TotalAvailablePipesSupport[i][j] = true;
   4027 			else
   4028 				locals->TotalAvailablePipesSupport[i][j] = false;
   4029 		}
   4030 	}
   4031 	/*Total Available OTG Support Check*/
   4032 
   4033 	mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
   4034 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4035 		if (mode_lib->vba.BlendingAndTiming[k] == k) {
   4036 			mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
   4037 					+ 1.0;
   4038 		}
   4039 	}
   4040 	if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
   4041 		mode_lib->vba.NumberOfOTGSupport = true;
   4042 	} else {
   4043 		mode_lib->vba.NumberOfOTGSupport = false;
   4044 	}
   4045 	/*Display IO and DSC Support Check*/
   4046 
   4047 	mode_lib->vba.NonsupportedDSCInputBPC = false;
   4048 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4049 		if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
   4050 				|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
   4051 				|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
   4052 			mode_lib->vba.NonsupportedDSCInputBPC = true;
   4053 		}
   4054 	}
   4055 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4056 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4057 			locals->RequiresDSC[i][k] = 0;
   4058 			locals->RequiresFEC[i][k] = 0;
   4059 			if (mode_lib->vba.BlendingAndTiming[k] == k) {
   4060 				if (mode_lib->vba.Output[k] == dm_hdmi) {
   4061 					locals->RequiresDSC[i][k] = 0;
   4062 					locals->RequiresFEC[i][k] = 0;
   4063 					locals->OutputBppPerState[i][k] = TruncToValidBPP(
   4064 							dml_min(600.0, mode_lib->vba.PHYCLKPerState[i]) / mode_lib->vba.PixelClockBackEnd[k] * 24,
   4065 							false,
   4066 							mode_lib->vba.Output[k],
   4067 							mode_lib->vba.OutputFormat[k],
   4068 							mode_lib->vba.DSCInputBitPerComponent[k]);
   4069 				} else if (mode_lib->vba.Output[k] == dm_dp
   4070 						|| mode_lib->vba.Output[k] == dm_edp) {
   4071 					if (mode_lib->vba.Output[k] == dm_edp) {
   4072 						mode_lib->vba.EffectiveFECOverhead = 0.0;
   4073 					} else {
   4074 						mode_lib->vba.EffectiveFECOverhead =
   4075 								mode_lib->vba.FECOverhead;
   4076 					}
   4077 					if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
   4078 						mode_lib->vba.Outbpp = TruncToValidBPP(
   4079 								(1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0
   4080 								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
   4081 								false,
   4082 								mode_lib->vba.Output[k],
   4083 								mode_lib->vba.OutputFormat[k],
   4084 								mode_lib->vba.DSCInputBitPerComponent[k]);
   4085 						mode_lib->vba.OutbppDSC = TruncToValidBPP(
   4086 								(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0
   4087 								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
   4088 								true,
   4089 								mode_lib->vba.Output[k],
   4090 								mode_lib->vba.OutputFormat[k],
   4091 								mode_lib->vba.DSCInputBitPerComponent[k]);
   4092 						if (mode_lib->vba.DSCEnabled[k] == true) {
   4093 							locals->RequiresDSC[i][k] = true;
   4094 							if (mode_lib->vba.Output[k] == dm_dp) {
   4095 								locals->RequiresFEC[i][k] = true;
   4096 							} else {
   4097 								locals->RequiresFEC[i][k] = false;
   4098 							}
   4099 							mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
   4100 						} else {
   4101 							locals->RequiresDSC[i][k] = false;
   4102 							locals->RequiresFEC[i][k] = false;
   4103 						}
   4104 						locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
   4105 					}
   4106 					if (mode_lib->vba.Outbpp == BPP_INVALID && mode_lib->vba.PHYCLKPerState[i] >= 540.0) {
   4107 						mode_lib->vba.Outbpp = TruncToValidBPP(
   4108 								(1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0
   4109 								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
   4110 									false,
   4111 									mode_lib->vba.Output[k],
   4112 									mode_lib->vba.OutputFormat[k],
   4113 									mode_lib->vba.DSCInputBitPerComponent[k]);
   4114 						mode_lib->vba.OutbppDSC = TruncToValidBPP(
   4115 								(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0
   4116 								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
   4117 								true,
   4118 								mode_lib->vba.Output[k],
   4119 								mode_lib->vba.OutputFormat[k],
   4120 								mode_lib->vba.DSCInputBitPerComponent[k]);
   4121 						if (mode_lib->vba.DSCEnabled[k] == true) {
   4122 							locals->RequiresDSC[i][k] = true;
   4123 							if (mode_lib->vba.Output[k] == dm_dp) {
   4124 								locals->RequiresFEC[i][k] = true;
   4125 							} else {
   4126 								locals->RequiresFEC[i][k] = false;
   4127 							}
   4128 							mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
   4129 						} else {
   4130 							locals->RequiresDSC[i][k] = false;
   4131 							locals->RequiresFEC[i][k] = false;
   4132 						}
   4133 						locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
   4134 					}
   4135 					if (mode_lib->vba.Outbpp == BPP_INVALID
   4136 							&& mode_lib->vba.PHYCLKPerState[i]
   4137 									>= 810.0) {
   4138 						mode_lib->vba.Outbpp = TruncToValidBPP(
   4139 								(1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
   4140 								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
   4141 								false,
   4142 								mode_lib->vba.Output[k],
   4143 								mode_lib->vba.OutputFormat[k],
   4144 								mode_lib->vba.DSCInputBitPerComponent[k]);
   4145 						mode_lib->vba.OutbppDSC = TruncToValidBPP(
   4146 								(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
   4147 								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
   4148 								true,
   4149 								mode_lib->vba.Output[k],
   4150 								mode_lib->vba.OutputFormat[k],
   4151 								mode_lib->vba.DSCInputBitPerComponent[k]);
   4152 						if (mode_lib->vba.DSCEnabled[k] == true || mode_lib->vba.Outbpp == BPP_INVALID) {
   4153 							locals->RequiresDSC[i][k] = true;
   4154 							if (mode_lib->vba.Output[k] == dm_dp) {
   4155 								locals->RequiresFEC[i][k] = true;
   4156 							} else {
   4157 								locals->RequiresFEC[i][k] = false;
   4158 							}
   4159 							mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
   4160 						} else {
   4161 							locals->RequiresDSC[i][k] = false;
   4162 							locals->RequiresFEC[i][k] = false;
   4163 						}
   4164 						locals->OutputBppPerState[i][k] =
   4165 								mode_lib->vba.Outbpp;
   4166 					}
   4167 				}
   4168 			} else {
   4169 				locals->OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
   4170 			}
   4171 		}
   4172 	}
   4173 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4174 		locals->DIOSupport[i] = true;
   4175 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4176 			if (locals->OutputBppPerState[i][k] == BPP_INVALID
   4177 					|| (mode_lib->vba.OutputFormat[k] == dm_420
   4178 							&& mode_lib->vba.Interlace[k] == true
   4179 							&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) {
   4180 				locals->DIOSupport[i] = false;
   4181 			}
   4182 		}
   4183 	}
   4184 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4185 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4186 			locals->DSCCLKRequiredMoreThanSupported[i] = false;
   4187 			if (mode_lib->vba.BlendingAndTiming[k] == k) {
   4188 				if ((mode_lib->vba.Output[k] == dm_dp
   4189 						|| mode_lib->vba.Output[k] == dm_edp)) {
   4190 					if (mode_lib->vba.OutputFormat[k] == dm_420
   4191 							|| mode_lib->vba.OutputFormat[k]
   4192 									== dm_n422) {
   4193 						mode_lib->vba.DSCFormatFactor = 2;
   4194 					} else {
   4195 						mode_lib->vba.DSCFormatFactor = 1;
   4196 					}
   4197 					if (locals->RequiresDSC[i][k] == true) {
   4198 						if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
   4199 							if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
   4200 									> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
   4201 								locals->DSCCLKRequiredMoreThanSupported[i] =
   4202 										true;
   4203 							}
   4204 						} else {
   4205 							if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 / mode_lib->vba.DSCFormatFactor
   4206 									> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
   4207 								locals->DSCCLKRequiredMoreThanSupported[i] =
   4208 										true;
   4209 							}
   4210 						}
   4211 					}
   4212 				}
   4213 			}
   4214 		}
   4215 	}
   4216 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4217 		locals->NotEnoughDSCUnits[i] = false;
   4218 		mode_lib->vba.TotalDSCUnitsRequired = 0.0;
   4219 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4220 			if (locals->RequiresDSC[i][k] == true) {
   4221 				if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
   4222 					mode_lib->vba.TotalDSCUnitsRequired =
   4223 							mode_lib->vba.TotalDSCUnitsRequired + 2.0;
   4224 				} else {
   4225 					mode_lib->vba.TotalDSCUnitsRequired =
   4226 							mode_lib->vba.TotalDSCUnitsRequired + 1.0;
   4227 				}
   4228 			}
   4229 		}
   4230 		if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
   4231 			locals->NotEnoughDSCUnits[i] = true;
   4232 		}
   4233 	}
   4234 	/*DSC Delay per state*/
   4235 
   4236 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4237 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4238 			if (mode_lib->vba.BlendingAndTiming[k] != k) {
   4239 				mode_lib->vba.slices = 0;
   4240 			} else if (locals->RequiresDSC[i][k] == 0
   4241 					|| locals->RequiresDSC[i][k] == false) {
   4242 				mode_lib->vba.slices = 0;
   4243 			} else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
   4244 				mode_lib->vba.slices = dml_ceil(
   4245 						mode_lib->vba.PixelClockBackEnd[k] / 400.0,
   4246 						4.0);
   4247 			} else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
   4248 				mode_lib->vba.slices = 8.0;
   4249 			} else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
   4250 				mode_lib->vba.slices = 4.0;
   4251 			} else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
   4252 				mode_lib->vba.slices = 2.0;
   4253 			} else {
   4254 				mode_lib->vba.slices = 1.0;
   4255 			}
   4256 			if (locals->OutputBppPerState[i][k] == BPP_BLENDED_PIPE
   4257 					|| locals->OutputBppPerState[i][k] == BPP_INVALID) {
   4258 				mode_lib->vba.bpp = 0.0;
   4259 			} else {
   4260 				mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
   4261 			}
   4262 			if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
   4263 				if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
   4264 					locals->DSCDelayPerState[i][k] =
   4265 							dscceComputeDelay(
   4266 									mode_lib->vba.DSCInputBitPerComponent[k],
   4267 									mode_lib->vba.bpp,
   4268 									dml_ceil(
   4269 											mode_lib->vba.HActive[k]
   4270 													/ mode_lib->vba.slices,
   4271 											1.0),
   4272 									mode_lib->vba.slices,
   4273 									mode_lib->vba.OutputFormat[k])
   4274 									+ dscComputeDelay(
   4275 											mode_lib->vba.OutputFormat[k]);
   4276 				} else {
   4277 					locals->DSCDelayPerState[i][k] =
   4278 							2.0 * (dscceComputeDelay(
   4279 											mode_lib->vba.DSCInputBitPerComponent[k],
   4280 											mode_lib->vba.bpp,
   4281 											dml_ceil(mode_lib->vba.HActive[k] / mode_lib->vba.slices, 1.0),
   4282 											mode_lib->vba.slices / 2,
   4283 											mode_lib->vba.OutputFormat[k])
   4284 									+ dscComputeDelay(mode_lib->vba.OutputFormat[k]));
   4285 				}
   4286 				locals->DSCDelayPerState[i][k] =
   4287 						locals->DSCDelayPerState[i][k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k];
   4288 			} else {
   4289 				locals->DSCDelayPerState[i][k] = 0.0;
   4290 			}
   4291 		}
   4292 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4293 			for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
   4294 				for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
   4295 					if (mode_lib->vba.BlendingAndTiming[k] == m && locals->RequiresDSC[i][m] == true)
   4296 						locals->DSCDelayPerState[i][k] = locals->DSCDelayPerState[i][m];
   4297 				}
   4298 			}
   4299 		}
   4300 	}
   4301 
   4302 	//Prefetch Check
   4303 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4304 		for (j = 0; j < 2; j++) {
   4305 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4306 				if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1)
   4307 					locals->SwathWidthYPerState[i][j][k] = dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
   4308 				else
   4309 					locals->SwathWidthYPerState[i][j][k] = locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
   4310 				locals->SwathWidthGranularityY = 256  / dml_ceil(locals->BytePerPixelInDETY[k], 1) / locals->MaxSwathHeightY[k];
   4311 				locals->RoundedUpMaxSwathSizeBytesY = (dml_ceil(locals->SwathWidthYPerState[i][j][k] - 1, locals->SwathWidthGranularityY)
   4312 						+ locals->SwathWidthGranularityY) * locals->BytePerPixelInDETY[k] * locals->MaxSwathHeightY[k];
   4313 				if (locals->SourcePixelFormat[k] == dm_420_10) {
   4314 					locals->RoundedUpMaxSwathSizeBytesY = dml_ceil(locals->RoundedUpMaxSwathSizeBytesY, 256) + 256;
   4315 				}
   4316 				if (locals->MaxSwathHeightC[k] > 0) {
   4317 					locals->SwathWidthGranularityC = 256 / dml_ceil(locals->BytePerPixelInDETC[k], 2) / locals->MaxSwathHeightC[k];
   4318 
   4319 					locals->RoundedUpMaxSwathSizeBytesC = (dml_ceil(locals->SwathWidthYPerState[i][j][k] / 2 - 1, locals->SwathWidthGranularityC)
   4320 					+ locals->SwathWidthGranularityC) * locals->BytePerPixelInDETC[k] * locals->MaxSwathHeightC[k];
   4321 				}
   4322 				if (locals->SourcePixelFormat[k] == dm_420_10) {
   4323 					locals->RoundedUpMaxSwathSizeBytesC = dml_ceil(locals->RoundedUpMaxSwathSizeBytesC, 256)  + 256;
   4324 				} else {
   4325 					locals->RoundedUpMaxSwathSizeBytesC = 0;
   4326 				}
   4327 
   4328 				if (locals->RoundedUpMaxSwathSizeBytesY + locals->RoundedUpMaxSwathSizeBytesC <= locals->DETBufferSizeInKByte * 1024 / 2) {
   4329 					locals->SwathHeightYPerState[i][j][k] = locals->MaxSwathHeightY[k];
   4330 					locals->SwathHeightCPerState[i][j][k] = locals->MaxSwathHeightC[k];
   4331 				} else {
   4332 					locals->SwathHeightYPerState[i][j][k] = locals->MinSwathHeightY[k];
   4333 					locals->SwathHeightCPerState[i][j][k] = locals->MinSwathHeightC[k];
   4334 				}
   4335 
   4336 				if (locals->BytePerPixelInDETC[k] == 0) {
   4337 					locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
   4338 					locals->LinesInDETChroma = 0;
   4339 				} else if (locals->SwathHeightYPerState[i][j][k] <= locals->SwathHeightCPerState[i][j][k]) {
   4340 					locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 / 2 / locals->BytePerPixelInDETY[k] /
   4341 							locals->SwathWidthYPerState[i][j][k];
   4342 					locals->LinesInDETChroma = locals->DETBufferSizeInKByte * 1024 / 2 / locals->BytePerPixelInDETC[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
   4343 				} else {
   4344 					locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 * 2 / 3 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
   4345 					locals->LinesInDETChroma = locals->DETBufferSizeInKByte * 1024 / 3 / locals->BytePerPixelInDETY[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
   4346 				}
   4347 
   4348 				locals->EffectiveLBLatencyHidingSourceLinesLuma = dml_min(locals->MaxLineBufferLines,
   4349 					dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k] / (locals->SwathWidthYPerState[i][j][k]
   4350 					/ dml_max(locals->HRatio[k], 1)), 1)) - (locals->vtaps[k] - 1);
   4351 
   4352 				locals->EffectiveLBLatencyHidingSourceLinesChroma =  dml_min(locals->MaxLineBufferLines,
   4353 						dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k]
   4354 						/ (locals->SwathWidthYPerState[i][j][k] / 2
   4355 						/ dml_max(locals->HRatio[k] / 2, 1)), 1)) - (locals->VTAPsChroma[k] - 1);
   4356 
   4357 				locals->EffectiveDETLBLinesLuma = dml_floor(locals->LinesInDETLuma +  dml_min(
   4358 						locals->LinesInDETLuma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETY[k] *
   4359 						locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i][0],
   4360 						locals->EffectiveLBLatencyHidingSourceLinesLuma),
   4361 						locals->SwathHeightYPerState[i][j][k]);
   4362 
   4363 				locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min(
   4364 						locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] *
   4365 						locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i][0],
   4366 						locals->EffectiveLBLatencyHidingSourceLinesChroma),
   4367 						locals->SwathHeightCPerState[i][j][k]);
   4368 
   4369 				if (locals->BytePerPixelInDETC[k] == 0) {
   4370 					locals->UrgentLatencySupportUsPerState[i][j][k] = locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
   4371 							/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
   4372 								dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]);
   4373 				} else {
   4374 					locals->UrgentLatencySupportUsPerState[i][j][k] = dml_min(
   4375 						locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
   4376 						/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
   4377 						dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]),
   4378 							locals->EffectiveDETLBLinesChroma * (locals->HTotal[k] / locals->PixelClock[k]) / (locals->VRatio[k] / 2) -
   4379 							locals->EffectiveDETLBLinesChroma * locals->SwathWidthYPerState[i][j][k] / 2 *
   4380 							dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]));
   4381 				}
   4382 			}
   4383 		}
   4384 	}
   4385 
   4386 	for (i = 0; i <= locals->soc.num_states; i++) {
   4387 		for (j = 0; j < 2; j++) {
   4388 			locals->UrgentLatencySupport[i][j] = true;
   4389 			for (k = 0; k < locals->NumberOfActivePlanes; k++) {
   4390 				if (locals->UrgentLatencySupportUsPerState[i][j][k] < locals->UrgentLatency)
   4391 					locals->UrgentLatencySupport[i][j] = false;
   4392 			}
   4393 		}
   4394 	}
   4395 
   4396 
   4397 	/*Prefetch Check*/
   4398 	for (i = 0; i <= locals->soc.num_states; i++) {
   4399 		for (j = 0; j < 2; j++) {
   4400 			locals->TotalNumberOfDCCActiveDPP[i][j] = 0;
   4401 			for (k = 0; k < locals->NumberOfActivePlanes; k++) {
   4402 				if (locals->DCCEnable[k] == true) {
   4403 					locals->TotalNumberOfDCCActiveDPP[i][j] =
   4404 						locals->TotalNumberOfDCCActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
   4405 				}
   4406 			}
   4407 		}
   4408 	}
   4409 
   4410 	CalculateMinAndMaxPrefetchMode(locals->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &locals->MinPrefetchMode, &locals->MaxPrefetchMode);
   4411 
   4412 	for (i = 0; i <= locals->soc.num_states; i++) {
   4413 		for (j = 0; j < 2; j++) {
   4414 			for (k = 0; k < locals->NumberOfActivePlanes; k++) {
   4415 				locals->NoOfDPPThisState[k] = locals->NoOfDPP[i][j][k];
   4416 				locals->RequiredDPPCLKThisState[k] = locals->RequiredDPPCLK[i][j][k];
   4417 				locals->SwathHeightYThisState[k] = locals->SwathHeightYPerState[i][j][k];
   4418 				locals->SwathHeightCThisState[k] = locals->SwathHeightCPerState[i][j][k];
   4419 				locals->SwathWidthYThisState[k] = locals->SwathWidthYPerState[i][j][k];
   4420 				mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] = dml_max(
   4421 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4422 						mode_lib->vba.PixelClock[k] / 16.0);
   4423 				if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
   4424 					if (mode_lib->vba.VRatio[k] <= 1.0) {
   4425 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
   4426 								dml_max(
   4427 										mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4428 										1.1
   4429 												* dml_ceil(
   4430 														mode_lib->vba.BytePerPixelInDETY[k],
   4431 														1.0)
   4432 												/ 64.0
   4433 												* mode_lib->vba.HRatio[k]
   4434 												* mode_lib->vba.PixelClock[k]
   4435 												/ mode_lib->vba.NoOfDPP[i][j][k]);
   4436 					} else {
   4437 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
   4438 								dml_max(
   4439 										mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4440 										1.1
   4441 												* dml_ceil(
   4442 														mode_lib->vba.BytePerPixelInDETY[k],
   4443 														1.0)
   4444 												/ 64.0
   4445 												* mode_lib->vba.PSCL_FACTOR[k]
   4446 												* mode_lib->vba.RequiredDPPCLK[i][j][k]);
   4447 					}
   4448 				} else {
   4449 					if (mode_lib->vba.VRatio[k] <= 1.0) {
   4450 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
   4451 								dml_max(
   4452 										mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4453 										1.1
   4454 												* dml_ceil(
   4455 														mode_lib->vba.BytePerPixelInDETY[k],
   4456 														1.0)
   4457 												/ 32.0
   4458 												* mode_lib->vba.HRatio[k]
   4459 												* mode_lib->vba.PixelClock[k]
   4460 												/ mode_lib->vba.NoOfDPP[i][j][k]);
   4461 					} else {
   4462 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
   4463 								dml_max(
   4464 										mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4465 										1.1
   4466 												* dml_ceil(
   4467 														mode_lib->vba.BytePerPixelInDETY[k],
   4468 														1.0)
   4469 												/ 32.0
   4470 												* mode_lib->vba.PSCL_FACTOR[k]
   4471 												* mode_lib->vba.RequiredDPPCLK[i][j][k]);
   4472 					}
   4473 					if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
   4474 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
   4475 								dml_max(
   4476 										mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4477 										1.1
   4478 												* dml_ceil(
   4479 														mode_lib->vba.BytePerPixelInDETC[k],
   4480 														2.0)
   4481 												/ 32.0
   4482 												* mode_lib->vba.HRatio[k]
   4483 												/ 2.0
   4484 												* mode_lib->vba.PixelClock[k]
   4485 												/ mode_lib->vba.NoOfDPP[i][j][k]);
   4486 					} else {
   4487 						mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
   4488 								dml_max(
   4489 										mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4490 										1.1
   4491 												* dml_ceil(
   4492 														mode_lib->vba.BytePerPixelInDETC[k],
   4493 														2.0)
   4494 												/ 32.0
   4495 												* mode_lib->vba.PSCL_FACTOR_CHROMA[k]
   4496 												* mode_lib->vba.RequiredDPPCLK[i][j][k]);
   4497 					}
   4498 				}
   4499 			}
   4500 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4501 				mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
   4502 						mode_lib,
   4503 						mode_lib->vba.DCCEnable[k],
   4504 						mode_lib->vba.Read256BlockHeightY[k],
   4505 						mode_lib->vba.Read256BlockWidthY[k],
   4506 						mode_lib->vba.SourcePixelFormat[k],
   4507 						mode_lib->vba.SurfaceTiling[k],
   4508 						dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
   4509 						mode_lib->vba.SourceScan[k],
   4510 						mode_lib->vba.ViewportWidth[k],
   4511 						mode_lib->vba.ViewportHeight[k],
   4512 						mode_lib->vba.SwathWidthYPerState[i][j][k],
   4513 						mode_lib->vba.GPUVMEnable,
   4514 						mode_lib->vba.VMMPageSize,
   4515 						mode_lib->vba.PTEBufferSizeInRequestsLuma,
   4516 						mode_lib->vba.PDEProcessingBufIn64KBReqs,
   4517 						mode_lib->vba.PitchY[k],
   4518 						mode_lib->vba.DCCMetaPitchY[k],
   4519 						&mode_lib->vba.MacroTileWidthY[k],
   4520 						&mode_lib->vba.MetaRowBytesY,
   4521 						&mode_lib->vba.DPTEBytesPerRowY,
   4522 						&mode_lib->vba.PTEBufferSizeNotExceededY[i][j][k],
   4523 						&mode_lib->vba.dpte_row_height[k],
   4524 						&mode_lib->vba.meta_row_height[k]);
   4525 				mode_lib->vba.PrefetchLinesY[0][0][k] = CalculatePrefetchSourceLines(
   4526 						mode_lib,
   4527 						mode_lib->vba.VRatio[k],
   4528 						mode_lib->vba.vtaps[k],
   4529 						mode_lib->vba.Interlace[k],
   4530 						mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
   4531 						mode_lib->vba.SwathHeightYPerState[i][j][k],
   4532 						mode_lib->vba.ViewportYStartY[k],
   4533 						&mode_lib->vba.PrefillY[k],
   4534 						&mode_lib->vba.MaxNumSwY[k]);
   4535 				if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
   4536 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
   4537 						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
   4538 						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
   4539 						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
   4540 					mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
   4541 							mode_lib,
   4542 							mode_lib->vba.DCCEnable[k],
   4543 							mode_lib->vba.Read256BlockHeightY[k],
   4544 							mode_lib->vba.Read256BlockWidthY[k],
   4545 							mode_lib->vba.SourcePixelFormat[k],
   4546 							mode_lib->vba.SurfaceTiling[k],
   4547 							dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
   4548 							mode_lib->vba.SourceScan[k],
   4549 							mode_lib->vba.ViewportWidth[k] / 2.0,
   4550 							mode_lib->vba.ViewportHeight[k] / 2.0,
   4551 							mode_lib->vba.SwathWidthYPerState[i][j][k] / 2.0,
   4552 							mode_lib->vba.GPUVMEnable,
   4553 							mode_lib->vba.VMMPageSize,
   4554 							mode_lib->vba.PTEBufferSizeInRequestsLuma,
   4555 							mode_lib->vba.PDEProcessingBufIn64KBReqs,
   4556 							mode_lib->vba.PitchC[k],
   4557 							0.0,
   4558 							&mode_lib->vba.MacroTileWidthC[k],
   4559 							&mode_lib->vba.MetaRowBytesC,
   4560 							&mode_lib->vba.DPTEBytesPerRowC,
   4561 							&mode_lib->vba.PTEBufferSizeNotExceededC[i][j][k],
   4562 							&mode_lib->vba.dpte_row_height_chroma[k],
   4563 							&mode_lib->vba.meta_row_height_chroma[k]);
   4564 					mode_lib->vba.PrefetchLinesC[0][0][k] = CalculatePrefetchSourceLines(
   4565 							mode_lib,
   4566 							mode_lib->vba.VRatio[k] / 2.0,
   4567 							mode_lib->vba.VTAPsChroma[k],
   4568 							mode_lib->vba.Interlace[k],
   4569 							mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
   4570 							mode_lib->vba.SwathHeightCPerState[i][j][k],
   4571 							mode_lib->vba.ViewportYStartC[k],
   4572 							&mode_lib->vba.PrefillC[k],
   4573 							&mode_lib->vba.MaxNumSwC[k]);
   4574 				} else {
   4575 					mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
   4576 					mode_lib->vba.MetaRowBytesC = 0.0;
   4577 					mode_lib->vba.DPTEBytesPerRowC = 0.0;
   4578 					locals->PrefetchLinesC[0][0][k] = 0.0;
   4579 					locals->PTEBufferSizeNotExceededC[i][j][k] = true;
   4580 					locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
   4581 				}
   4582 				locals->PDEAndMetaPTEBytesPerFrame[0][0][k] =
   4583 						mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
   4584 				locals->MetaRowBytes[0][0][k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
   4585 				locals->DPTEBytesPerRow[0][0][k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
   4586 
   4587 				CalculateActiveRowBandwidth(
   4588 						mode_lib->vba.GPUVMEnable,
   4589 						mode_lib->vba.SourcePixelFormat[k],
   4590 						mode_lib->vba.VRatio[k],
   4591 						mode_lib->vba.DCCEnable[k],
   4592 						mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
   4593 						mode_lib->vba.MetaRowBytesY,
   4594 						mode_lib->vba.MetaRowBytesC,
   4595 						mode_lib->vba.meta_row_height[k],
   4596 						mode_lib->vba.meta_row_height_chroma[k],
   4597 						mode_lib->vba.DPTEBytesPerRowY,
   4598 						mode_lib->vba.DPTEBytesPerRowC,
   4599 						mode_lib->vba.dpte_row_height[k],
   4600 						mode_lib->vba.dpte_row_height_chroma[k],
   4601 						&mode_lib->vba.meta_row_bw[k],
   4602 						&mode_lib->vba.dpte_row_bw[k],
   4603 						&mode_lib->vba.qual_row_bw[k]);
   4604 			}
   4605 			mode_lib->vba.ExtraLatency =
   4606 					mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
   4607 							+ (mode_lib->vba.TotalNumberOfActiveDPP[i][j]
   4608 									* mode_lib->vba.PixelChunkSizeInKByte
   4609 									+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i][j]
   4610 											* mode_lib->vba.MetaChunkSize)
   4611 									* 1024.0
   4612 									/ mode_lib->vba.ReturnBWPerState[i][0];
   4613 			if (mode_lib->vba.GPUVMEnable == true) {
   4614 				mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
   4615 						+ mode_lib->vba.TotalNumberOfActiveDPP[i][j]
   4616 								* mode_lib->vba.PTEGroupSize
   4617 								/ mode_lib->vba.ReturnBWPerState[i][0];
   4618 			}
   4619 			mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
   4620 
   4621 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4622 				if (mode_lib->vba.BlendingAndTiming[k] == k) {
   4623 					if (mode_lib->vba.WritebackEnable[k] == true) {
   4624 						locals->WritebackDelay[i][k] = mode_lib->vba.WritebackLatency
   4625 								+ CalculateWriteBackDelay(
   4626 										mode_lib->vba.WritebackPixelFormat[k],
   4627 										mode_lib->vba.WritebackHRatio[k],
   4628 										mode_lib->vba.WritebackVRatio[k],
   4629 										mode_lib->vba.WritebackLumaHTaps[k],
   4630 										mode_lib->vba.WritebackLumaVTaps[k],
   4631 										mode_lib->vba.WritebackChromaHTaps[k],
   4632 										mode_lib->vba.WritebackChromaVTaps[k],
   4633 										mode_lib->vba.WritebackDestinationWidth[k]) / locals->RequiredDISPCLK[i][j];
   4634 					} else {
   4635 						locals->WritebackDelay[i][k] = 0.0;
   4636 					}
   4637 					for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
   4638 						if (mode_lib->vba.BlendingAndTiming[m] == k
   4639 								&& mode_lib->vba.WritebackEnable[m]
   4640 										== true) {
   4641 							locals->WritebackDelay[i][k] = dml_max(locals->WritebackDelay[i][k],
   4642 											mode_lib->vba.WritebackLatency + CalculateWriteBackDelay(
   4643 													mode_lib->vba.WritebackPixelFormat[m],
   4644 													mode_lib->vba.WritebackHRatio[m],
   4645 													mode_lib->vba.WritebackVRatio[m],
   4646 													mode_lib->vba.WritebackLumaHTaps[m],
   4647 													mode_lib->vba.WritebackLumaVTaps[m],
   4648 													mode_lib->vba.WritebackChromaHTaps[m],
   4649 													mode_lib->vba.WritebackChromaVTaps[m],
   4650 													mode_lib->vba.WritebackDestinationWidth[m]) / locals->RequiredDISPCLK[i][j]);
   4651 						}
   4652 					}
   4653 				}
   4654 			}
   4655 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4656 				for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
   4657 					if (mode_lib->vba.BlendingAndTiming[k] == m) {
   4658 						locals->WritebackDelay[i][k] = locals->WritebackDelay[i][m];
   4659 					}
   4660 				}
   4661 			}
   4662 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4663 				for (m = 0; m < locals->NumberOfCursors[k]; m++)
   4664 					locals->cursor_bw[k] = locals->NumberOfCursors[k] * locals->CursorWidth[k][m] * locals->CursorBPP[k][m]
   4665 						/ 8 / (locals->HTotal[k] / locals->PixelClock[k]) * locals->VRatio[k];
   4666 			}
   4667 
   4668 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4669 				locals->MaximumVStartup[0][0][k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
   4670 					- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
   4671 			}
   4672 
   4673 			mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
   4674 			do {
   4675 				mode_lib->vba.PrefetchMode[i][j] = mode_lib->vba.NextPrefetchMode;
   4676 				mode_lib->vba.NextPrefetchMode = mode_lib->vba.NextPrefetchMode + 1;
   4677 
   4678 				mode_lib->vba.TWait = CalculateTWait(
   4679 						mode_lib->vba.PrefetchMode[i][j],
   4680 						mode_lib->vba.DRAMClockChangeLatency,
   4681 						mode_lib->vba.UrgentLatency,
   4682 						mode_lib->vba.SREnterPlusExitTime);
   4683 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4684 
   4685 					if (mode_lib->vba.XFCEnabled[k] == true) {
   4686 						mode_lib->vba.XFCRemoteSurfaceFlipDelay =
   4687 								CalculateRemoteSurfaceFlipDelay(
   4688 										mode_lib,
   4689 										mode_lib->vba.VRatio[k],
   4690 										locals->SwathWidthYPerState[i][j][k],
   4691 										dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
   4692 										mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
   4693 										mode_lib->vba.XFCTSlvVupdateOffset,
   4694 										mode_lib->vba.XFCTSlvVupdateWidth,
   4695 										mode_lib->vba.XFCTSlvVreadyOffset,
   4696 										mode_lib->vba.XFCXBUFLatencyTolerance,
   4697 										mode_lib->vba.XFCFillBWOverhead,
   4698 										mode_lib->vba.XFCSlvChunkSize,
   4699 										mode_lib->vba.XFCBusTransportTime,
   4700 										mode_lib->vba.TimeCalc,
   4701 										mode_lib->vba.TWait,
   4702 										&mode_lib->vba.SrcActiveDrainRate,
   4703 										&mode_lib->vba.TInitXFill,
   4704 										&mode_lib->vba.TslvChk);
   4705 					} else {
   4706 						mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
   4707 					}
   4708 					mode_lib->vba.IsErrorResult[i][j][k] =
   4709 							CalculatePrefetchSchedule(
   4710 									mode_lib,
   4711 									mode_lib->vba.RequiredDPPCLK[i][j][k],
   4712 									mode_lib->vba.RequiredDISPCLK[i][j],
   4713 									mode_lib->vba.PixelClock[k],
   4714 									mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
   4715 									mode_lib->vba.DSCDelayPerState[i][k],
   4716 									mode_lib->vba.NoOfDPP[i][j][k],
   4717 									mode_lib->vba.ScalerEnabled[k],
   4718 									mode_lib->vba.NumberOfCursors[k],
   4719 									mode_lib->vba.DPPCLKDelaySubtotal,
   4720 									mode_lib->vba.DPPCLKDelaySCL,
   4721 									mode_lib->vba.DPPCLKDelaySCLLBOnly,
   4722 									mode_lib->vba.DPPCLKDelayCNVCFormater,
   4723 									mode_lib->vba.DPPCLKDelayCNVCCursor,
   4724 									mode_lib->vba.DISPCLKDelaySubtotal,
   4725 									mode_lib->vba.SwathWidthYPerState[i][j][k]
   4726 											/ mode_lib->vba.HRatio[k],
   4727 									mode_lib->vba.OutputFormat[k],
   4728 									mode_lib->vba.VTotal[k]
   4729 											- mode_lib->vba.VActive[k],
   4730 									mode_lib->vba.HTotal[k],
   4731 									mode_lib->vba.MaxInterDCNTileRepeaters,
   4732 									mode_lib->vba.MaximumVStartup[0][0][k],
   4733 									mode_lib->vba.GPUVMMaxPageTableLevels,
   4734 									mode_lib->vba.GPUVMEnable,
   4735 									mode_lib->vba.DynamicMetadataEnable[k],
   4736 									mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
   4737 									mode_lib->vba.DynamicMetadataTransmittedBytes[k],
   4738 									mode_lib->vba.DCCEnable[k],
   4739 									mode_lib->vba.UrgentLatencyPixelDataOnly,
   4740 									mode_lib->vba.ExtraLatency,
   4741 									mode_lib->vba.TimeCalc,
   4742 									mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
   4743 									mode_lib->vba.MetaRowBytes[0][0][k],
   4744 									mode_lib->vba.DPTEBytesPerRow[0][0][k],
   4745 									mode_lib->vba.PrefetchLinesY[0][0][k],
   4746 									mode_lib->vba.SwathWidthYPerState[i][j][k],
   4747 									mode_lib->vba.BytePerPixelInDETY[k],
   4748 									mode_lib->vba.PrefillY[k],
   4749 									mode_lib->vba.MaxNumSwY[k],
   4750 									mode_lib->vba.PrefetchLinesC[0][0][k],
   4751 									mode_lib->vba.BytePerPixelInDETC[k],
   4752 									mode_lib->vba.PrefillC[k],
   4753 									mode_lib->vba.MaxNumSwC[k],
   4754 									mode_lib->vba.SwathHeightYPerState[i][j][k],
   4755 									mode_lib->vba.SwathHeightCPerState[i][j][k],
   4756 									mode_lib->vba.TWait,
   4757 									mode_lib->vba.XFCEnabled[k],
   4758 									mode_lib->vba.XFCRemoteSurfaceFlipDelay,
   4759 									mode_lib->vba.Interlace[k],
   4760 									mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
   4761 									mode_lib->vba.DSTXAfterScaler,
   4762 									mode_lib->vba.DSTYAfterScaler,
   4763 									&mode_lib->vba.LineTimesForPrefetch[k],
   4764 									&mode_lib->vba.PrefetchBW[k],
   4765 									&mode_lib->vba.LinesForMetaPTE[k],
   4766 									&mode_lib->vba.LinesForMetaAndDPTERow[k],
   4767 									&mode_lib->vba.VRatioPreY[i][j][k],
   4768 									&mode_lib->vba.VRatioPreC[i][j][k],
   4769 									&mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k],
   4770 									&mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
   4771 									&mode_lib->vba.Tno_bw[k],
   4772 									&mode_lib->vba.VUpdateOffsetPix[k],
   4773 									&mode_lib->vba.VUpdateWidthPix[k],
   4774 									&mode_lib->vba.VReadyOffsetPix[k]);
   4775 				}
   4776 				mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0;
   4777 				mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
   4778 				locals->prefetch_vm_bw_valid = true;
   4779 				locals->prefetch_row_bw_valid = true;
   4780 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4781 					if (locals->PDEAndMetaPTEBytesPerFrame[0][0][k] == 0)
   4782 						locals->prefetch_vm_bw[k] = 0;
   4783 					else if (locals->LinesForMetaPTE[k] > 0)
   4784 						locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[0][0][k]
   4785 							/ (locals->LinesForMetaPTE[k] * locals->HTotal[k] / locals->PixelClock[k]);
   4786 					else {
   4787 						locals->prefetch_vm_bw[k] = 0;
   4788 						locals->prefetch_vm_bw_valid = false;
   4789 					}
   4790 					if (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k] == 0)
   4791 						locals->prefetch_row_bw[k] = 0;
   4792 					else if (locals->LinesForMetaAndDPTERow[k] > 0)
   4793 						locals->prefetch_row_bw[k] = (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k])
   4794 							/ (locals->LinesForMetaAndDPTERow[k] * locals->HTotal[k] / locals->PixelClock[k]);
   4795 					else {
   4796 						locals->prefetch_row_bw[k] = 0;
   4797 						locals->prefetch_row_bw_valid = false;
   4798 					}
   4799 
   4800 					mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = mode_lib->vba.MaximumReadBandwidthWithPrefetch
   4801 							+ mode_lib->vba.cursor_bw[k] + mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k];
   4802 					mode_lib->vba.MaximumReadBandwidthWithPrefetch =
   4803 							mode_lib->vba.MaximumReadBandwidthWithPrefetch
   4804 									+ mode_lib->vba.cursor_bw[k]
   4805 									+ dml_max3(
   4806 											mode_lib->vba.prefetch_vm_bw[k],
   4807 											mode_lib->vba.prefetch_row_bw[k],
   4808 											dml_max(mode_lib->vba.ReadBandwidth[k],
   4809 											mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k])
   4810 											+ mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k]);
   4811 				}
   4812 				locals->BandwidthWithoutPrefetchSupported[i][0] = true;
   4813 				if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i][0]) {
   4814 					locals->BandwidthWithoutPrefetchSupported[i][0] = false;
   4815 				}
   4816 
   4817 				locals->PrefetchSupported[i][j] = true;
   4818 				if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i][0]) {
   4819 					locals->PrefetchSupported[i][j] = false;
   4820 				}
   4821 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4822 					if (locals->LineTimesForPrefetch[k] < 2.0
   4823 							|| locals->LinesForMetaPTE[k] >= 8.0
   4824 							|| locals->LinesForMetaAndDPTERow[k] >= 16.0
   4825 							|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
   4826 						locals->PrefetchSupported[i][j] = false;
   4827 					}
   4828 				}
   4829 				locals->VRatioInPrefetchSupported[i][j] = true;
   4830 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4831 					if (locals->VRatioPreY[i][j][k] > 4.0
   4832 							|| locals->VRatioPreC[i][j][k] > 4.0
   4833 							|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
   4834 						locals->VRatioInPrefetchSupported[i][j] = false;
   4835 					}
   4836 				}
   4837 			} while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true)
   4838 					&& mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode);
   4839 
   4840 			if (mode_lib->vba.PrefetchSupported[i][j] == true
   4841 					&& mode_lib->vba.VRatioInPrefetchSupported[i][j] == true) {
   4842 				mode_lib->vba.BandwidthAvailableForImmediateFlip =
   4843 						mode_lib->vba.ReturnBWPerState[i][0];
   4844 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4845 					mode_lib->vba.BandwidthAvailableForImmediateFlip =
   4846 							mode_lib->vba.BandwidthAvailableForImmediateFlip
   4847 									- mode_lib->vba.cursor_bw[k]
   4848 									- dml_max(
   4849 											mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.qual_row_bw[k],
   4850 											mode_lib->vba.PrefetchBW[k]);
   4851 				}
   4852 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4853 					mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
   4854 					if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
   4855 							&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
   4856 						mode_lib->vba.ImmediateFlipBytes[k] =
   4857 								mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k]
   4858 										+ mode_lib->vba.MetaRowBytes[0][0][k]
   4859 										+ mode_lib->vba.DPTEBytesPerRow[0][0][k];
   4860 					}
   4861 				}
   4862 				mode_lib->vba.TotImmediateFlipBytes = 0.0;
   4863 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4864 					if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
   4865 							&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
   4866 						mode_lib->vba.TotImmediateFlipBytes =
   4867 								mode_lib->vba.TotImmediateFlipBytes
   4868 										+ mode_lib->vba.ImmediateFlipBytes[k];
   4869 					}
   4870 				}
   4871 
   4872 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4873 					CalculateFlipSchedule(
   4874 							mode_lib,
   4875 							mode_lib->vba.ExtraLatency,
   4876 							mode_lib->vba.UrgentLatencyPixelDataOnly,
   4877 							mode_lib->vba.GPUVMMaxPageTableLevels,
   4878 							mode_lib->vba.GPUVMEnable,
   4879 							mode_lib->vba.BandwidthAvailableForImmediateFlip,
   4880 							mode_lib->vba.TotImmediateFlipBytes,
   4881 							mode_lib->vba.SourcePixelFormat[k],
   4882 							mode_lib->vba.ImmediateFlipBytes[k],
   4883 							mode_lib->vba.HTotal[k]
   4884 									/ mode_lib->vba.PixelClock[k],
   4885 							mode_lib->vba.VRatio[k],
   4886 							mode_lib->vba.Tno_bw[k],
   4887 							mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
   4888 							mode_lib->vba.MetaRowBytes[0][0][k],
   4889 							mode_lib->vba.DPTEBytesPerRow[0][0][k],
   4890 							mode_lib->vba.DCCEnable[k],
   4891 							mode_lib->vba.dpte_row_height[k],
   4892 							mode_lib->vba.meta_row_height[k],
   4893 							mode_lib->vba.qual_row_bw[k],
   4894 							&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
   4895 							&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
   4896 							&mode_lib->vba.final_flip_bw[k],
   4897 							&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
   4898 				}
   4899 				mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
   4900 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4901 					mode_lib->vba.total_dcn_read_bw_with_flip =
   4902 							mode_lib->vba.total_dcn_read_bw_with_flip
   4903 									+ mode_lib->vba.cursor_bw[k]
   4904 									+ dml_max3(
   4905 											mode_lib->vba.prefetch_vm_bw[k],
   4906 											mode_lib->vba.prefetch_row_bw[k],
   4907 											mode_lib->vba.final_flip_bw[k]
   4908 													+ dml_max(
   4909 															mode_lib->vba.ReadBandwidth[k],
   4910 															mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k]));
   4911 				}
   4912 				mode_lib->vba.ImmediateFlipSupportedForState[i][j] = true;
   4913 				if (mode_lib->vba.total_dcn_read_bw_with_flip
   4914 						> mode_lib->vba.ReturnBWPerState[i][0]) {
   4915 					mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
   4916 				}
   4917 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4918 					if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
   4919 						mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
   4920 					}
   4921 				}
   4922 			} else {
   4923 				mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
   4924 			}
   4925 		}
   4926 	}
   4927 
   4928 	/*Vertical Active BW support*/
   4929 	mode_lib->vba.MaxTotalVActiveRDBandwidth = 0;
   4930 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
   4931 		mode_lib->vba.MaxTotalVActiveRDBandwidth = mode_lib->vba.MaxTotalVActiveRDBandwidth + mode_lib->vba.ReadBandwidth[k];
   4932 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4933 		mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0] = dml_min(mode_lib->vba.ReturnBusWidth *
   4934 				mode_lib->vba.DCFCLKPerState[i], mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000) *
   4935 				mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100;
   4936 		if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0])
   4937 			mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = true;
   4938 		else
   4939 			mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = false;
   4940 	}
   4941 
   4942 	/*PTE Buffer Size Check*/
   4943 
   4944 	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
   4945 		for (j = 0; j < 2; j++) {
   4946 			locals->PTEBufferSizeNotExceeded[i][j] = true;
   4947 			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4948 				if (locals->PTEBufferSizeNotExceededY[i][j][k] == false
   4949 						|| locals->PTEBufferSizeNotExceededC[i][j][k] == false) {
   4950 					locals->PTEBufferSizeNotExceeded[i][j] = false;
   4951 				}
   4952 			}
   4953 		}
   4954 	}
   4955 	/*Cursor Support Check*/
   4956 	mode_lib->vba.CursorSupport = true;
   4957 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4958 		for (j = 0; j < 2; j++) {
   4959 			if (mode_lib->vba.CursorWidth[k][j] > 0.0) {
   4960 				if (dml_floor(
   4961 						dml_floor(
   4962 								mode_lib->vba.CursorBufferSize
   4963 										- mode_lib->vba.CursorChunkSize,
   4964 								mode_lib->vba.CursorChunkSize) * 1024.0
   4965 								/ (mode_lib->vba.CursorWidth[k][j]
   4966 										* mode_lib->vba.CursorBPP[k][j]
   4967 										/ 8.0),
   4968 						1.0)
   4969 						* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
   4970 						/ mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatencyPixelDataOnly
   4971 						|| (mode_lib->vba.CursorBPP[k][j] == 64.0
   4972 								&& mode_lib->vba.Cursor64BppSupport == false)) {
   4973 					mode_lib->vba.CursorSupport = false;
   4974 				}
   4975 			}
   4976 		}
   4977 	}
   4978 	/*Valid Pitch Check*/
   4979 
   4980 	mode_lib->vba.PitchSupport = true;
   4981 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   4982 		locals->AlignedYPitch[k] = dml_ceil(
   4983 				dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
   4984 				locals->MacroTileWidthY[k]);
   4985 		if (locals->AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
   4986 			mode_lib->vba.PitchSupport = false;
   4987 		}
   4988 		if (mode_lib->vba.DCCEnable[k] == true) {
   4989 			locals->AlignedDCCMetaPitch[k] = dml_ceil(
   4990 					dml_max(
   4991 							mode_lib->vba.DCCMetaPitchY[k],
   4992 							mode_lib->vba.ViewportWidth[k]),
   4993 					64.0 * locals->Read256BlockWidthY[k]);
   4994 		} else {
   4995 			locals->AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
   4996 		}
   4997 		if (locals->AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
   4998 			mode_lib->vba.PitchSupport = false;
   4999 		}
   5000 		if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
   5001 				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
   5002 				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
   5003 				&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
   5004 				&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
   5005 			locals->AlignedCPitch[k] = dml_ceil(
   5006 					dml_max(
   5007 							mode_lib->vba.PitchC[k],
   5008 							mode_lib->vba.ViewportWidth[k] / 2.0),
   5009 					locals->MacroTileWidthC[k]);
   5010 		} else {
   5011 			locals->AlignedCPitch[k] = mode_lib->vba.PitchC[k];
   5012 		}
   5013 		if (locals->AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
   5014 			mode_lib->vba.PitchSupport = false;
   5015 		}
   5016 	}
   5017 	/*Mode Support, Voltage State and SOC Configuration*/
   5018 
   5019 	for (i = mode_lib->vba.soc.num_states; i >= 0; i--) {
   5020 		for (j = 0; j < 2; j++) {
   5021 			enum dm_validation_status status = DML_VALIDATION_OK;
   5022 
   5023 			if (mode_lib->vba.ScaleRatioAndTapsSupport != true) {
   5024 				status = DML_FAIL_SCALE_RATIO_TAP;
   5025 			} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
   5026 				status = DML_FAIL_SOURCE_PIXEL_FORMAT;
   5027 			} else if (locals->ViewportSizeSupport[i][0] != true) {
   5028 				status = DML_FAIL_VIEWPORT_SIZE;
   5029 			} else if (locals->DIOSupport[i] != true) {
   5030 				status = DML_FAIL_DIO_SUPPORT;
   5031 			} else if (locals->NotEnoughDSCUnits[i] != false) {
   5032 				status = DML_FAIL_NOT_ENOUGH_DSC;
   5033 			} else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) {
   5034 				status = DML_FAIL_DSC_CLK_REQUIRED;
   5035 			} else if (locals->UrgentLatencySupport[i][j] != true) {
   5036 				status = DML_FAIL_URGENT_LATENCY;
   5037 			} else if (locals->ROBSupport[i][0] != true) {
   5038 				status = DML_FAIL_REORDERING_BUFFER;
   5039 			} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
   5040 				status = DML_FAIL_DISPCLK_DPPCLK;
   5041 			} else if (locals->TotalAvailablePipesSupport[i][j] != true) {
   5042 				status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
   5043 			} else if (mode_lib->vba.NumberOfOTGSupport != true) {
   5044 				status = DML_FAIL_NUM_OTG;
   5045 			} else if (mode_lib->vba.WritebackModeSupport != true) {
   5046 				status = DML_FAIL_WRITEBACK_MODE;
   5047 			} else if (mode_lib->vba.WritebackLatencySupport != true) {
   5048 				status = DML_FAIL_WRITEBACK_LATENCY;
   5049 			} else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) {
   5050 				status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
   5051 			} else if (mode_lib->vba.CursorSupport != true) {
   5052 				status = DML_FAIL_CURSOR_SUPPORT;
   5053 			} else if (mode_lib->vba.PitchSupport != true) {
   5054 				status = DML_FAIL_PITCH_SUPPORT;
   5055 			} else if (locals->PrefetchSupported[i][j] != true) {
   5056 				status = DML_FAIL_PREFETCH_SUPPORT;
   5057 			} else if (locals->TotalVerticalActiveBandwidthSupport[i][0] != true) {
   5058 				status = DML_FAIL_TOTAL_V_ACTIVE_BW;
   5059 			} else if (locals->VRatioInPrefetchSupported[i][j] != true) {
   5060 				status = DML_FAIL_V_RATIO_PREFETCH;
   5061 			} else if (locals->PTEBufferSizeNotExceeded[i][j] != true) {
   5062 				status = DML_FAIL_PTE_BUFFER_SIZE;
   5063 			} else if (mode_lib->vba.NonsupportedDSCInputBPC != false) {
   5064 				status = DML_FAIL_DSC_INPUT_BPC;
   5065 			}
   5066 
   5067 			if (status == DML_VALIDATION_OK) {
   5068 				locals->ModeSupport[i][j] = true;
   5069 			} else {
   5070 				locals->ModeSupport[i][j] = false;
   5071 			}
   5072 			locals->ValidationStatus[i] = status;
   5073 		}
   5074 	}
   5075 	{
   5076 		unsigned int MaximumMPCCombine = 0;
   5077 		mode_lib->vba.VoltageLevel = mode_lib->vba.soc.num_states + 1;
   5078 		for (i = mode_lib->vba.VoltageOverrideLevel; i <= mode_lib->vba.soc.num_states; i++) {
   5079 			if (locals->ModeSupport[i][0] == true || locals->ModeSupport[i][1] == true) {
   5080 				mode_lib->vba.VoltageLevel = i;
   5081 				if (locals->ModeSupport[i][1] == true && (locals->ModeSupport[i][0] == false
   5082 						|| mode_lib->vba.WhenToDoMPCCombine == dm_mpc_always_when_possible)) {
   5083 					MaximumMPCCombine = 1;
   5084 				} else {
   5085 					MaximumMPCCombine = 0;
   5086 				}
   5087 				break;
   5088 			}
   5089 		}
   5090 		mode_lib->vba.ImmediateFlipSupport =
   5091 			locals->ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
   5092 		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   5093 			mode_lib->vba.DPPPerPlane[k] = locals->NoOfDPP[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
   5094 			locals->DPPCLK[k] = locals->RequiredDPPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
   5095 		}
   5096 		mode_lib->vba.DISPCLK = locals->RequiredDISPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
   5097 		mode_lib->vba.maxMpcComb = MaximumMPCCombine;
   5098 	}
   5099 	mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
   5100 	mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
   5101 	mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
   5102 	mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
   5103 	mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
   5104 	mode_lib->vba.FabricAndDRAMBandwidth = locals->FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
   5105 	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
   5106 		if (mode_lib->vba.BlendingAndTiming[k] == k) {
   5107 			mode_lib->vba.ODMCombineEnabled[k] =
   5108 					locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
   5109 		} else {
   5110 			mode_lib->vba.ODMCombineEnabled[k] = 0;
   5111 		}
   5112 		mode_lib->vba.DSCEnabled[k] =
   5113 				locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
   5114 		mode_lib->vba.OutputBpp[k] =
   5115 				locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
   5116 	}
   5117 }
   5118