File Index
Files and directories
Sign in
FILE

display_mode_vba_20v2.c

File preview with syntax highlighting.

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