File Index
Files and directories
Sign in
FILE

display_mode_vba_20.c

File preview with syntax highlighting.

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