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