#include "../display_mode_lib.h"
#include "../dml_inline_defs.h"
#include "../display_mode_vba.h"
#include "display_mode_vba_21.h"
typedef struct {
double DPPCLK;
double DISPCLK;
double PixelClock;
double DCFCLKDeepSleep;
unsigned int DPPPerPlane;
bool ScalerEnabled;
enum scan_direction_class SourceScan;
unsigned int BlockWidth256BytesY;
unsigned int BlockHeight256BytesY;
unsigned int BlockWidth256BytesC;
unsigned int BlockHeight256BytesC;
unsigned int InterlaceEnable;
unsigned int NumberOfCursors;
unsigned int VBlank;
unsigned int HTotal;
} Pipe;
typedef struct {
bool Enable;
unsigned int MaxPageTableLevels;
unsigned int CachedPageTableLevels;
} HostVM;
#define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff
#define DCN21_MAX_DSC_IMAGE_WIDTH 5184
#define DCN21_MAX_420_IMAGE_WIDTH 4096
static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
struct display_mode_lib *mode_lib);
static unsigned int dscceComputeDelay(
unsigned int bpc,
double bpp,
unsigned int sliceWidth,
unsigned int numSlices,
enum output_format_class pixelFormat);
static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
Pipe *myPipe,
unsigned int DSCDelay,
double DPPCLKDelaySubtotal,
double DPPCLKDelaySCL,
double DPPCLKDelaySCLLBOnly,
double DPPCLKDelayCNVCFormater,
double DPPCLKDelayCNVCCursor,
double DISPCLKDelaySubtotal,
unsigned int ScalerRecoutWidth,
enum output_format_class OutputFormat,
unsigned int MaxInterDCNTileRepeaters,
unsigned int VStartup,
unsigned int MaxVStartup,
unsigned int GPUVMPageTableLevels,
bool GPUVMEnable,
HostVM *myHostVM,
bool DynamicMetadataEnable,
int DynamicMetadataLinesBeforeActiveRequired,
unsigned int DynamicMetadataTransmittedBytes,
bool DCCEnable,
double UrgentLatency,
double UrgentExtraLatency,
double TCalc,
unsigned int PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
double PrefetchSourceLinesY,
unsigned int SwathWidthY,
double BytePerPixelDETY,
double VInitPreFillY,
unsigned int MaxNumSwathY,
double PrefetchSourceLinesC,
double BytePerPixelDETC,
double VInitPreFillC,
unsigned int MaxNumSwathC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
double TWait,
bool XFCEnabled,
double XFCRemoteSurfaceFlipDelay,
bool ProgressiveToInterlaceUnitInOPP,
double *DSTXAfterScaler,
double *DSTYAfterScaler,
double *DestinationLinesForPrefetch,
double *PrefetchBandwidth,
double *DestinationLinesToRequestVMInVBlank,
double *DestinationLinesToRequestRowInVBlank,
double *VRatioPrefetchY,
double *VRatioPrefetchC,
double *RequiredPrefetchPixDataBWLuma,
double *RequiredPrefetchPixDataBWChroma,
unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
double *Tno_bw,
double *prefetch_vmrow_bw,
unsigned int *swath_width_luma_ub,
unsigned int *swath_width_chroma_ub,
unsigned int *VUpdateOffsetPix,
double *VUpdateWidthPix,
double *VReadyOffsetPix);
static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
static double CalculateDCCConfiguration(
bool DCCEnabled,
bool DCCProgrammingAssumesScanDirectionUnknown,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int DETBufferSize,
unsigned int RequestHeight256Byte,
unsigned int SwathHeight,
enum dm_swizzle_mode TilingFormat,
unsigned int BytePerPixel,
enum scan_direction_class ScanOrientation,
unsigned int *MaxUncompressedBlock,
unsigned int *MaxCompressedBlock,
unsigned int *Independent64ByteBlock);
static double CalculatePrefetchSourceLines(
struct display_mode_lib *mode_lib,
double VRatio,
double vtaps,
bool Interlace,
bool ProgressiveToInterlaceUnitInOPP,
unsigned int SwathHeight,
unsigned int ViewportYStart,
double *VInitPreFill,
unsigned int *MaxNumSwath);
static unsigned int CalculateVMAndRowBytes(
struct display_mode_lib *mode_lib,
bool DCCEnable,
unsigned int BlockHeight256Bytes,
unsigned int BlockWidth256Bytes,
enum source_format_class SourcePixelFormat,
unsigned int SurfaceTiling,
unsigned int BytePerPixel,
enum scan_direction_class ScanDirection,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int SwathWidthY,
bool GPUVMEnable,
bool HostVMEnable,
unsigned int HostVMMaxPageTableLevels,
unsigned int HostVMCachedPageTableLevels,
unsigned int VMMPageSize,
unsigned int PTEBufferSizeInRequests,
unsigned int Pitch,
unsigned int DCCMetaPitch,
unsigned int *MacroTileWidth,
unsigned int *MetaRowByte,
unsigned int *PixelPTEBytesPerRow,
bool *PTEBufferSizeNotExceeded,
unsigned int *dpte_row_width_ub,
unsigned int *dpte_row_height,
unsigned int *MetaRequestWidth,
unsigned int *MetaRequestHeight,
unsigned int *meta_row_width,
unsigned int *meta_row_height,
unsigned int *vm_group_bytes,
unsigned int *dpte_group_bytes,
unsigned int *PixelPTEReqWidth,
unsigned int *PixelPTEReqHeight,
unsigned int *PTERequestSize,
unsigned int *DPDE0BytesFrame,
unsigned int *MetaPTEBytesFrame);
static double CalculateTWait(
unsigned int PrefetchMode,
double DRAMClockChangeLatency,
double UrgentLatency,
double SREnterPlusExitTime);
static double CalculateRemoteSurfaceFlipDelay(
struct display_mode_lib *mode_lib,
double VRatio,
double SwathWidth,
double Bpp,
double LineTime,
double XFCTSlvVupdateOffset,
double XFCTSlvVupdateWidth,
double XFCTSlvVreadyOffset,
double XFCXBUFLatencyTolerance,
double XFCFillBWOverhead,
double XFCSlvChunkSize,
double XFCBusTransportTime,
double TCalc,
double TWait,
double *SrcActiveDrainRate,
double *TInitXFill,
double *TslvChk);
static void CalculateActiveRowBandwidth(
bool GPUVMEnable,
enum source_format_class SourcePixelFormat,
double VRatio,
bool DCCEnable,
double LineTime,
unsigned int MetaRowByteLuma,
unsigned int MetaRowByteChroma,
unsigned int meta_row_height_luma,
unsigned int meta_row_height_chroma,
unsigned int PixelPTEBytesPerRowLuma,
unsigned int PixelPTEBytesPerRowChroma,
unsigned int dpte_row_height_luma,
unsigned int dpte_row_height_chroma,
double *meta_row_bw,
double *dpte_row_bw);
static void CalculateFlipSchedule(
struct display_mode_lib *mode_lib,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
double UrgentExtraLatency,
double UrgentLatency,
unsigned int GPUVMMaxPageTableLevels,
bool HostVMEnable,
unsigned int HostVMMaxPageTableLevels,
unsigned int HostVMCachedPageTableLevels,
bool GPUVMEnable,
double PDEAndMetaPTEBytesPerFrame,
double MetaRowBytes,
double DPTEBytesPerRow,
double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum source_format_class SourcePixelFormat,
double LineTime,
double VRatio,
double Tno_bw,
bool DCCEnable,
unsigned int dpte_row_height,
unsigned int meta_row_height,
unsigned int dpte_row_height_chroma,
unsigned int meta_row_height_chroma,
double *DestinationLinesToRequestVMInImmediateFlip,
double *DestinationLinesToRequestRowInImmediateFlip,
double *final_flip_bw,
bool *ImmediateFlipSupportedForPipe);
static double CalculateWriteBackDelay(
enum source_format_class WritebackPixelFormat,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackLumaHTaps,
unsigned int WritebackLumaVTaps,
unsigned int WritebackChromaHTaps,
unsigned int WritebackChromaVTaps,
unsigned int WritebackDestinationWidth);
static void CalculateWatermarksAndDRAMSpeedChangeSupport(
struct display_mode_lib *mode_lib,
unsigned int PrefetchMode,
unsigned int NumberOfActivePlanes,
unsigned int MaxLineBufferLines,
unsigned int LineBufferSize,
unsigned int DPPOutputBufferPixels,
unsigned int DETBufferSizeInKByte,
unsigned int WritebackInterfaceLumaBufferSize,
unsigned int WritebackInterfaceChromaBufferSize,
double DCFCLK,
double UrgentOutOfOrderReturn,
double ReturnBW,
bool GPUVMEnable,
int dpte_group_bytes[],
unsigned int MetaChunkSize,
double UrgentLatency,
double ExtraLatency,
double WritebackLatency,
double WritebackChunkSize,
double SOCCLK,
double DRAMClockChangeLatency,
double SRExitTime,
double SREnterPlusExitTime,
double DCFCLKDeepSleep,
int DPPPerPlane[],
bool DCCEnable[],
double DPPCLK[],
double SwathWidthSingleDPPY[],
unsigned int SwathHeightY[],
double ReadBandwidthPlaneLuma[],
unsigned int SwathHeightC[],
double ReadBandwidthPlaneChroma[],
unsigned int LBBitPerPixel[],
double SwathWidthY[],
double HRatio[],
unsigned int vtaps[],
unsigned int VTAPsChroma[],
double VRatio[],
unsigned int HTotal[],
double PixelClock[],
unsigned int BlendingAndTiming[],
double BytePerPixelDETY[],
double BytePerPixelDETC[],
bool WritebackEnable[],
enum source_format_class WritebackPixelFormat[],
double WritebackDestinationWidth[],
double WritebackDestinationHeight[],
double WritebackSourceHeight[],
enum clock_change_support *DRAMClockChangeSupport,
double *UrgentWatermark,
double *WritebackUrgentWatermark,
double *DRAMClockChangeWatermark,
double *WritebackDRAMClockChangeWatermark,
double *StutterExitWatermark,
double *StutterEnterPlusExitWatermark,
double *MinActiveDRAMClockChangeLatencySupported);
static void CalculateDCFCLKDeepSleep(
struct display_mode_lib *mode_lib,
unsigned int NumberOfActivePlanes,
double BytePerPixelDETY[],
double BytePerPixelDETC[],
double VRatio[],
double SwathWidthY[],
int DPPPerPlane[],
double HRatio[],
double PixelClock[],
double PSCL_THROUGHPUT[],
double PSCL_THROUGHPUT_CHROMA[],
double DPPCLK[],
double *DCFCLKDeepSleep);
static void CalculateDETBufferSize(
unsigned int DETBufferSizeInKByte,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
unsigned int *DETBufferSizeY,
unsigned int *DETBufferSizeC);
static void CalculateUrgentBurstFactor(
unsigned int DETBufferSizeInKByte,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
unsigned int SwathWidthY,
double LineTime,
double UrgentLatency,
double CursorBufferSize,
unsigned int CursorWidth,
unsigned int CursorBPP,
double VRatio,
double VRatioPreY,
double VRatioPreC,
double BytePerPixelInDETY,
double BytePerPixelInDETC,
double *UrgentBurstFactorCursor,
double *UrgentBurstFactorCursorPre,
double *UrgentBurstFactorLuma,
double *UrgentBurstFactorLumaPre,
double *UrgentBurstFactorChroma,
double *UrgentBurstFactorChromaPre,
unsigned int *NotEnoughUrgentLatencyHiding,
unsigned int *NotEnoughUrgentLatencyHidingPre);
static void CalculatePixelDeliveryTimes(
unsigned int NumberOfActivePlanes,
double VRatio[],
double VRatioPrefetchY[],
double VRatioPrefetchC[],
unsigned int swath_width_luma_ub[],
unsigned int swath_width_chroma_ub[],
int DPPPerPlane[],
double HRatio[],
double PixelClock[],
double PSCL_THROUGHPUT[],
double PSCL_THROUGHPUT_CHROMA[],
double DPPCLK[],
double BytePerPixelDETC[],
enum scan_direction_class SourceScan[],
unsigned int BlockWidth256BytesY[],
unsigned int BlockHeight256BytesY[],
unsigned int BlockWidth256BytesC[],
unsigned int BlockHeight256BytesC[],
double DisplayPipeLineDeliveryTimeLuma[],
double DisplayPipeLineDeliveryTimeChroma[],
double DisplayPipeLineDeliveryTimeLumaPrefetch[],
double DisplayPipeLineDeliveryTimeChromaPrefetch[],
double DisplayPipeRequestDeliveryTimeLuma[],
double DisplayPipeRequestDeliveryTimeChroma[],
double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
double DisplayPipeRequestDeliveryTimeChromaPrefetch[]);
static void CalculateMetaAndPTETimes(
unsigned int NumberOfActivePlanes,
bool GPUVMEnable,
unsigned int MetaChunkSize,
unsigned int MinMetaChunkSizeBytes,
unsigned int GPUVMMaxPageTableLevels,
unsigned int HTotal[],
double VRatio[],
double VRatioPrefetchY[],
double VRatioPrefetchC[],
double DestinationLinesToRequestRowInVBlank[],
double DestinationLinesToRequestRowInImmediateFlip[],
double DestinationLinesToRequestVMInVBlank[],
double DestinationLinesToRequestVMInImmediateFlip[],
bool DCCEnable[],
double PixelClock[],
double BytePerPixelDETY[],
double BytePerPixelDETC[],
enum scan_direction_class SourceScan[],
unsigned int dpte_row_height[],
unsigned int dpte_row_height_chroma[],
unsigned int meta_row_width[],
unsigned int meta_row_height[],
unsigned int meta_req_width[],
unsigned int meta_req_height[],
int dpte_group_bytes[],
unsigned int PTERequestSizeY[],
unsigned int PTERequestSizeC[],
unsigned int PixelPTEReqWidthY[],
unsigned int PixelPTEReqHeightY[],
unsigned int PixelPTEReqWidthC[],
unsigned int PixelPTEReqHeightC[],
unsigned int dpte_row_width_luma_ub[],
unsigned int dpte_row_width_chroma_ub[],
unsigned int vm_group_bytes[],
unsigned int dpde0_bytes_per_frame_ub_l[],
unsigned int dpde0_bytes_per_frame_ub_c[],
unsigned int meta_pte_bytes_per_frame_ub_l[],
unsigned int meta_pte_bytes_per_frame_ub_c[],
double DST_Y_PER_PTE_ROW_NOM_L[],
double DST_Y_PER_PTE_ROW_NOM_C[],
double DST_Y_PER_META_ROW_NOM_L[],
double TimePerMetaChunkNominal[],
double TimePerMetaChunkVBlank[],
double TimePerMetaChunkFlip[],
double time_per_pte_group_nom_luma[],
double time_per_pte_group_vblank_luma[],
double time_per_pte_group_flip_luma[],
double time_per_pte_group_nom_chroma[],
double time_per_pte_group_vblank_chroma[],
double time_per_pte_group_flip_chroma[],
double TimePerVMGroupVBlank[],
double TimePerVMGroupFlip[],
double TimePerVMRequestVBlank[],
double TimePerVMRequestFlip[]);
static double CalculateExtraLatency(
double UrgentRoundTripAndOutOfOrderLatency,
int TotalNumberOfActiveDPP,
int PixelChunkSizeInKByte,
int TotalNumberOfDCCActiveDPP,
int MetaChunkSize,
double ReturnBW,
bool GPUVMEnable,
bool HostVMEnable,
int NumberOfActivePlanes,
int NumberOfDPP[],
int dpte_group_bytes[],
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
int HostVMMaxPageTableLevels,
int HostVMCachedPageTableLevels);
void dml21_recalculate(struct display_mode_lib *mode_lib)
{
ModeSupportAndSystemConfiguration(mode_lib);
PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
DisplayPipeConfiguration(mode_lib);
DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
}
static unsigned int dscceComputeDelay(
unsigned int bpc,
double bpp,
unsigned int sliceWidth,
unsigned int numSlices,
enum output_format_class pixelFormat)
{
unsigned int rcModelSize = 8192;
unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, S, ix, wx, p, l0, a, ax, l,
Delay, pixels;
if (pixelFormat == dm_n422 || pixelFormat == dm_420)
pixelsPerClock = 2;
else
pixelsPerClock = 1;
initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
if (bpc == 8)
D = 81;
else if (bpc == 10)
D = 89;
else
D = 113;
w = sliceWidth / pixelsPerClock;
if (pixelFormat == dm_s422)
S = 1;
else
S = 0;
ix = initalXmitDelay + 45;
wx = (w + 2) / 3;
p = 3 * wx - w;
l0 = ix / w;
a = ix + p * l0;
ax = (a + 2) / 3 + D + 6 + 1;
l = (ax + wx - 1) / wx;
if ((ix % w) == 0 && p != 0)
lstall = 1;
else
lstall = 0;
Delay = l * wx * (numSlices - 1) + ax + S + lstall + 22;
pixels = Delay * 3 * pixelsPerClock;
return pixels;
}
static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
{
unsigned int Delay = 0;
if (pixelFormat == dm_420) {
Delay = Delay + 2;
Delay = Delay + 0;
Delay = Delay + 3;
Delay = Delay + 2;
Delay = Delay + 12;
Delay = Delay + 13;
Delay = Delay + 2;
Delay = Delay + 7;
Delay = Delay + 3;
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 1;
} else if (pixelFormat == dm_n422) {
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 5;
Delay = Delay + 25;
Delay = Delay + 2;
Delay = Delay + 10;
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 1;
} else {
Delay = Delay + 2;
Delay = Delay + 0;
Delay = Delay + 3;
Delay = Delay + 12;
Delay = Delay + 2;
Delay = Delay + 7;
Delay = Delay + 1;
Delay = Delay + 2;
Delay = Delay + 1;
}
return Delay;
}
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
Pipe *myPipe,
unsigned int DSCDelay,
double DPPCLKDelaySubtotal,
double DPPCLKDelaySCL,
double DPPCLKDelaySCLLBOnly,
double DPPCLKDelayCNVCFormater,
double DPPCLKDelayCNVCCursor,
double DISPCLKDelaySubtotal,
unsigned int ScalerRecoutWidth,
enum output_format_class OutputFormat,
unsigned int MaxInterDCNTileRepeaters,
unsigned int VStartup,
unsigned int MaxVStartup,
unsigned int GPUVMPageTableLevels,
bool GPUVMEnable,
HostVM *myHostVM,
bool DynamicMetadataEnable,
int DynamicMetadataLinesBeforeActiveRequired,
unsigned int DynamicMetadataTransmittedBytes,
bool DCCEnable,
double UrgentLatency,
double UrgentExtraLatency,
double TCalc,
unsigned int PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
double PrefetchSourceLinesY,
unsigned int SwathWidthY,
double BytePerPixelDETY,
double VInitPreFillY,
unsigned int MaxNumSwathY,
double PrefetchSourceLinesC,
double BytePerPixelDETC,
double VInitPreFillC,
unsigned int MaxNumSwathC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
double TWait,
bool XFCEnabled,
double XFCRemoteSurfaceFlipDelay,
bool ProgressiveToInterlaceUnitInOPP,
double *DSTXAfterScaler,
double *DSTYAfterScaler,
double *DestinationLinesForPrefetch,
double *PrefetchBandwidth,
double *DestinationLinesToRequestVMInVBlank,
double *DestinationLinesToRequestRowInVBlank,
double *VRatioPrefetchY,
double *VRatioPrefetchC,
double *RequiredPrefetchPixDataBWLuma,
double *RequiredPrefetchPixDataBWChroma,
unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
double *Tno_bw,
double *prefetch_vmrow_bw,
unsigned int *swath_width_luma_ub,
unsigned int *swath_width_chroma_ub,
unsigned int *VUpdateOffsetPix,
double *VUpdateWidthPix,
double *VReadyOffsetPix)
{
bool MyError = false;
unsigned int DPPCycles, DISPCLKCycles;
double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
double Tdm, LineTime, Tsetup;
double dst_y_prefetch_equ;
double Tsw_oto;
double prefetch_bw_oto;
double Tvm_oto;
double Tr0_oto;
double Tvm_oto_lines;
double Tr0_oto_lines;
double Tsw_oto_lines;
double dst_y_prefetch_oto;
double TimeForFetchingMetaPTE = 0;
double TimeForFetchingRowInVBlank = 0;
double LinesToRequestPrefetchPixelData = 0;
double HostVMInefficiencyFactor;
unsigned int HostVMDynamicLevels;
if (GPUVMEnable == true && myHostVM->Enable == true) {
HostVMInefficiencyFactor =
PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData
/ PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
HostVMDynamicLevels = myHostVM->MaxPageTableLevels
- myHostVM->CachedPageTableLevels;
} else {
HostVMInefficiencyFactor = 1;
HostVMDynamicLevels = 0;
}
if (myPipe->ScalerEnabled)
DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
else
DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + myPipe->NumberOfCursors * DPPCLKDelayCNVCCursor;
DISPCLKCycles = DISPCLKDelaySubtotal;
if (myPipe->DPPCLK == 0.0 || myPipe->DISPCLK == 0.0)
return true;
*DSTXAfterScaler = DPPCycles * myPipe->PixelClock / myPipe->DPPCLK
+ DISPCLKCycles * myPipe->PixelClock / myPipe->DISPCLK + DSCDelay;
if (myPipe->DPPPerPlane > 1)
*DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
if (OutputFormat == dm_420 || (myPipe->InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
*DSTYAfterScaler = 1;
else
*DSTYAfterScaler = 0;
DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * myPipe->HTotal)) + *DSTXAfterScaler;
*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / myPipe->HTotal, 1);
*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * myPipe->HTotal));
*VUpdateOffsetPix = dml_ceil(myPipe->HTotal / 4.0, 1);
TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / myPipe->DPPCLK + 3.0 / myPipe->DISPCLK);
*VUpdateWidthPix = (14.0 / myPipe->DCFCLKDeepSleep + 12.0 / myPipe->DPPCLK + TotalRepeaterDelayTime)
* myPipe->PixelClock;
*VReadyOffsetPix = dml_max(
150.0 / myPipe->DPPCLK,
TotalRepeaterDelayTime + 20.0 / myPipe->DCFCLKDeepSleep + 10.0 / myPipe->DPPCLK)
* myPipe->PixelClock;
Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / myPipe->PixelClock;
LineTime = (double) myPipe->HTotal / myPipe->PixelClock;
if (DynamicMetadataEnable) {
double Tdmbf, Tdmec, Tdmsks;
Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / myPipe->DISPCLK;
Tdmec = LineTime;
if (DynamicMetadataLinesBeforeActiveRequired == -1)
Tdmsks = myPipe->VBlank * LineTime / 2.0;
else
Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
if (myPipe->InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
Tdmsks = Tdmsks / 2;
if (VStartup * LineTime
< Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
MyError = true;
*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
+ UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
} else
*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
} else
Tdm = 0;
if (GPUVMEnable) {
if (GPUVMPageTableLevels >= 3)
*Tno_bw = UrgentExtraLatency + UrgentLatency * ((GPUVMPageTableLevels - 2) * (myHostVM->MaxPageTableLevels + 1) - 1);
else
*Tno_bw = 0;
} else if (!DCCEnable)
*Tno_bw = LineTime;
else
*Tno_bw = LineTime / 4;
dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
- (Tsetup + Tdm) / LineTime
- (*DSTYAfterScaler + *DSTXAfterScaler / myPipe->HTotal);
Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
if (myPipe->SourceScan == dm_horz) {
*swath_width_luma_ub = dml_ceil(SwathWidthY - 1, myPipe->BlockWidth256BytesY) + myPipe->BlockWidth256BytesY;
if (myPipe->BlockWidth256BytesC > 0)
*swath_width_chroma_ub = dml_ceil(SwathWidthY / 2 - 1, myPipe->BlockWidth256BytesC) + myPipe->BlockWidth256BytesC;
} else {
*swath_width_luma_ub = dml_ceil(SwathWidthY - 1, myPipe->BlockHeight256BytesY) + myPipe->BlockHeight256BytesY;
if (myPipe->BlockHeight256BytesC > 0)
*swath_width_chroma_ub = dml_ceil(SwathWidthY / 2 - 1, myPipe->BlockHeight256BytesC) + myPipe->BlockHeight256BytesC;
}
prefetch_bw_oto = (PrefetchSourceLinesY * *swath_width_luma_ub * dml_ceil(BytePerPixelDETY, 1) + PrefetchSourceLinesC * *swath_width_chroma_ub * dml_ceil(BytePerPixelDETC, 2)) / Tsw_oto;
if (GPUVMEnable == true) {
Tvm_oto = dml_max(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_oto,
dml_max(UrgentExtraLatency + UrgentLatency * (GPUVMPageTableLevels * (HostVMDynamicLevels + 1) - 1),
LineTime / 4.0));
} else
Tvm_oto = LineTime / 4.0;
if ((GPUVMEnable == true || DCCEnable == true)) {
Tr0_oto = dml_max(
(MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_oto,
dml_max(UrgentLatency * (HostVMDynamicLevels + 1), dml_max(LineTime - Tvm_oto, LineTime / 4)));
} else
Tr0_oto = (LineTime - Tvm_oto) / 2.0;
Tvm_oto_lines = dml_ceil(4 * Tvm_oto / LineTime, 1) / 4.0;
Tr0_oto_lines = dml_ceil(4 * Tr0_oto / LineTime, 1) / 4.0;
Tsw_oto_lines = dml_ceil(4 * Tsw_oto / LineTime, 1) / 4.0;
dst_y_prefetch_oto = Tvm_oto_lines + 2 * Tr0_oto_lines + Tsw_oto_lines + 0.75;
dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0;
if (dst_y_prefetch_oto < dst_y_prefetch_equ)
*DestinationLinesForPrefetch = dst_y_prefetch_oto;
else
*DestinationLinesForPrefetch = dst_y_prefetch_equ;
*DestinationLinesForPrefetch = dml_min(*DestinationLinesForPrefetch, 63.75);
dml_print("DML: VStartup: %d\n", VStartup);
dml_print("DML: TCalc: %f\n", TCalc);
dml_print("DML: TWait: %f\n", TWait);
dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
dml_print("DML: LineTime: %f\n", LineTime);
dml_print("DML: Tsetup: %f\n", Tsetup);
dml_print("DML: Tdm: %f\n", Tdm);
dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler);
dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler);
dml_print("DML: HTotal: %d\n", myPipe->HTotal);
*PrefetchBandwidth = 0;
*DestinationLinesToRequestVMInVBlank = 0;
*DestinationLinesToRequestRowInVBlank = 0;
*VRatioPrefetchY = 0;
*VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBWLuma = 0;
if (*DestinationLinesForPrefetch > 1) {
double PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte
+ 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
+ PrefetchSourceLinesY * *swath_width_luma_ub * dml_ceil(BytePerPixelDETY, 1)
+ PrefetchSourceLinesC * *swath_width_chroma_ub * dml_ceil(BytePerPixelDETC, 2))
/ (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
double PrefetchBandwidth2 = (PDEAndMetaPTEBytesFrame *
HostVMInefficiencyFactor + PrefetchSourceLinesY *
*swath_width_luma_ub * dml_ceil(BytePerPixelDETY, 1) +
PrefetchSourceLinesC * *swath_width_chroma_ub *
dml_ceil(BytePerPixelDETC, 2)) /
(*DestinationLinesForPrefetch * LineTime - *Tno_bw - 2 *
UrgentLatency * (1 + HostVMDynamicLevels));
double PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow
* HostVMInefficiencyFactor + PrefetchSourceLinesY *
*swath_width_luma_ub * dml_ceil(BytePerPixelDETY, 1) +
PrefetchSourceLinesC * *swath_width_chroma_ub *
dml_ceil(BytePerPixelDETC, 2)) /
(*DestinationLinesForPrefetch * LineTime -
UrgentExtraLatency - UrgentLatency * (GPUVMPageTableLevels
* (HostVMDynamicLevels + 1) - 1));
double PrefetchBandwidth4 = (PrefetchSourceLinesY * *swath_width_luma_ub *
dml_ceil(BytePerPixelDETY, 1) + PrefetchSourceLinesC *
*swath_width_chroma_ub * dml_ceil(BytePerPixelDETC, 2)) /
(*DestinationLinesForPrefetch * LineTime -
UrgentExtraLatency - UrgentLatency * (GPUVMPageTableLevels
* (HostVMDynamicLevels + 1) - 1) - 2 * UrgentLatency *
(1 + HostVMDynamicLevels));
if (VStartup == MaxVStartup && (PrefetchBandwidth1 > 4 * prefetch_bw_oto) && (*DestinationLinesForPrefetch - dml_ceil(Tsw_oto_lines, 1) / 4.0 - 0.75) * LineTime - *Tno_bw > 0) {
PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor) / ((*DestinationLinesForPrefetch - dml_ceil(Tsw_oto_lines, 1) / 4.0 - 0.75) * LineTime - *Tno_bw);
}
if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth1 >= UrgentExtraLatency + UrgentLatency * (GPUVMPageTableLevels * (HostVMDynamicLevels + 1) - 1) && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth1 >= UrgentLatency * (1 + HostVMDynamicLevels)) {
*PrefetchBandwidth = PrefetchBandwidth1;
} else if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth2 >= UrgentExtraLatency + UrgentLatency * (GPUVMPageTableLevels * (HostVMDynamicLevels + 1) - 1) && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth2 < UrgentLatency * (1 + HostVMDynamicLevels)) {
*PrefetchBandwidth = PrefetchBandwidth2;
} else if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth3 < UrgentExtraLatency + UrgentLatency * (GPUVMPageTableLevels * (HostVMDynamicLevels + 1) - 1) && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth3 >= UrgentLatency * (1 + HostVMDynamicLevels)) {
*PrefetchBandwidth = PrefetchBandwidth3;
} else {
*PrefetchBandwidth = PrefetchBandwidth4;
}
if (GPUVMEnable) {
TimeForFetchingMetaPTE = dml_max(*Tno_bw + (double) PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / *PrefetchBandwidth,
dml_max(UrgentExtraLatency + UrgentLatency * (GPUVMPageTableLevels * (HostVMDynamicLevels + 1) - 1), LineTime / 4));
} else {
TimeForFetchingMetaPTE = LineTime / 4;
}
if ((GPUVMEnable == true || DCCEnable == true)) {
TimeForFetchingRowInVBlank =
dml_max(
(MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor)
/ *PrefetchBandwidth,
dml_max(
UrgentLatency * (1 + HostVMDynamicLevels),
dml_max(
(LineTime
- TimeForFetchingMetaPTE) / 2.0,
LineTime
/ 4.0)));
} else {
TimeForFetchingRowInVBlank = (LineTime - TimeForFetchingMetaPTE) / 2.0;
}
*DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
*DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0;
LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch
- ((GPUVMEnable || DCCEnable) ?
(*DestinationLinesToRequestVMInVBlank + 2 * *DestinationLinesToRequestRowInVBlank) :
0.0);
if (LinesToRequestPrefetchPixelData > 0) {
*VRatioPrefetchY = (double) PrefetchSourceLinesY
/ LinesToRequestPrefetchPixelData;
*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
*VRatioPrefetchY =
dml_max(
(double) PrefetchSourceLinesY
/ LinesToRequestPrefetchPixelData,
(double) MaxNumSwathY
* SwathHeightY
/ (LinesToRequestPrefetchPixelData
- (VInitPreFillY
- 3.0)
/ 2.0));
*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
} else {
MyError = true;
*VRatioPrefetchY = 0;
}
}
*VRatioPrefetchC = (double) PrefetchSourceLinesC
/ LinesToRequestPrefetchPixelData;
*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
if ((SwathHeightC > 4)) {
if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
*VRatioPrefetchC =
dml_max(
*VRatioPrefetchC,
(double) MaxNumSwathC
* SwathHeightC
/ (LinesToRequestPrefetchPixelData
- (VInitPreFillC
- 3.0)
/ 2.0));
*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
} else {
MyError = true;
*VRatioPrefetchC = 0;
}
}
*RequiredPrefetchPixDataBWLuma = myPipe->DPPPerPlane
* (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData
* dml_ceil(BytePerPixelDETY, 1)
* *swath_width_luma_ub / LineTime;
*RequiredPrefetchPixDataBWChroma = myPipe->DPPPerPlane
* (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData
* dml_ceil(BytePerPixelDETC, 2)
* *swath_width_chroma_ub / LineTime;
} else {
MyError = true;
*VRatioPrefetchY = 0;
*VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBWLuma = 0;
*RequiredPrefetchPixDataBWChroma = 0;
}
dml_print("DML: Tvm: %fus\n", TimeForFetchingMetaPTE);
dml_print("DML: Tr0: %fus\n", TimeForFetchingRowInVBlank);
dml_print("DML: Tsw: %fus\n", (double)(*DestinationLinesForPrefetch) * LineTime - TimeForFetchingMetaPTE - TimeForFetchingRowInVBlank);
dml_print("DML: Tpre: %fus\n", (double)(*DestinationLinesForPrefetch) * LineTime);
dml_print("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %d\n", PixelPTEBytesPerRow);
} else {
MyError = true;
}
{
double prefetch_vm_bw;
double prefetch_row_bw;
if (PDEAndMetaPTEBytesFrame == 0) {
prefetch_vm_bw = 0;
} else if (*DestinationLinesToRequestVMInVBlank > 0) {
prefetch_vm_bw = PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInVBlank * LineTime);
} else {
prefetch_vm_bw = 0;
MyError = true;
}
if (MetaRowByte + PixelPTEBytesPerRow == 0) {
prefetch_row_bw = 0;
} else if (*DestinationLinesToRequestRowInVBlank > 0) {
prefetch_row_bw = (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInVBlank * LineTime);
} else {
prefetch_row_bw = 0;
MyError = true;
}
*prefetch_vmrow_bw = dml_max(prefetch_vm_bw, prefetch_row_bw);
}
if (MyError) {
*PrefetchBandwidth = 0;
TimeForFetchingMetaPTE = 0;
TimeForFetchingRowInVBlank = 0;
*DestinationLinesToRequestVMInVBlank = 0;
*DestinationLinesToRequestRowInVBlank = 0;
*DestinationLinesForPrefetch = 0;
LinesToRequestPrefetchPixelData = 0;
*VRatioPrefetchY = 0;
*VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBWLuma = 0;
*RequiredPrefetchPixDataBWChroma = 0;
}
return MyError;
}
static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
{
return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
}
static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
{
return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
}
static double CalculateDCCConfiguration(
bool DCCEnabled,
bool DCCProgrammingAssumesScanDirectionUnknown,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int DETBufferSize,
unsigned int RequestHeight256Byte,
unsigned int SwathHeight,
enum dm_swizzle_mode TilingFormat,
unsigned int BytePerPixel,
enum scan_direction_class ScanOrientation,
unsigned int *MaxUncompressedBlock,
unsigned int *MaxCompressedBlock,
unsigned int *Independent64ByteBlock)
{
double MaximumDCCCompressionSurface = 0.0;
enum {
REQ_256Bytes,
REQ_128BytesNonContiguous,
REQ_128BytesContiguous,
REQ_NA
} Request = REQ_NA;
if (DCCEnabled == true) {
if (DCCProgrammingAssumesScanDirectionUnknown == true) {
if (DETBufferSize >= RequestHeight256Byte * ViewportWidth * BytePerPixel
&& DETBufferSize
>= 256 / RequestHeight256Byte
* ViewportHeight) {
Request = REQ_256Bytes;
} else if ((DETBufferSize
< RequestHeight256Byte * ViewportWidth * BytePerPixel
&& (BytePerPixel == 2 || BytePerPixel == 4))
|| (DETBufferSize
< 256 / RequestHeight256Byte
* ViewportHeight
&& BytePerPixel == 8
&& (TilingFormat == dm_sw_4kb_d
|| TilingFormat
== dm_sw_4kb_d_x
|| TilingFormat
== dm_sw_var_d
|| TilingFormat
== dm_sw_var_d_x
|| TilingFormat
== dm_sw_64kb_d
|| TilingFormat
== dm_sw_64kb_d_x
|| TilingFormat
== dm_sw_64kb_d_t
|| TilingFormat
== dm_sw_64kb_r_x))) {
Request = REQ_128BytesNonContiguous;
} else {
Request = REQ_128BytesContiguous;
}
} else {
if (BytePerPixel == 1) {
if (ScanOrientation == dm_vert || SwathHeight == 16) {
Request = REQ_256Bytes;
} else {
Request = REQ_128BytesContiguous;
}
} else if (BytePerPixel == 2) {
if ((ScanOrientation == dm_vert && SwathHeight == 16) || (ScanOrientation != dm_vert && SwathHeight == 8)) {
Request = REQ_256Bytes;
} else if (ScanOrientation == dm_vert) {
Request = REQ_128BytesContiguous;
} else {
Request = REQ_128BytesNonContiguous;
}
} else if (BytePerPixel == 4) {
if (SwathHeight == 8) {
Request = REQ_256Bytes;
} else if (ScanOrientation == dm_vert) {
Request = REQ_128BytesContiguous;
} else {
Request = REQ_128BytesNonContiguous;
}
} else if (BytePerPixel == 8) {
if (TilingFormat == dm_sw_4kb_d || TilingFormat == dm_sw_4kb_d_x
|| TilingFormat == dm_sw_var_d
|| TilingFormat == dm_sw_var_d_x
|| TilingFormat == dm_sw_64kb_d
|| TilingFormat == dm_sw_64kb_d_x
|| TilingFormat == dm_sw_64kb_d_t
|| TilingFormat == dm_sw_64kb_r_x) {
if ((ScanOrientation == dm_vert && SwathHeight == 8)
|| (ScanOrientation != dm_vert
&& SwathHeight == 4)) {
Request = REQ_256Bytes;
} else if (ScanOrientation != dm_vert) {
Request = REQ_128BytesContiguous;
} else {
Request = REQ_128BytesNonContiguous;
}
} else {
if (ScanOrientation != dm_vert || SwathHeight == 8) {
Request = REQ_256Bytes;
} else {
Request = REQ_128BytesContiguous;
}
}
}
}
} else {
Request = REQ_NA;
}
if (Request == REQ_256Bytes) {
*MaxUncompressedBlock = 256;
*MaxCompressedBlock = 256;
*Independent64ByteBlock = false;
MaximumDCCCompressionSurface = 4.0;
} else if (Request == REQ_128BytesContiguous) {
*MaxUncompressedBlock = 128;
*MaxCompressedBlock = 128;
*Independent64ByteBlock = false;
MaximumDCCCompressionSurface = 2.0;
} else if (Request == REQ_128BytesNonContiguous) {
*MaxUncompressedBlock = 256;
*MaxCompressedBlock = 64;
*Independent64ByteBlock = true;
MaximumDCCCompressionSurface = 4.0;
} else {
*MaxUncompressedBlock = 0;
*MaxCompressedBlock = 0;
*Independent64ByteBlock = 0;
MaximumDCCCompressionSurface = 0.0;
}
return MaximumDCCCompressionSurface;
}
static double CalculatePrefetchSourceLines(
struct display_mode_lib *mode_lib,
double VRatio,
double vtaps,
bool Interlace,
bool ProgressiveToInterlaceUnitInOPP,
unsigned int SwathHeight,
unsigned int ViewportYStart,
double *VInitPreFill,
unsigned int *MaxNumSwath)
{
unsigned int MaxPartialSwath;
if (ProgressiveToInterlaceUnitInOPP)
*VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
else
*VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
if (!mode_lib->vba.IgnoreViewportPositioning) {
*MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
if (*VInitPreFill > 1.0)
MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
else
MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
% SwathHeight;
MaxPartialSwath = dml_max(1U, MaxPartialSwath);
} else {
if (ViewportYStart != 0)
dml_print(
"WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
*MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
if (*VInitPreFill > 1.0)
MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
else
MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
% SwathHeight;
}
return *MaxNumSwath * SwathHeight + MaxPartialSwath;
}
static unsigned int CalculateVMAndRowBytes(
struct display_mode_lib *mode_lib,
bool DCCEnable,
unsigned int BlockHeight256Bytes,
unsigned int BlockWidth256Bytes,
enum source_format_class SourcePixelFormat,
unsigned int SurfaceTiling,
unsigned int BytePerPixel,
enum scan_direction_class ScanDirection,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int SwathWidth,
bool GPUVMEnable,
bool HostVMEnable,
unsigned int HostVMMaxPageTableLevels,
unsigned int HostVMCachedPageTableLevels,
unsigned int VMMPageSize,
unsigned int PTEBufferSizeInRequests,
unsigned int Pitch,
unsigned int DCCMetaPitch,
unsigned int *MacroTileWidth,
unsigned int *MetaRowByte,
unsigned int *PixelPTEBytesPerRow,
bool *PTEBufferSizeNotExceeded,
unsigned int *dpte_row_width_ub,
unsigned int *dpte_row_height,
unsigned int *MetaRequestWidth,
unsigned int *MetaRequestHeight,
unsigned int *meta_row_width,
unsigned int *meta_row_height,
unsigned int *vm_group_bytes,
unsigned int *dpte_group_bytes,
unsigned int *PixelPTEReqWidth,
unsigned int *PixelPTEReqHeight,
unsigned int *PTERequestSize,
unsigned int *DPDE0BytesFrame,
unsigned int *MetaPTEBytesFrame)
{
unsigned int MPDEBytesFrame;
unsigned int DCCMetaSurfaceBytes;
unsigned int MacroTileSizeBytes;
unsigned int MacroTileHeight;
unsigned int ExtraDPDEBytesFrame;
unsigned int PDEAndMetaPTEBytesFrame;
unsigned int PixelPTEReqHeightPTEs = 0;
if (DCCEnable == true) {
*MetaRequestHeight = 8 * BlockHeight256Bytes;
*MetaRequestWidth = 8 * BlockWidth256Bytes;
if (ScanDirection == dm_horz) {
*meta_row_height = *MetaRequestHeight;
*meta_row_width = dml_ceil((double) SwathWidth - 1, *MetaRequestWidth)
+ *MetaRequestWidth;
*MetaRowByte = *meta_row_width * *MetaRequestHeight * BytePerPixel / 256.0;
} else {
*meta_row_height = *MetaRequestWidth;
*meta_row_width = dml_ceil((double) SwathWidth - 1, *MetaRequestHeight)
+ *MetaRequestHeight;
*MetaRowByte = *meta_row_width * *MetaRequestWidth * BytePerPixel / 256.0;
}
if (ScanDirection == dm_horz) {
DCCMetaSurfaceBytes = DCCMetaPitch
* (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
+ 64 * BlockHeight256Bytes) * BytePerPixel
/ 256;
} else {
DCCMetaSurfaceBytes = DCCMetaPitch
* (dml_ceil(
(double) ViewportHeight - 1,
64 * BlockHeight256Bytes)
+ 64 * BlockHeight256Bytes) * BytePerPixel
/ 256;
}
if (GPUVMEnable == true) {
*MetaPTEBytesFrame = (dml_ceil(
(double) (DCCMetaSurfaceBytes - VMMPageSize)
/ (8 * VMMPageSize),
1) + 1) * 64;
MPDEBytesFrame = 128 * ((mode_lib->vba.GPUVMMaxPageTableLevels + 1) * (mode_lib->vba.HostVMMaxPageTableLevels + 1) - 2);
} else {
*MetaPTEBytesFrame = 0;
MPDEBytesFrame = 0;
}
} else {
*MetaPTEBytesFrame = 0;
MPDEBytesFrame = 0;
*MetaRowByte = 0;
}
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) {
MacroTileSizeBytes = 256;
MacroTileHeight = BlockHeight256Bytes;
} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
|| SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
MacroTileSizeBytes = 4096;
MacroTileHeight = 4 * BlockHeight256Bytes;
} else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
|| SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
|| SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
|| SurfaceTiling == dm_sw_64kb_r_x) {
MacroTileSizeBytes = 65536;
MacroTileHeight = 16 * BlockHeight256Bytes;
} else {
MacroTileSizeBytes = 262144;
MacroTileHeight = 32 * BlockHeight256Bytes;
}
*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
if (GPUVMEnable == true && (mode_lib->vba.GPUVMMaxPageTableLevels + 1) * (mode_lib->vba.HostVMMaxPageTableLevels + 1) > 2) {
if (ScanDirection == dm_horz) {
*DPDE0BytesFrame = 64 * (dml_ceil(((Pitch * (dml_ceil(ViewportHeight - 1, MacroTileHeight) + MacroTileHeight) * BytePerPixel) - MacroTileSizeBytes) / (8 * 2097152), 1) + 1);
} else {
*DPDE0BytesFrame = 64 * (dml_ceil(((Pitch * (dml_ceil((double) SwathWidth - 1, MacroTileHeight) + MacroTileHeight) * BytePerPixel) - MacroTileSizeBytes) / (8 * 2097152), 1) + 1);
}
ExtraDPDEBytesFrame = 128 * ((mode_lib->vba.GPUVMMaxPageTableLevels + 1) * (mode_lib->vba.HostVMMaxPageTableLevels + 1) - 3);
} else {
*DPDE0BytesFrame = 0;
ExtraDPDEBytesFrame = 0;
}
PDEAndMetaPTEBytesFrame = *MetaPTEBytesFrame + MPDEBytesFrame + *DPDE0BytesFrame
+ ExtraDPDEBytesFrame;
if (HostVMEnable == true) {
PDEAndMetaPTEBytesFrame = PDEAndMetaPTEBytesFrame * (1 + 8 * (HostVMMaxPageTableLevels - HostVMCachedPageTableLevels));
}
if (GPUVMEnable == true) {
double FractionOfPTEReturnDrop;
if (SurfaceTiling == dm_sw_linear) {
PixelPTEReqHeightPTEs = 1;
*PixelPTEReqHeight = 1;
*PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
*PTERequestSize = 64;
FractionOfPTEReturnDrop = 0;
} else if (MacroTileSizeBytes == 4096) {
PixelPTEReqHeightPTEs = 1;
*PixelPTEReqHeight = MacroTileHeight;
*PixelPTEReqWidth = 8 * *MacroTileWidth;
*PTERequestSize = 64;
if (ScanDirection == dm_horz)
FractionOfPTEReturnDrop = 0;
else
FractionOfPTEReturnDrop = 7 / 8;
} else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
PixelPTEReqHeightPTEs = 16;
*PixelPTEReqHeight = 16 * BlockHeight256Bytes;
*PixelPTEReqWidth = 16 * BlockWidth256Bytes;
*PTERequestSize = 128;
FractionOfPTEReturnDrop = 0;
} else {
PixelPTEReqHeightPTEs = 1;
*PixelPTEReqHeight = MacroTileHeight;
*PixelPTEReqWidth = 8 * *MacroTileWidth;
*PTERequestSize = 64;
FractionOfPTEReturnDrop = 0;
}
if (SurfaceTiling == dm_sw_linear) {
*dpte_row_height = dml_min(128,
1 << (unsigned int) dml_floor(
dml_log2(
(double) PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch),
1));
*dpte_row_width_ub = (dml_ceil((double) (Pitch * *dpte_row_height - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
} else if (ScanDirection == dm_horz) {
*dpte_row_height = *PixelPTEReqHeight;
*dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
} else {
*dpte_row_height = dml_min(*PixelPTEReqWidth, *MacroTileWidth);
*dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqHeight, 1) + 1) * *PixelPTEReqHeight;
*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqHeight * *PTERequestSize;
}
if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
<= 64 * PTEBufferSizeInRequests) {
*PTEBufferSizeNotExceeded = true;
} else {
*PTEBufferSizeNotExceeded = false;
}
} else {
*PixelPTEBytesPerRow = 0;
*PTEBufferSizeNotExceeded = true;
}
dml_print("DML: vm_bytes = meta_pte_bytes_per_frame (per_pipe) = MetaPTEBytesFrame = : %d\n", *MetaPTEBytesFrame);
if (HostVMEnable == true) {
*PixelPTEBytesPerRow = *PixelPTEBytesPerRow * (1 + 8 * (HostVMMaxPageTableLevels - HostVMCachedPageTableLevels));
}
if (HostVMEnable == true) {
*vm_group_bytes = 512;
*dpte_group_bytes = 512;
} else if (GPUVMEnable == true) {
*vm_group_bytes = 2048;
if (SurfaceTiling != dm_sw_linear && PixelPTEReqHeightPTEs == 1 && ScanDirection != dm_horz) {
*dpte_group_bytes = 512;
} else {
*dpte_group_bytes = 2048;
}
} else {
*vm_group_bytes = 0;
*dpte_group_bytes = 0;
}
return PDEAndMetaPTEBytesFrame;
}
static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
struct display_mode_lib *mode_lib)
{
struct vba_vars_st *locals = &mode_lib->vba;
unsigned int j, k;
mode_lib->vba.WritebackDISPCLK = 0.0;
mode_lib->vba.DISPCLKWithRamping = 0;
mode_lib->vba.DISPCLKWithoutRamping = 0;
mode_lib->vba.GlobalDPPCLK = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.WritebackEnable[k]) {
mode_lib->vba.WritebackDISPCLK =
dml_max(
mode_lib->vba.WritebackDISPCLK,
CalculateWriteBackDISPCLK(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.PixelClock[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.WritebackChromaLineBufferWidth));
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.HRatio[k] > 1) {
locals->PSCL_THROUGHPUT_LUMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ dml_ceil(
mode_lib->vba.htaps[k]
/ 6.0,
1));
} else {
locals->PSCL_THROUGHPUT_LUMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
mode_lib->vba.DPPCLKUsingSingleDPPLuma =
mode_lib->vba.PixelClock[k]
* dml_max(
mode_lib->vba.vtaps[k] / 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]),
dml_max(
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ locals->PSCL_THROUGHPUT_LUMA[k],
1.0));
if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
&& mode_lib->vba.DPPCLKUsingSingleDPPLuma
< 2 * mode_lib->vba.PixelClock[k]) {
mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
}
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
locals->PSCL_THROUGHPUT_CHROMA[k] = 0.0;
locals->DPPCLKUsingSingleDPP[k] =
mode_lib->vba.DPPCLKUsingSingleDPPLuma;
} else {
if (mode_lib->vba.HRatio[k] > 1) {
locals->PSCL_THROUGHPUT_CHROMA[k] =
dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ 2
/ dml_ceil(
mode_lib->vba.HTAPsChroma[k]
/ 6.0,
1.0));
} else {
locals->PSCL_THROUGHPUT_CHROMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
mode_lib->vba.DPPCLKUsingSingleDPPChroma =
mode_lib->vba.PixelClock[k]
* dml_max(
mode_lib->vba.VTAPsChroma[k]
/ 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]
/ 2),
dml_max(
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ 4
/ locals->PSCL_THROUGHPUT_CHROMA[k],
1.0));
if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
&& mode_lib->vba.DPPCLKUsingSingleDPPChroma
< 2 * mode_lib->vba.PixelClock[k]) {
mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
* mode_lib->vba.PixelClock[k];
}
locals->DPPCLKUsingSingleDPP[k] = dml_max(
mode_lib->vba.DPPCLKUsingSingleDPPLuma,
mode_lib->vba.DPPCLKUsingSingleDPPChroma);
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.BlendingAndTiming[k] != k)
continue;
if (mode_lib->vba.ODMCombineEnabled[k]) {
mode_lib->vba.DISPCLKWithRamping =
dml_max(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.PixelClock[k] / 2
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100)
* (1
+ mode_lib->vba.DISPCLKRampingMargin
/ 100));
mode_lib->vba.DISPCLKWithoutRamping =
dml_max(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.PixelClock[k] / 2
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100));
} else if (!mode_lib->vba.ODMCombineEnabled[k]) {
mode_lib->vba.DISPCLKWithRamping =
dml_max(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.PixelClock[k]
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100)
* (1
+ mode_lib->vba.DISPCLKRampingMargin
/ 100));
mode_lib->vba.DISPCLKWithoutRamping =
dml_max(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.PixelClock[k]
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100));
}
}
mode_lib->vba.DISPCLKWithRamping = dml_max(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.WritebackDISPCLK);
mode_lib->vba.DISPCLKWithoutRamping = dml_max(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.WritebackDISPCLK);
ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
mode_lib->vba.soc.clock_limits[mode_lib->vba.soc.num_states - 1].dispclk_mhz,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
mode_lib->vba.DISPCLK_calculated =
mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
} else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
} else {
mode_lib->vba.DISPCLK_calculated =
mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
}
DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.DPPCLK_calculated[k] = locals->DPPCLKUsingSingleDPP[k]
/ mode_lib->vba.DPPPerPlane[k]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
mode_lib->vba.GlobalDPPCLK = dml_max(
mode_lib->vba.GlobalDPPCLK,
mode_lib->vba.DPPCLK_calculated[k]);
}
mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
mode_lib->vba.GlobalDPPCLK,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
* dml_ceil(
mode_lib->vba.DPPCLK_calculated[k] * 255
/ mode_lib->vba.GlobalDPPCLK,
1);
DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
}
DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK);
DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN);
DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
bool MainPlaneDoesODMCombine = false;
if (mode_lib->vba.SourceScan[k] == dm_horz)
locals->SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
else
locals->SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
MainPlaneDoesODMCombine = true;
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
MainPlaneDoesODMCombine = true;
if (MainPlaneDoesODMCombine == true)
locals->SwathWidthY[k] = dml_min(
(double) locals->SwathWidthSingleDPPY[k],
dml_round(
mode_lib->vba.HActive[k] / 2.0
* mode_lib->vba.HRatio[k]));
else
locals->SwathWidthY[k] = locals->SwathWidthSingleDPPY[k]
/ mode_lib->vba.DPPPerPlane[k];
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
locals->BytePerPixelDETY[k] = 8;
locals->BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
locals->BytePerPixelDETY[k] = 4;
locals->BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
locals->BytePerPixelDETY[k] = 2;
locals->BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
locals->BytePerPixelDETY[k] = 1;
locals->BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
locals->BytePerPixelDETY[k] = 1;
locals->BytePerPixelDETC[k] = 2;
} else {
locals->BytePerPixelDETY[k] = 4.0 / 3.0;
locals->BytePerPixelDETC[k] = 8.0 / 3.0;
}
}
mode_lib->vba.TotalDataReadBandwidth = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
locals->ReadBandwidthPlaneLuma[k] = locals->SwathWidthSingleDPPY[k]
* dml_ceil(locals->BytePerPixelDETY[k], 1)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* mode_lib->vba.VRatio[k];
locals->ReadBandwidthPlaneChroma[k] = locals->SwathWidthSingleDPPY[k]
/ 2 * dml_ceil(locals->BytePerPixelDETC[k], 2)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* mode_lib->vba.VRatio[k] / 2;
DTRACE(
" read_bw[%i] = %fBps",
k,
locals->ReadBandwidthPlaneLuma[k]
+ locals->ReadBandwidthPlaneChroma[k]);
mode_lib->vba.TotalDataReadBandwidth += locals->ReadBandwidthPlaneLuma[k]
+ locals->ReadBandwidthPlaneChroma[k];
}
CalculateDCFCLKDeepSleep(
mode_lib,
mode_lib->vba.NumberOfActivePlanes,
locals->BytePerPixelDETY,
locals->BytePerPixelDETC,
mode_lib->vba.VRatio,
locals->SwathWidthY,
mode_lib->vba.DPPPerPlane,
mode_lib->vba.HRatio,
mode_lib->vba.PixelClock,
locals->PSCL_THROUGHPUT_LUMA,
locals->PSCL_THROUGHPUT_CHROMA,
locals->DPPCLK,
&mode_lib->vba.DCFCLKDeepSleep);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
locals->DSCCLK_calculated[k] = 0.0;
} else {
if (mode_lib->vba.OutputFormat[k] == dm_420
|| mode_lib->vba.OutputFormat[k] == dm_n422)
mode_lib->vba.DSCFormatFactor = 2;
else
mode_lib->vba.DSCFormatFactor = 1;
if (mode_lib->vba.ODMCombineEnabled[k])
locals->DSCCLK_calculated[k] =
mode_lib->vba.PixelClockBackEnd[k] / 6
/ mode_lib->vba.DSCFormatFactor
/ (1
- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100);
else
locals->DSCCLK_calculated[k] =
mode_lib->vba.PixelClockBackEnd[k] / 3
/ mode_lib->vba.DSCFormatFactor
/ (1
- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100);
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
double bpp = mode_lib->vba.OutputBpp[k];
unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
if (!mode_lib->vba.ODMCombineEnabled[k]) {
locals->DSCDelay[k] =
dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
bpp,
dml_ceil(
(double) mode_lib->vba.HActive[k]
/ mode_lib->vba.NumberOfDSCSlices[k],
1),
slices,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]);
} else {
locals->DSCDelay[k] =
2
* (dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
bpp,
dml_ceil(
(double) mode_lib->vba.HActive[k]
/ mode_lib->vba.NumberOfDSCSlices[k],
1),
slices / 2.0,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]));
}
locals->DSCDelay[k] = locals->DSCDelay[k]
* mode_lib->vba.PixelClock[k]
/ mode_lib->vba.PixelClockBackEnd[k];
} else {
locals->DSCDelay[k] = 0;
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.DSCEnabled[j])
locals->DSCDelay[k] = locals->DSCDelay[j];
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
unsigned int PDEAndMetaPTEBytesFrameY;
unsigned int PixelPTEBytesPerRowY;
unsigned int MetaRowByteY;
unsigned int MetaRowByteC;
unsigned int PDEAndMetaPTEBytesFrameC;
unsigned int PixelPTEBytesPerRowC;
bool PTEBufferSizeNotExceededY;
bool PTEBufferSizeNotExceededC;
Calculate256BBlockSizes(
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
dml_ceil(locals->BytePerPixelDETY[k], 1),
dml_ceil(locals->BytePerPixelDETC[k], 2),
&locals->BlockHeight256BytesY[k],
&locals->BlockHeight256BytesC[k],
&locals->BlockWidth256BytesY[k],
&locals->BlockWidth256BytesC[k]);
locals->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k],
mode_lib->vba.vtaps[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.ViewportYStartY[k],
&locals->VInitPreFillY[k],
&locals->MaxNumSwathY[k]);
if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
PDEAndMetaPTEBytesFrameC =
CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
locals->BlockHeight256BytesC[k],
locals->BlockWidth256BytesC[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
dml_ceil(
locals->BytePerPixelDETC[k],
2),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k] / 2,
mode_lib->vba.ViewportHeight[k] / 2,
locals->SwathWidthY[k] / 2,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.HostVMEnable,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequestsChroma,
mode_lib->vba.PitchC[k],
mode_lib->vba.DCCMetaPitchC[k],
&locals->MacroTileWidthC[k],
&MetaRowByteC,
&PixelPTEBytesPerRowC,
&PTEBufferSizeNotExceededC,
&locals->dpte_row_width_chroma_ub[k],
&locals->dpte_row_height_chroma[k],
&locals->meta_req_width_chroma[k],
&locals->meta_req_height_chroma[k],
&locals->meta_row_width_chroma[k],
&locals->meta_row_height_chroma[k],
&locals->vm_group_bytes_chroma,
&locals->dpte_group_bytes_chroma,
&locals->PixelPTEReqWidthC[k],
&locals->PixelPTEReqHeightC[k],
&locals->PTERequestSizeC[k],
&locals->dpde0_bytes_per_frame_ub_c[k],
&locals->meta_pte_bytes_per_frame_ub_c[k]);
locals->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k] / 2,
mode_lib->vba.VTAPsChroma[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.SwathHeightC[k],
mode_lib->vba.ViewportYStartC[k],
&locals->VInitPreFillC[k],
&locals->MaxNumSwathC[k]);
} else {
PixelPTEBytesPerRowC = 0;
PDEAndMetaPTEBytesFrameC = 0;
MetaRowByteC = 0;
locals->MaxNumSwathC[k] = 0;
locals->PrefetchSourceLinesC[k] = 0;
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
}
PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
locals->BlockHeight256BytesY[k],
locals->BlockWidth256BytesY[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
dml_ceil(locals->BytePerPixelDETY[k], 1),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k],
mode_lib->vba.ViewportHeight[k],
locals->SwathWidthY[k],
mode_lib->vba.GPUVMEnable,
mode_lib->vba.HostVMEnable,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels,
mode_lib->vba.VMMPageSize,
locals->PTEBufferSizeInRequestsForLuma,
mode_lib->vba.PitchY[k],
mode_lib->vba.DCCMetaPitchY[k],
&locals->MacroTileWidthY[k],
&MetaRowByteY,
&PixelPTEBytesPerRowY,
&PTEBufferSizeNotExceededY,
&locals->dpte_row_width_luma_ub[k],
&locals->dpte_row_height[k],
&locals->meta_req_width[k],
&locals->meta_req_height[k],
&locals->meta_row_width[k],
&locals->meta_row_height[k],
&locals->vm_group_bytes[k],
&locals->dpte_group_bytes[k],
&locals->PixelPTEReqWidthY[k],
&locals->PixelPTEReqHeightY[k],
&locals->PTERequestSizeY[k],
&locals->dpde0_bytes_per_frame_ub_l[k],
&locals->meta_pte_bytes_per_frame_ub_l[k]);
locals->PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
locals->PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
+ PDEAndMetaPTEBytesFrameC;
locals->MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
CalculateActiveRowBandwidth(
mode_lib->vba.GPUVMEnable,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.VRatio[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
MetaRowByteY,
MetaRowByteC,
locals->meta_row_height[k],
locals->meta_row_height_chroma[k],
PixelPTEBytesPerRowY,
PixelPTEBytesPerRowC,
locals->dpte_row_height[k],
locals->dpte_row_height_chroma[k],
&locals->meta_row_bw[k],
&locals->dpte_row_bw[k]);
}
mode_lib->vba.TotalDCCActiveDPP = 0;
mode_lib->vba.TotalActiveDPP = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
+ mode_lib->vba.DPPPerPlane[k];
if (mode_lib->vba.DCCEnable[k])
mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
+ mode_lib->vba.DPPPerPlane[k];
}
mode_lib->vba.UrgentOutOfOrderReturnPerChannel = dml_max3(
mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly,
mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly);
mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
(mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
+ mode_lib->vba.UrgentOutOfOrderReturnPerChannel
* mode_lib->vba.NumberOfChannels
/ mode_lib->vba.ReturnBW;
mode_lib->vba.UrgentExtraLatency = CalculateExtraLatency(
mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency,
mode_lib->vba.TotalActiveDPP,
mode_lib->vba.PixelChunkSizeInKByte,
mode_lib->vba.TotalDCCActiveDPP,
mode_lib->vba.MetaChunkSize,
mode_lib->vba.ReturnBW,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.HostVMEnable,
mode_lib->vba.NumberOfActivePlanes,
mode_lib->vba.DPPPerPlane,
locals->dpte_group_bytes,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels);
mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFCLKDeepSleep;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.WritebackEnable[k] == true) {
locals->WritebackDelay[mode_lib->vba.VoltageLevel][k] =
mode_lib->vba.WritebackLatency
+ CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k])
/ mode_lib->vba.DISPCLK;
} else
locals->WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
if (mode_lib->vba.BlendingAndTiming[j] == k
&& mode_lib->vba.WritebackEnable[j] == true) {
locals->WritebackDelay[mode_lib->vba.VoltageLevel][k] =
dml_max(
locals->WritebackDelay[mode_lib->vba.VoltageLevel][k],
mode_lib->vba.WritebackLatency
+ CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[j],
mode_lib->vba.WritebackHRatio[j],
mode_lib->vba.WritebackVRatio[j],
mode_lib->vba.WritebackLumaHTaps[j],
mode_lib->vba.WritebackLumaVTaps[j],
mode_lib->vba.WritebackChromaHTaps[j],
mode_lib->vba.WritebackChromaVTaps[j],
mode_lib->vba.WritebackDestinationWidth[j])
/ mode_lib->vba.DISPCLK);
}
}
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (mode_lib->vba.BlendingAndTiming[k] == j)
locals->WritebackDelay[mode_lib->vba.VoltageLevel][k] =
locals->WritebackDelay[mode_lib->vba.VoltageLevel][j];
mode_lib->vba.VStartupLines = 13;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
locals->MaxVStartupLines[k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k] - dml_max(1.0, dml_ceil(locals->WritebackDelay[mode_lib->vba.VoltageLevel][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1));
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
locals->MaximumMaxVStartupLines = dml_max(locals->MaximumMaxVStartupLines, locals->MaxVStartupLines[k]);
mode_lib->vba.UrgentLatency = dml_max3(mode_lib->vba.UrgentLatencyPixelDataOnly, mode_lib->vba.UrgentLatencyPixelMixedWithVMData, mode_lib->vba.UrgentLatencyVMDataOnly);
do {
double MaxTotalRDBandwidth = 0;
double MaxTotalRDBandwidthNoUrgentBurst = 0;
bool DestinationLineTimesForPrefetchLessThan2 = false;
bool VRatioPrefetchMoreThan4 = false;
double TWait = CalculateTWait(
mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatency,
mode_lib->vba.SREnterPlusExitTime);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
Pipe myPipe;
HostVM myHostVM;
if (mode_lib->vba.XFCEnabled[k] == true) {
mode_lib->vba.XFCRemoteSurfaceFlipDelay =
CalculateRemoteSurfaceFlipDelay(
mode_lib,
mode_lib->vba.VRatio[k],
locals->SwathWidthY[k],
dml_ceil(
locals->BytePerPixelDETY[k],
1),
mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k],
mode_lib->vba.XFCTSlvVupdateOffset,
mode_lib->vba.XFCTSlvVupdateWidth,
mode_lib->vba.XFCTSlvVreadyOffset,
mode_lib->vba.XFCXBUFLatencyTolerance,
mode_lib->vba.XFCFillBWOverhead,
mode_lib->vba.XFCSlvChunkSize,
mode_lib->vba.XFCBusTransportTime,
mode_lib->vba.TCalc,
TWait,
&mode_lib->vba.SrcActiveDrainRate,
&mode_lib->vba.TInitXFill,
&mode_lib->vba.TslvChk);
} else {
mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
}
myPipe.DPPCLK = locals->DPPCLK[k];
myPipe.DISPCLK = mode_lib->vba.DISPCLK;
myPipe.PixelClock = mode_lib->vba.PixelClock[k];
myPipe.DCFCLKDeepSleep = mode_lib->vba.DCFCLKDeepSleep;
myPipe.DPPPerPlane = mode_lib->vba.DPPPerPlane[k];
myPipe.ScalerEnabled = mode_lib->vba.ScalerEnabled[k];
myPipe.SourceScan = mode_lib->vba.SourceScan[k];
myPipe.BlockWidth256BytesY = locals->BlockWidth256BytesY[k];
myPipe.BlockHeight256BytesY = locals->BlockHeight256BytesY[k];
myPipe.BlockWidth256BytesC = locals->BlockWidth256BytesC[k];
myPipe.BlockHeight256BytesC = locals->BlockHeight256BytesC[k];
myPipe.InterlaceEnable = mode_lib->vba.Interlace[k];
myPipe.NumberOfCursors = mode_lib->vba.NumberOfCursors[k];
myPipe.VBlank = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k];
myPipe.HTotal = mode_lib->vba.HTotal[k];
myHostVM.Enable = mode_lib->vba.HostVMEnable;
myHostVM.MaxPageTableLevels = mode_lib->vba.HostVMMaxPageTableLevels;
myHostVM.CachedPageTableLevels = mode_lib->vba.HostVMCachedPageTableLevels;
mode_lib->vba.ErrorResult[k] =
CalculatePrefetchSchedule(
mode_lib,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
&myPipe,
locals->DSCDelay[k],
mode_lib->vba.DPPCLKDelaySubtotal,
mode_lib->vba.DPPCLKDelaySCL,
mode_lib->vba.DPPCLKDelaySCLLBOnly,
mode_lib->vba.DPPCLKDelayCNVCFormater,
mode_lib->vba.DPPCLKDelayCNVCCursor,
mode_lib->vba.DISPCLKDelaySubtotal,
(unsigned int) (locals->SwathWidthY[k]
/ mode_lib->vba.HRatio[k]),
mode_lib->vba.OutputFormat[k],
mode_lib->vba.MaxInterDCNTileRepeaters,
dml_min(mode_lib->vba.VStartupLines, locals->MaxVStartupLines[k]),
locals->MaxVStartupLines[k],
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.GPUVMEnable,
&myHostVM,
mode_lib->vba.DynamicMetadataEnable[k],
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
mode_lib->vba.DynamicMetadataTransmittedBytes[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.UrgentLatency,
mode_lib->vba.UrgentExtraLatency,
mode_lib->vba.TCalc,
locals->PDEAndMetaPTEBytesFrame[k],
locals->MetaRowByte[k],
locals->PixelPTEBytesPerRow[k],
locals->PrefetchSourceLinesY[k],
locals->SwathWidthY[k],
locals->BytePerPixelDETY[k],
locals->VInitPreFillY[k],
locals->MaxNumSwathY[k],
locals->PrefetchSourceLinesC[k],
locals->BytePerPixelDETC[k],
locals->VInitPreFillC[k],
locals->MaxNumSwathC[k],
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.SwathHeightC[k],
TWait,
mode_lib->vba.XFCEnabled[k],
mode_lib->vba.XFCRemoteSurfaceFlipDelay,
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
&locals->DSTXAfterScaler[k],
&locals->DSTYAfterScaler[k],
&locals->DestinationLinesForPrefetch[k],
&locals->PrefetchBandwidth[k],
&locals->DestinationLinesToRequestVMInVBlank[k],
&locals->DestinationLinesToRequestRowInVBlank[k],
&locals->VRatioPrefetchY[k],
&locals->VRatioPrefetchC[k],
&locals->RequiredPrefetchPixDataBWLuma[k],
&locals->RequiredPrefetchPixDataBWChroma[k],
&locals->VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
&locals->Tno_bw[k],
&locals->prefetch_vmrow_bw[k],
&locals->swath_width_luma_ub[k],
&locals->swath_width_chroma_ub[k],
&mode_lib->vba.VUpdateOffsetPix[k],
&mode_lib->vba.VUpdateWidthPix[k],
&mode_lib->vba.VReadyOffsetPix[k]);
if (mode_lib->vba.BlendingAndTiming[k] == k) {
locals->VStartup[k] = dml_min(
mode_lib->vba.VStartupLines,
locals->MaxVStartupLines[k]);
if (locals->VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
!= 0) {
locals->VStartup[k] =
locals->VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
}
} else {
locals->VStartup[k] =
dml_min(
mode_lib->vba.VStartupLines,
locals->MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
unsigned int m;
locals->cursor_bw[k] = 0;
locals->cursor_bw_pre[k] = 0;
for (m = 0; m < mode_lib->vba.NumberOfCursors[k]; m++) {
locals->cursor_bw[k] += mode_lib->vba.CursorWidth[k][m] * mode_lib->vba.CursorBPP[k][m] / 8.0 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
locals->cursor_bw_pre[k] += mode_lib->vba.CursorWidth[k][m] * mode_lib->vba.CursorBPP[k][m] / 8.0 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * locals->VRatioPrefetchY[k];
}
CalculateUrgentBurstFactor(
mode_lib->vba.DETBufferSizeInKByte[0],
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.SwathHeightC[k],
locals->SwathWidthY[k],
mode_lib->vba.HTotal[k] /
mode_lib->vba.PixelClock[k],
mode_lib->vba.UrgentLatency,
mode_lib->vba.CursorBufferSize,
mode_lib->vba.CursorWidth[k][0] + mode_lib->vba.CursorWidth[k][1],
dml_max(mode_lib->vba.CursorBPP[k][0], mode_lib->vba.CursorBPP[k][1]),
mode_lib->vba.VRatio[k],
locals->VRatioPrefetchY[k],
locals->VRatioPrefetchC[k],
locals->BytePerPixelDETY[k],
locals->BytePerPixelDETC[k],
&locals->UrgentBurstFactorCursor[k],
&locals->UrgentBurstFactorCursorPre[k],
&locals->UrgentBurstFactorLuma[k],
&locals->UrgentBurstFactorLumaPre[k],
&locals->UrgentBurstFactorChroma[k],
&locals->UrgentBurstFactorChromaPre[k],
&locals->NotEnoughUrgentLatencyHiding[0][0],
&locals->NotEnoughUrgentLatencyHidingPre);
if (mode_lib->vba.UseUrgentBurstBandwidth == false) {
locals->UrgentBurstFactorLuma[k] = 1;
locals->UrgentBurstFactorChroma[k] = 1;
locals->UrgentBurstFactorCursor[k] = 1;
locals->UrgentBurstFactorLumaPre[k] = 1;
locals->UrgentBurstFactorChromaPre[k] = 1;
locals->UrgentBurstFactorCursorPre[k] = 1;
}
MaxTotalRDBandwidth = MaxTotalRDBandwidth +
dml_max3(locals->prefetch_vmrow_bw[k],
locals->ReadBandwidthPlaneLuma[k] * locals->UrgentBurstFactorLuma[k]
+ locals->ReadBandwidthPlaneChroma[k] * locals->UrgentBurstFactorChroma[k] + locals->cursor_bw[k]
* locals->UrgentBurstFactorCursor[k] + locals->meta_row_bw[k] + locals->dpte_row_bw[k],
locals->RequiredPrefetchPixDataBWLuma[k] * locals->UrgentBurstFactorLumaPre[k] + locals->RequiredPrefetchPixDataBWChroma[k]
* locals->UrgentBurstFactorChromaPre[k] + locals->cursor_bw_pre[k] * locals->UrgentBurstFactorCursorPre[k]);
MaxTotalRDBandwidthNoUrgentBurst = MaxTotalRDBandwidthNoUrgentBurst +
dml_max3(locals->prefetch_vmrow_bw[k],
locals->ReadBandwidthPlaneLuma[k] + locals->ReadBandwidthPlaneChroma[k] + locals->cursor_bw[k]
+ locals->meta_row_bw[k] + locals->dpte_row_bw[k],
locals->RequiredPrefetchPixDataBWLuma[k] + locals->RequiredPrefetchPixDataBWChroma[k] + locals->cursor_bw_pre[k]);
if (locals->DestinationLinesForPrefetch[k] < 2)
DestinationLineTimesForPrefetchLessThan2 = true;
if (locals->VRatioPrefetchY[k] > 4 || locals->VRatioPrefetchC[k] > 4)
VRatioPrefetchMoreThan4 = true;
}
mode_lib->vba.FractionOfUrgentBandwidth = MaxTotalRDBandwidthNoUrgentBurst / mode_lib->vba.ReturnBW;
if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && locals->NotEnoughUrgentLatencyHiding[0][0] == 0 &&
locals->NotEnoughUrgentLatencyHidingPre == 0 && !VRatioPrefetchMoreThan4
&& !DestinationLineTimesForPrefetchLessThan2)
mode_lib->vba.PrefetchModeSupported = true;
else {
mode_lib->vba.PrefetchModeSupported = false;
dml_print(
"DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
}
if (mode_lib->vba.PrefetchModeSupported == true) {
mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.BandwidthAvailableForImmediateFlip =
mode_lib->vba.BandwidthAvailableForImmediateFlip
- dml_max(
locals->ReadBandwidthPlaneLuma[k] * locals->UrgentBurstFactorLuma[k]
+ locals->ReadBandwidthPlaneChroma[k] * locals->UrgentBurstFactorChroma[k]
+ locals->cursor_bw[k] * locals->UrgentBurstFactorCursor[k],
locals->RequiredPrefetchPixDataBWLuma[k] * locals->UrgentBurstFactorLumaPre[k] +
locals->RequiredPrefetchPixDataBWChroma[k] * locals->UrgentBurstFactorChromaPre[k] +
locals->cursor_bw_pre[k] * locals->UrgentBurstFactorCursorPre[k]);
}
mode_lib->vba.TotImmediateFlipBytes = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.TotImmediateFlipBytes = mode_lib->vba.TotImmediateFlipBytes + locals->PDEAndMetaPTEBytesFrame[k] + locals->MetaRowByte[k] + locals->PixelPTEBytesPerRow[k];
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
CalculateFlipSchedule(
mode_lib,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
mode_lib->vba.UrgentExtraLatency,
mode_lib->vba.UrgentLatency,
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.HostVMEnable,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels,
mode_lib->vba.GPUVMEnable,
locals->PDEAndMetaPTEBytesFrame[k],
locals->MetaRowByte[k],
locals->PixelPTEBytesPerRow[k],
mode_lib->vba.BandwidthAvailableForImmediateFlip,
mode_lib->vba.TotImmediateFlipBytes,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.VRatio[k],
locals->Tno_bw[k],
mode_lib->vba.DCCEnable[k],
locals->dpte_row_height[k],
locals->meta_row_height[k],
locals->dpte_row_height_chroma[k],
locals->meta_row_height_chroma[k],
&locals->DestinationLinesToRequestVMInImmediateFlip[k],
&locals->DestinationLinesToRequestRowInImmediateFlip[k],
&locals->final_flip_bw[k],
&locals->ImmediateFlipSupportedForPipe[k]);
}
mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
mode_lib->vba.total_dcn_read_bw_with_flip_no_urgent_burst = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.total_dcn_read_bw_with_flip =
mode_lib->vba.total_dcn_read_bw_with_flip + dml_max3(
locals->prefetch_vmrow_bw[k],
locals->final_flip_bw[k] + locals->ReadBandwidthLuma[k] * locals->UrgentBurstFactorLuma[k]
+ locals->ReadBandwidthChroma[k] * locals->UrgentBurstFactorChroma[k] + locals->cursor_bw[k] * locals->UrgentBurstFactorCursor[k],
locals->final_flip_bw[k] + locals->RequiredPrefetchPixDataBWLuma[k] * locals->UrgentBurstFactorLumaPre[k]
+ locals->RequiredPrefetchPixDataBWChroma[k] * locals->UrgentBurstFactorChromaPre[k]
+ locals->cursor_bw_pre[k] * locals->UrgentBurstFactorCursorPre[k]);
mode_lib->vba.total_dcn_read_bw_with_flip_no_urgent_burst =
mode_lib->vba.total_dcn_read_bw_with_flip_no_urgent_burst +
dml_max3(locals->prefetch_vmrow_bw[k],
locals->final_flip_bw[k] + locals->ReadBandwidthPlaneLuma[k] + locals->ReadBandwidthPlaneChroma[k] + locals->cursor_bw[k],
locals->final_flip_bw[k] + locals->RequiredPrefetchPixDataBWLuma[k] + locals->RequiredPrefetchPixDataBWChroma[k] + locals->cursor_bw_pre[k]);
}
mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip = mode_lib->vba.total_dcn_read_bw_with_flip_no_urgent_burst / mode_lib->vba.ReturnBW;
mode_lib->vba.ImmediateFlipSupported = true;
if (mode_lib->vba.total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
mode_lib->vba.ImmediateFlipSupported = false;
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (locals->ImmediateFlipSupportedForPipe[k] == false) {
mode_lib->vba.ImmediateFlipSupported = false;
}
}
} else {
mode_lib->vba.ImmediateFlipSupported = false;
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.ErrorResult[k]) {
mode_lib->vba.PrefetchModeSupported = false;
dml_print(
"DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
}
}
mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
} while (!((mode_lib->vba.PrefetchModeSupported
&& ((!mode_lib->vba.ImmediateFlipSupport && !mode_lib->vba.HostVMEnable)
|| mode_lib->vba.ImmediateFlipSupported))
|| locals->MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
{
enum clock_change_support DRAMClockChangeSupport;
CalculateWatermarksAndDRAMSpeedChangeSupport(
mode_lib,
mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
mode_lib->vba.NumberOfActivePlanes,
mode_lib->vba.MaxLineBufferLines,
mode_lib->vba.LineBufferSize,
mode_lib->vba.DPPOutputBufferPixels,
mode_lib->vba.DETBufferSizeInKByte[0],
mode_lib->vba.WritebackInterfaceLumaBufferSize,
mode_lib->vba.WritebackInterfaceChromaBufferSize,
mode_lib->vba.DCFCLK,
mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels,
mode_lib->vba.ReturnBW,
mode_lib->vba.GPUVMEnable,
locals->dpte_group_bytes,
mode_lib->vba.MetaChunkSize,
mode_lib->vba.UrgentLatency,
mode_lib->vba.UrgentExtraLatency,
mode_lib->vba.WritebackLatency,
mode_lib->vba.WritebackChunkSize,
mode_lib->vba.SOCCLK,
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.SRExitTime,
mode_lib->vba.SREnterPlusExitTime,
mode_lib->vba.DCFCLKDeepSleep,
mode_lib->vba.DPPPerPlane,
mode_lib->vba.DCCEnable,
locals->DPPCLK,
locals->SwathWidthSingleDPPY,
mode_lib->vba.SwathHeightY,
locals->ReadBandwidthPlaneLuma,
mode_lib->vba.SwathHeightC,
locals->ReadBandwidthPlaneChroma,
mode_lib->vba.LBBitPerPixel,
locals->SwathWidthY,
mode_lib->vba.HRatio,
mode_lib->vba.vtaps,
mode_lib->vba.VTAPsChroma,
mode_lib->vba.VRatio,
mode_lib->vba.HTotal,
mode_lib->vba.PixelClock,
mode_lib->vba.BlendingAndTiming,
locals->BytePerPixelDETY,
locals->BytePerPixelDETC,
mode_lib->vba.WritebackEnable,
mode_lib->vba.WritebackPixelFormat,
mode_lib->vba.WritebackDestinationWidth,
mode_lib->vba.WritebackDestinationHeight,
mode_lib->vba.WritebackSourceHeight,
&DRAMClockChangeSupport,
&mode_lib->vba.UrgentWatermark,
&mode_lib->vba.WritebackUrgentWatermark,
&mode_lib->vba.DRAMClockChangeWatermark,
&mode_lib->vba.WritebackDRAMClockChangeWatermark,
&mode_lib->vba.StutterExitWatermark,
&mode_lib->vba.StutterEnterPlusExitWatermark,
&mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
}
CalculatePixelDeliveryTimes(
mode_lib->vba.NumberOfActivePlanes,
mode_lib->vba.VRatio,
locals->VRatioPrefetchY,
locals->VRatioPrefetchC,
locals->swath_width_luma_ub,
locals->swath_width_chroma_ub,
mode_lib->vba.DPPPerPlane,
mode_lib->vba.HRatio,
mode_lib->vba.PixelClock,
locals->PSCL_THROUGHPUT_LUMA,
locals->PSCL_THROUGHPUT_CHROMA,
locals->DPPCLK,
locals->BytePerPixelDETC,
mode_lib->vba.SourceScan,
locals->BlockWidth256BytesY,
locals->BlockHeight256BytesY,
locals->BlockWidth256BytesC,
locals->BlockHeight256BytesC,
locals->DisplayPipeLineDeliveryTimeLuma,
locals->DisplayPipeLineDeliveryTimeChroma,
locals->DisplayPipeLineDeliveryTimeLumaPrefetch,
locals->DisplayPipeLineDeliveryTimeChromaPrefetch,
locals->DisplayPipeRequestDeliveryTimeLuma,
locals->DisplayPipeRequestDeliveryTimeChroma,
locals->DisplayPipeRequestDeliveryTimeLumaPrefetch,
locals->DisplayPipeRequestDeliveryTimeChromaPrefetch);
CalculateMetaAndPTETimes(
mode_lib->vba.NumberOfActivePlanes,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.MetaChunkSize,
mode_lib->vba.MinMetaChunkSizeBytes,
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.HTotal,
mode_lib->vba.VRatio,
locals->VRatioPrefetchY,
locals->VRatioPrefetchC,
locals->DestinationLinesToRequestRowInVBlank,
locals->DestinationLinesToRequestRowInImmediateFlip,
locals->DestinationLinesToRequestVMInVBlank,
locals->DestinationLinesToRequestVMInImmediateFlip,
mode_lib->vba.DCCEnable,
mode_lib->vba.PixelClock,
locals->BytePerPixelDETY,
locals->BytePerPixelDETC,
mode_lib->vba.SourceScan,
locals->dpte_row_height,
locals->dpte_row_height_chroma,
locals->meta_row_width,
locals->meta_row_height,
locals->meta_req_width,
locals->meta_req_height,
locals->dpte_group_bytes,
locals->PTERequestSizeY,
locals->PTERequestSizeC,
locals->PixelPTEReqWidthY,
locals->PixelPTEReqHeightY,
locals->PixelPTEReqWidthC,
locals->PixelPTEReqHeightC,
locals->dpte_row_width_luma_ub,
locals->dpte_row_width_chroma_ub,
locals->vm_group_bytes,
locals->dpde0_bytes_per_frame_ub_l,
locals->dpde0_bytes_per_frame_ub_c,
locals->meta_pte_bytes_per_frame_ub_l,
locals->meta_pte_bytes_per_frame_ub_c,
locals->DST_Y_PER_PTE_ROW_NOM_L,
locals->DST_Y_PER_PTE_ROW_NOM_C,
locals->DST_Y_PER_META_ROW_NOM_L,
locals->TimePerMetaChunkNominal,
locals->TimePerMetaChunkVBlank,
locals->TimePerMetaChunkFlip,
locals->time_per_pte_group_nom_luma,
locals->time_per_pte_group_vblank_luma,
locals->time_per_pte_group_flip_luma,
locals->time_per_pte_group_nom_chroma,
locals->time_per_pte_group_vblank_chroma,
locals->time_per_pte_group_flip_chroma,
locals->TimePerVMGroupVBlank,
locals->TimePerVMGroupFlip,
locals->TimePerVMRequestVBlank,
locals->TimePerVMRequestFlip);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
locals->AllowDRAMClockChangeDuringVBlank[k] = true;
locals->AllowDRAMSelfRefreshDuringVBlank[k] = true;
locals->MinTTUVBlank[k] = dml_max(
mode_lib->vba.DRAMClockChangeWatermark,
dml_max(
mode_lib->vba.StutterEnterPlusExitWatermark,
mode_lib->vba.UrgentWatermark));
} else if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 1) {
locals->AllowDRAMClockChangeDuringVBlank[k] = false;
locals->AllowDRAMSelfRefreshDuringVBlank[k] = true;
locals->MinTTUVBlank[k] = dml_max(
mode_lib->vba.StutterEnterPlusExitWatermark,
mode_lib->vba.UrgentWatermark);
} else {
locals->AllowDRAMClockChangeDuringVBlank[k] = false;
locals->AllowDRAMSelfRefreshDuringVBlank[k] = false;
locals->MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
}
if (!mode_lib->vba.DynamicMetadataEnable[k])
locals->MinTTUVBlank[k] = mode_lib->vba.TCalc
+ locals->MinTTUVBlank[k];
}
mode_lib->vba.ActiveDPPs = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
locals->MaximumDCCCompressionYSurface[k] = CalculateDCCConfiguration(
mode_lib->vba.DCCEnable[k],
false,
mode_lib->vba.ViewportWidth[k],
mode_lib->vba.ViewportHeight[k],
mode_lib->vba.DETBufferSizeInKByte[0] * 1024,
locals->BlockHeight256BytesY[k],
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.SurfaceTiling[k],
locals->BytePerPixelDETY[k],
mode_lib->vba.SourceScan[k],
&locals->DCCYMaxUncompressedBlock[k],
&locals->DCCYMaxCompressedBlock[k],
&locals->DCCYIndependent64ByteBlock[k]);
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.XFCEnabled[k] == true) {
double TWait;
locals->XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
locals->XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
locals->XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
TWait = CalculateTWait(
mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatency,
mode_lib->vba.SREnterPlusExitTime);
mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
mode_lib,
mode_lib->vba.VRatio[k],
locals->SwathWidthY[k],
dml_ceil(locals->BytePerPixelDETY[k], 1),
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.XFCTSlvVupdateOffset,
mode_lib->vba.XFCTSlvVupdateWidth,
mode_lib->vba.XFCTSlvVreadyOffset,
mode_lib->vba.XFCXBUFLatencyTolerance,
mode_lib->vba.XFCFillBWOverhead,
mode_lib->vba.XFCSlvChunkSize,
mode_lib->vba.XFCBusTransportTime,
mode_lib->vba.TCalc,
TWait,
&mode_lib->vba.SrcActiveDrainRate,
&mode_lib->vba.TInitXFill,
&mode_lib->vba.TslvChk);
locals->XFCRemoteSurfaceFlipLatency[k] =
dml_floor(
mode_lib->vba.XFCRemoteSurfaceFlipDelay
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1);
locals->XFCTransferDelay[k] =
dml_ceil(
mode_lib->vba.XFCBusTransportTime
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1);
locals->XFCPrechargeDelay[k] =
dml_ceil(
(mode_lib->vba.XFCBusTransportTime
+ mode_lib->vba.TInitXFill
+ mode_lib->vba.TslvChk)
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1);
mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
* mode_lib->vba.SrcActiveDrainRate;
mode_lib->vba.FinalFillMargin =
(locals->DestinationLinesToRequestVMInVBlank[k]
+ locals->DestinationLinesToRequestRowInVBlank[k])
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]
* mode_lib->vba.SrcActiveDrainRate
+ mode_lib->vba.XFCFillConstant;
mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
* mode_lib->vba.SrcActiveDrainRate
+ mode_lib->vba.FinalFillMargin;
mode_lib->vba.RemainingFillLevel = dml_max(
0.0,
mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
/ (mode_lib->vba.SrcActiveDrainRate
* mode_lib->vba.XFCFillBWOverhead / 100);
locals->XFCPrefetchMargin[k] =
mode_lib->vba.XFCRemoteSurfaceFlipDelay
+ mode_lib->vba.TFinalxFill
+ (locals->DestinationLinesToRequestVMInVBlank[k]
+ locals->DestinationLinesToRequestRowInVBlank[k])
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
} else {
locals->XFCSlaveVUpdateOffset[k] = 0;
locals->XFCSlaveVupdateWidth[k] = 0;
locals->XFCSlaveVReadyOffset[k] = 0;
locals->XFCRemoteSurfaceFlipLatency[k] = 0;
locals->XFCPrechargeDelay[k] = 0;
locals->XFCTransferDelay[k] = 0;
locals->XFCPrefetchMargin[k] = 0;
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
CalculateDETBufferSize(
mode_lib->vba.DETBufferSizeInKByte[0],
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.SwathHeightC[k],
&locals->DETBufferSizeY[k],
&locals->DETBufferSizeC[k]);
locals->LinesInDETY[k] = (double)locals->DETBufferSizeY[k]
/ locals->BytePerPixelDETY[k] / locals->SwathWidthY[k];
locals->LinesInDETYRoundedDownToSwath[k] = dml_floor(
locals->LinesInDETY[k],
mode_lib->vba.SwathHeightY[k]);
locals->FullDETBufferingTimeY[k] =
locals->LinesInDETYRoundedDownToSwath[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k];
}
mode_lib->vba.StutterPeriod = 999999.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (locals->FullDETBufferingTimeY[k] < mode_lib->vba.StutterPeriod) {
mode_lib->vba.StutterPeriod = locals->FullDETBufferingTimeY[k];
mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
locals->BytePerPixelYCriticalPlane = dml_ceil(locals->BytePerPixelDETY[k], 1);
locals->SwathWidthYCriticalPlane = locals->SwathWidthY[k];
locals->LinesToFinishSwathTransferStutterCriticalPlane =
mode_lib->vba.SwathHeightY[k] - (locals->LinesInDETY[k] - locals->LinesInDETYRoundedDownToSwath[k]);
}
}
mode_lib->vba.AverageReadBandwidth = 0.0;
mode_lib->vba.TotalRowReadBandwidth = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
unsigned int DCCRateLimit;
if (mode_lib->vba.DCCEnable[k]) {
if (locals->DCCYMaxCompressedBlock[k] == 256)
DCCRateLimit = 4;
else
DCCRateLimit = 2;
mode_lib->vba.AverageReadBandwidth =
mode_lib->vba.AverageReadBandwidth
+ (locals->ReadBandwidthPlaneLuma[k] + locals->ReadBandwidthPlaneChroma[k]) /
dml_min(mode_lib->vba.DCCRate[k], DCCRateLimit);
} else {
mode_lib->vba.AverageReadBandwidth =
mode_lib->vba.AverageReadBandwidth
+ locals->ReadBandwidthPlaneLuma[k]
+ locals->ReadBandwidthPlaneChroma[k];
}
mode_lib->vba.TotalRowReadBandwidth = mode_lib->vba.TotalRowReadBandwidth +
locals->meta_row_bw[k] + locals->dpte_row_bw[k];
}
mode_lib->vba.AverageDCCCompressionRate = mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.AverageReadBandwidth;
mode_lib->vba.PartOfBurstThatFitsInROB =
dml_min(
mode_lib->vba.StutterPeriod
* mode_lib->vba.TotalDataReadBandwidth,
mode_lib->vba.ROBBufferSizeInKByte * 1024
* mode_lib->vba.AverageDCCCompressionRate);
mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
/ mode_lib->vba.AverageDCCCompressionRate / mode_lib->vba.ReturnBW
+ (mode_lib->vba.StutterPeriod * mode_lib->vba.TotalDataReadBandwidth
- mode_lib->vba.PartOfBurstThatFitsInROB)
/ (mode_lib->vba.DCFCLK * 64)
+ mode_lib->vba.StutterPeriod * mode_lib->vba.TotalRowReadBandwidth / mode_lib->vba.ReturnBW;
mode_lib->vba.StutterBurstTime = dml_max(
mode_lib->vba.StutterBurstTime,
(locals->LinesToFinishSwathTransferStutterCriticalPlane * locals->BytePerPixelYCriticalPlane *
locals->SwathWidthYCriticalPlane / mode_lib->vba.ReturnBW)
);
mode_lib->vba.TotalActiveWriteback = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
}
}
if (mode_lib->vba.TotalActiveWriteback == 0) {
mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
- (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
/ mode_lib->vba.StutterPeriod) * 100;
} else {
mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
}
mode_lib->vba.SmallestVBlank = 999999;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
- mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
} else {
mode_lib->vba.VBlankTime = 0;
}
mode_lib->vba.SmallestVBlank = dml_min(
mode_lib->vba.SmallestVBlank,
mode_lib->vba.VBlankTime);
}
mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
* (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
- mode_lib->vba.SmallestVBlank)
+ mode_lib->vba.SmallestVBlank)
/ mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
}
static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
{
double BytePerPixDETY;
double BytePerPixDETC;
double Read256BytesBlockHeightY;
double Read256BytesBlockHeightC;
double Read256BytesBlockWidthY;
double Read256BytesBlockWidthC;
double MaximumSwathHeightY;
double MaximumSwathHeightC;
double MinimumSwathHeightY;
double MinimumSwathHeightC;
double SwathWidth;
double SwathWidthGranularityY;
double SwathWidthGranularityC;
double RoundedUpMaxSwathSizeBytesY;
double RoundedUpMaxSwathSizeBytesC;
unsigned int j, k;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
bool MainPlaneDoesODMCombine = false;
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
BytePerPixDETY = 8;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
BytePerPixDETY = 4;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
BytePerPixDETY = 2;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
BytePerPixDETY = 1;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
BytePerPixDETY = 1;
BytePerPixDETC = 2;
} else {
BytePerPixDETY = 4.0 / 3.0;
BytePerPixDETC = 8.0 / 3.0;
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
Read256BytesBlockHeightY = 1;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
Read256BytesBlockHeightY = 4;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
Read256BytesBlockHeightY = 8;
} else {
Read256BytesBlockHeightY = 16;
}
Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
/ Read256BytesBlockHeightY;
Read256BytesBlockHeightC = 0;
Read256BytesBlockWidthC = 0;
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
Read256BytesBlockHeightY = 1;
Read256BytesBlockHeightC = 1;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
Read256BytesBlockHeightY = 16;
Read256BytesBlockHeightC = 8;
} else {
Read256BytesBlockHeightY = 8;
Read256BytesBlockHeightC = 8;
}
Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
/ Read256BytesBlockHeightY;
Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
/ Read256BytesBlockHeightC;
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
MaximumSwathHeightY = Read256BytesBlockHeightY;
MaximumSwathHeightC = Read256BytesBlockHeightC;
} else {
MaximumSwathHeightY = Read256BytesBlockWidthY;
MaximumSwathHeightC = Read256BytesBlockWidthC;
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_t
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s_x)
&& mode_lib->vba.SourceScan[k] == dm_horz)) {
MinimumSwathHeightY = MaximumSwathHeightY;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
&& mode_lib->vba.SourceScan[k] != dm_horz) {
MinimumSwathHeightY = MaximumSwathHeightY;
} else {
MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
}
MinimumSwathHeightC = MaximumSwathHeightC;
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
MinimumSwathHeightY = MaximumSwathHeightY;
MinimumSwathHeightC = MaximumSwathHeightC;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
&& mode_lib->vba.SourceScan[k] == dm_horz) {
MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
MinimumSwathHeightC = MaximumSwathHeightC;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
&& mode_lib->vba.SourceScan[k] == dm_horz) {
MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
MinimumSwathHeightY = MaximumSwathHeightY;
} else {
MinimumSwathHeightY = MaximumSwathHeightY;
MinimumSwathHeightC = MaximumSwathHeightC;
}
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
SwathWidth = mode_lib->vba.ViewportWidth[k];
} else {
SwathWidth = mode_lib->vba.ViewportHeight[k];
}
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
MainPlaneDoesODMCombine = true;
}
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
MainPlaneDoesODMCombine = true;
}
}
if (MainPlaneDoesODMCombine == true) {
SwathWidth = dml_min(
SwathWidth,
mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
} else {
SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
}
SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
RoundedUpMaxSwathSizeBytesY = (dml_ceil(
(double) (SwathWidth - 1),
SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
* MaximumSwathHeightY;
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
+ 256;
}
if (MaximumSwathHeightC > 0) {
SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
/ MaximumSwathHeightC;
RoundedUpMaxSwathSizeBytesC = (dml_ceil(
(double) (SwathWidth / 2.0 - 1),
SwathWidthGranularityC) + SwathWidthGranularityC)
* BytePerPixDETC * MaximumSwathHeightC;
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
RoundedUpMaxSwathSizeBytesC = dml_ceil(
RoundedUpMaxSwathSizeBytesC,
256) + 256;
}
} else
RoundedUpMaxSwathSizeBytesC = 0.0;
if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
<= mode_lib->vba.DETBufferSizeInKByte[0] * 1024.0 / 2.0) {
mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
} else {
mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
}
CalculateDETBufferSize(
mode_lib->vba.DETBufferSizeInKByte[0],
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.SwathHeightC[k],
&mode_lib->vba.DETBufferSizeY[k],
&mode_lib->vba.DETBufferSizeC[k]);
}
}
static double CalculateTWait(
unsigned int PrefetchMode,
double DRAMClockChangeLatency,
double UrgentLatency,
double SREnterPlusExitTime)
{
if (PrefetchMode == 0) {
return dml_max(
DRAMClockChangeLatency + UrgentLatency,
dml_max(SREnterPlusExitTime, UrgentLatency));
} else if (PrefetchMode == 1) {
return dml_max(SREnterPlusExitTime, UrgentLatency);
} else {
return UrgentLatency;
}
}
static double CalculateRemoteSurfaceFlipDelay(
struct display_mode_lib *mode_lib,
double VRatio,
double SwathWidth,
double Bpp,
double LineTime,
double XFCTSlvVupdateOffset,
double XFCTSlvVupdateWidth,
double XFCTSlvVreadyOffset,
double XFCXBUFLatencyTolerance,
double XFCFillBWOverhead,
double XFCSlvChunkSize,
double XFCBusTransportTime,
double TCalc,
double TWait,
double *SrcActiveDrainRate,
double *TInitXFill,
double *TslvChk)
{
double TSlvSetup, AvgfillRate, result;
*SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
*TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
*TslvChk = XFCSlvChunkSize / AvgfillRate;
dml_print(
"DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
*SrcActiveDrainRate);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill;
dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
return result;
}
static double CalculateWriteBackDelay(
enum source_format_class WritebackPixelFormat,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackLumaHTaps,
unsigned int WritebackLumaVTaps,
unsigned int WritebackChromaHTaps,
unsigned int WritebackChromaVTaps,
unsigned int WritebackDestinationWidth)
{
double CalculateWriteBackDelay =
dml_max(
dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
* dml_ceil(
WritebackDestinationWidth
/ 4.0,
1)
+ dml_ceil(1.0 / WritebackVRatio, 1)
* (dml_ceil(
WritebackLumaVTaps
/ 4.0,
1) + 4));
if (WritebackPixelFormat != dm_444_32) {
CalculateWriteBackDelay =
dml_max(
CalculateWriteBackDelay,
dml_max(
dml_ceil(
WritebackChromaHTaps
/ 2.0,
1)
/ (2
* WritebackHRatio),
WritebackChromaVTaps
* dml_ceil(
1
/ (2
* WritebackVRatio),
1)
* dml_ceil(
WritebackDestinationWidth
/ 2.0
/ 2.0,
1)
+ dml_ceil(
1
/ (2
* WritebackVRatio),
1)
* (dml_ceil(
WritebackChromaVTaps
/ 4.0,
1)
+ 4)));
}
return CalculateWriteBackDelay;
}
static void CalculateActiveRowBandwidth(
bool GPUVMEnable,
enum source_format_class SourcePixelFormat,
double VRatio,
bool DCCEnable,
double LineTime,
unsigned int MetaRowByteLuma,
unsigned int MetaRowByteChroma,
unsigned int meta_row_height_luma,
unsigned int meta_row_height_chroma,
unsigned int PixelPTEBytesPerRowLuma,
unsigned int PixelPTEBytesPerRowChroma,
unsigned int dpte_row_height_luma,
unsigned int dpte_row_height_chroma,
double *meta_row_bw,
double *dpte_row_bw)
{
if (DCCEnable != true) {
*meta_row_bw = 0;
} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
+ VRatio / 2 * MetaRowByteChroma
/ (meta_row_height_chroma * LineTime);
} else {
*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
}
if (GPUVMEnable != true) {
*dpte_row_bw = 0;
} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
+ VRatio / 2 * PixelPTEBytesPerRowChroma
/ (dpte_row_height_chroma * LineTime);
} else {
*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
}
}
static void CalculateFlipSchedule(
struct display_mode_lib *mode_lib,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
double UrgentExtraLatency,
double UrgentLatency,
unsigned int GPUVMMaxPageTableLevels,
bool HostVMEnable,
unsigned int HostVMMaxPageTableLevels,
unsigned int HostVMCachedPageTableLevels,
bool GPUVMEnable,
double PDEAndMetaPTEBytesPerFrame,
double MetaRowBytes,
double DPTEBytesPerRow,
double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum source_format_class SourcePixelFormat,
double LineTime,
double VRatio,
double Tno_bw,
bool DCCEnable,
unsigned int dpte_row_height,
unsigned int meta_row_height,
unsigned int dpte_row_height_chroma,
unsigned int meta_row_height_chroma,
double *DestinationLinesToRequestVMInImmediateFlip,
double *DestinationLinesToRequestRowInImmediateFlip,
double *final_flip_bw,
bool *ImmediateFlipSupportedForPipe)
{
double min_row_time = 0.0;
unsigned int HostVMDynamicLevels;
double TimeForFetchingMetaPTEImmediateFlip;
double TimeForFetchingRowInVBlankImmediateFlip;
double ImmediateFlipBW = 1.0;
double HostVMInefficiencyFactor;
double VRatioClamped;
if (GPUVMEnable == true && HostVMEnable == true) {
HostVMInefficiencyFactor =
PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData
/ PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
HostVMDynamicLevels = HostVMMaxPageTableLevels - HostVMCachedPageTableLevels;
} else {
HostVMInefficiencyFactor = 1;
HostVMDynamicLevels = 0;
}
ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow)
* BandwidthAvailableForImmediateFlip / TotImmediateFlipBytes;
if (GPUVMEnable == true) {
TimeForFetchingMetaPTEImmediateFlip = dml_max3(
Tno_bw + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW,
UrgentExtraLatency + UrgentLatency * (GPUVMMaxPageTableLevels * (HostVMDynamicLevels + 1) - 1),
LineTime / 4.0);
} else {
TimeForFetchingMetaPTEImmediateFlip = 0;
}
*DestinationLinesToRequestVMInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1) / 4.0;
if ((GPUVMEnable == true || DCCEnable == true)) {
TimeForFetchingRowInVBlankImmediateFlip = dml_max3((MetaRowBytes + DPTEBytesPerRow) * HostVMInefficiencyFactor / ImmediateFlipBW, UrgentLatency * (HostVMDynamicLevels + 1), LineTime / 4);
} else {
TimeForFetchingRowInVBlankImmediateFlip = 0;
}
*DestinationLinesToRequestRowInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0;
*final_flip_bw = dml_max(PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInImmediateFlip * LineTime), (MetaRowBytes + DPTEBytesPerRow) * HostVMInefficiencyFactor / (*DestinationLinesToRequestRowInImmediateFlip * LineTime));
VRatioClamped = (VRatio < 1.0) ? 1.0 : VRatio;
if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
if (GPUVMEnable == true && DCCEnable != true) {
min_row_time = dml_min(
dpte_row_height * LineTime / VRatioClamped,
dpte_row_height_chroma * LineTime / (VRatioClamped / 2));
} else if (GPUVMEnable != true && DCCEnable == true) {
min_row_time = dml_min(
meta_row_height * LineTime / VRatioClamped,
meta_row_height_chroma * LineTime / (VRatioClamped / 2));
} else {
min_row_time = dml_min4(
dpte_row_height * LineTime / VRatioClamped,
meta_row_height * LineTime / VRatioClamped,
dpte_row_height_chroma * LineTime / (VRatioClamped / 2),
meta_row_height_chroma * LineTime / (VRatioClamped / 2));
}
} else {
if (GPUVMEnable == true && DCCEnable != true) {
min_row_time = dpte_row_height * LineTime / VRatioClamped;
} else if (GPUVMEnable != true && DCCEnable == true) {
min_row_time = meta_row_height * LineTime / VRatioClamped;
} else {
min_row_time = dml_min(
dpte_row_height * LineTime / VRatioClamped,
meta_row_height * LineTime / VRatioClamped);
}
}
if (*DestinationLinesToRequestVMInImmediateFlip >= 32
|| *DestinationLinesToRequestRowInImmediateFlip >= 16
|| TimeForFetchingMetaPTEImmediateFlip + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) {
*ImmediateFlipSupportedForPipe = false;
} else {
*ImmediateFlipSupportedForPipe = true;
}
}
static unsigned int TruncToValidBPP(
double DecimalBPP,
double DesiredBPP,
bool DSCEnabled,
enum output_encoder_class Output,
enum output_format_class Format,
unsigned int DSCInputBitPerComponent)
{
if (Output == dm_hdmi) {
if (Format == dm_420) {
if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else if (DecimalBPP >= 15 && (DesiredBPP == 0 || DesiredBPP == 15))
return 15;
else if (DecimalBPP >= 12 && (DesiredBPP == 0 || DesiredBPP == 12))
return 12;
else
return BPP_INVALID;
} else if (Format == dm_444) {
if (DecimalBPP >= 36 && (DesiredBPP == 0 || DesiredBPP == 36))
return 36;
else if (DecimalBPP >= 30 && (DesiredBPP == 0 || DesiredBPP == 30))
return 30;
else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else
return BPP_INVALID;
} else {
if (DecimalBPP / 1.5 >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP / 1.5 >= 20 && (DesiredBPP == 0 || DesiredBPP == 20))
return 20;
else if (DecimalBPP / 1.5 >= 16 && (DesiredBPP == 0 || DesiredBPP == 16))
return 16;
else
return BPP_INVALID;
}
} else {
if (DSCEnabled) {
if (Format == dm_420) {
if (DesiredBPP == 0) {
if (DecimalBPP < 6)
return BPP_INVALID;
else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1.0 / 16.0)
return 1.5 * DSCInputBitPerComponent - 1.0 / 16.0;
else
return dml_floor(16 * DecimalBPP, 1) / 16.0;
} else {
if (DecimalBPP < 6
|| DesiredBPP < 6
|| DesiredBPP > 1.5 * DSCInputBitPerComponent - 1.0 / 16.0
|| DecimalBPP < DesiredBPP) {
return BPP_INVALID;
} else {
return DesiredBPP;
}
}
} else if (Format == dm_n422) {
if (DesiredBPP == 0) {
if (DecimalBPP < 7)
return BPP_INVALID;
else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1.0 / 16.0)
return 2 * DSCInputBitPerComponent - 1.0 / 16.0;
else
return dml_floor(16 * DecimalBPP, 1) / 16.0;
} else {
if (DecimalBPP < 7
|| DesiredBPP < 7
|| DesiredBPP > 2 * DSCInputBitPerComponent - 1.0 / 16.0
|| DecimalBPP < DesiredBPP) {
return BPP_INVALID;
} else {
return DesiredBPP;
}
}
} else {
if (DesiredBPP == 0) {
if (DecimalBPP < 8)
return BPP_INVALID;
else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1.0 / 16.0)
return 3 * DSCInputBitPerComponent - 1.0 / 16.0;
else
return dml_floor(16 * DecimalBPP, 1) / 16.0;
} else {
if (DecimalBPP < 8
|| DesiredBPP < 8
|| DesiredBPP > 3 * DSCInputBitPerComponent - 1.0 / 16.0
|| DecimalBPP < DesiredBPP) {
return BPP_INVALID;
} else {
return DesiredBPP;
}
}
}
} else if (Format == dm_420) {
if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else if (DecimalBPP >= 15 && (DesiredBPP == 0 || DesiredBPP == 15))
return 15;
else if (DecimalBPP >= 12 && (DesiredBPP == 0 || DesiredBPP == 12))
return 12;
else
return BPP_INVALID;
} else if (Format == dm_s422 || Format == dm_n422) {
if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP >= 20 && (DesiredBPP == 0 || DesiredBPP == 20))
return 20;
else if (DecimalBPP >= 16 && (DesiredBPP == 0 || DesiredBPP == 16))
return 16;
else
return BPP_INVALID;
} else {
if (DecimalBPP >= 36 && (DesiredBPP == 0 || DesiredBPP == 36))
return 36;
else if (DecimalBPP >= 30 && (DesiredBPP == 0 || DesiredBPP == 30))
return 30;
else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else
return BPP_INVALID;
}
}
}
static noinline void CalculatePrefetchSchedulePerPlane(
struct display_mode_lib *mode_lib,
int i,
unsigned j,
unsigned k)
{
struct vba_vars_st *locals = &mode_lib->vba;
Pipe myPipe;
HostVM myHostVM;
if (mode_lib->vba.XFCEnabled[k] == true) {
mode_lib->vba.XFCRemoteSurfaceFlipDelay =
CalculateRemoteSurfaceFlipDelay(
mode_lib,
mode_lib->vba.VRatio[k],
locals->SwathWidthYThisState[k],
dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.XFCTSlvVupdateOffset,
mode_lib->vba.XFCTSlvVupdateWidth,
mode_lib->vba.XFCTSlvVreadyOffset,
mode_lib->vba.XFCXBUFLatencyTolerance,
mode_lib->vba.XFCFillBWOverhead,
mode_lib->vba.XFCSlvChunkSize,
mode_lib->vba.XFCBusTransportTime,
mode_lib->vba.TimeCalc,
mode_lib->vba.TWait,
&mode_lib->vba.SrcActiveDrainRate,
&mode_lib->vba.TInitXFill,
&mode_lib->vba.TslvChk);
} else {
mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
}
myPipe.DPPCLK = locals->RequiredDPPCLK[i][j][k];
myPipe.DISPCLK = locals->RequiredDISPCLK[i][j];
myPipe.PixelClock = mode_lib->vba.PixelClock[k];
myPipe.DCFCLKDeepSleep = mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
myPipe.DPPPerPlane = locals->NoOfDPP[i][j][k];
myPipe.ScalerEnabled = mode_lib->vba.ScalerEnabled[k];
myPipe.SourceScan = mode_lib->vba.SourceScan[k];
myPipe.BlockWidth256BytesY = locals->Read256BlockWidthY[k];
myPipe.BlockHeight256BytesY = locals->Read256BlockHeightY[k];
myPipe.BlockWidth256BytesC = locals->Read256BlockWidthC[k];
myPipe.BlockHeight256BytesC = locals->Read256BlockHeightC[k];
myPipe.InterlaceEnable = mode_lib->vba.Interlace[k];
myPipe.NumberOfCursors = mode_lib->vba.NumberOfCursors[k];
myPipe.VBlank = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k];
myPipe.HTotal = mode_lib->vba.HTotal[k];
myHostVM.Enable = mode_lib->vba.HostVMEnable;
myHostVM.MaxPageTableLevels = mode_lib->vba.HostVMMaxPageTableLevels;
myHostVM.CachedPageTableLevels = mode_lib->vba.HostVMCachedPageTableLevels;
mode_lib->vba.IsErrorResult[i][j][k] = CalculatePrefetchSchedule(
mode_lib,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
&myPipe,
locals->DSCDelayPerState[i][k],
mode_lib->vba.DPPCLKDelaySubtotal,
mode_lib->vba.DPPCLKDelaySCL,
mode_lib->vba.DPPCLKDelaySCLLBOnly,
mode_lib->vba.DPPCLKDelayCNVCFormater,
mode_lib->vba.DPPCLKDelayCNVCCursor,
mode_lib->vba.DISPCLKDelaySubtotal,
locals->SwathWidthYThisState[k] / mode_lib->vba.HRatio[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.MaxInterDCNTileRepeaters,
dml_min(mode_lib->vba.MaxVStartup, locals->MaximumVStartup[0][0][k]),
locals->MaximumVStartup[0][0][k],
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.GPUVMEnable,
&myHostVM,
mode_lib->vba.DynamicMetadataEnable[k],
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
mode_lib->vba.DynamicMetadataTransmittedBytes[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.UrgentLatency,
mode_lib->vba.ExtraLatency,
mode_lib->vba.TimeCalc,
locals->PDEAndMetaPTEBytesPerFrame[0][0][k],
locals->MetaRowBytes[0][0][k],
locals->DPTEBytesPerRow[0][0][k],
locals->PrefetchLinesY[0][0][k],
locals->SwathWidthYThisState[k],
locals->BytePerPixelInDETY[k],
locals->PrefillY[k],
locals->MaxNumSwY[k],
locals->PrefetchLinesC[0][0][k],
locals->BytePerPixelInDETC[k],
locals->PrefillC[k],
locals->MaxNumSwC[k],
locals->SwathHeightYThisState[k],
locals->SwathHeightCThisState[k],
mode_lib->vba.TWait,
mode_lib->vba.XFCEnabled[k],
mode_lib->vba.XFCRemoteSurfaceFlipDelay,
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
&locals->dst_x_after_scaler,
&locals->dst_y_after_scaler,
&locals->LineTimesForPrefetch[k],
&locals->PrefetchBW[k],
&locals->LinesForMetaPTE[k],
&locals->LinesForMetaAndDPTERow[k],
&locals->VRatioPreY[i][j][k],
&locals->VRatioPreC[i][j][k],
&locals->RequiredPrefetchPixelDataBWLuma[i][j][k],
&locals->RequiredPrefetchPixelDataBWChroma[i][j][k],
&locals->VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
&locals->Tno_bw[k],
&locals->prefetch_vmrow_bw[k],
locals->swath_width_luma_ub,
locals->swath_width_chroma_ub,
&mode_lib->vba.VUpdateOffsetPix[k],
&mode_lib->vba.VUpdateWidthPix[k],
&mode_lib->vba.VReadyOffsetPix[k]);
}
void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
{
struct vba_vars_st *locals = &mode_lib->vba;
int i;
unsigned int j, k, m;
mode_lib->vba.ScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ScalerEnabled[k] == false
&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
|| mode_lib->vba.HRatio[k] != 1.0
|| mode_lib->vba.htaps[k] != 1.0
|| mode_lib->vba.VRatio[k] != 1.0
|| mode_lib->vba.vtaps[k] != 1.0)) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
|| (mode_lib->vba.htaps[k] > 1.0
&& (mode_lib->vba.htaps[k] % 2) == 1)
|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
&& (mode_lib->vba.HRatio[k] / 2.0
> mode_lib->vba.HTAPsChroma[k]
|| mode_lib->vba.VRatio[k] / 2.0
> mode_lib->vba.VTAPsChroma[k]))) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
}
}
mode_lib->vba.SourceFormatPixelAndScanSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
&& mode_lib->vba.SourceScan[k] != dm_horz)
|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10))
|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_gfx7_2d_thin_l_vp)
&& !((mode_lib->vba.SourcePixelFormat[k]
== dm_444_64
|| mode_lib->vba.SourcePixelFormat[k]
== dm_444_32)
&& mode_lib->vba.SourceScan[k]
== dm_horz
&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
== true
&& mode_lib->vba.DCCEnable[k]
== false))
|| (mode_lib->vba.DCCEnable[k] == true
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_linear
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10)))) {
mode_lib->vba.SourceFormatPixelAndScanSupport = false;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
locals->BytePerPixelInDETY[k] = 8.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
locals->BytePerPixelInDETY[k] = 4.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
locals->BytePerPixelInDETY[k] = 2.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
locals->BytePerPixelInDETY[k] = 1.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
locals->BytePerPixelInDETY[k] = 1.0;
locals->BytePerPixelInDETC[k] = 2.0;
} else {
locals->BytePerPixelInDETY[k] = 4.0 / 3;
locals->BytePerPixelInDETC[k] = 8.0 / 3;
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
} else {
locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->ReadBandwidthLuma[k] = locals->SwathWidthYSingleDPP[k] * dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
locals->ReadBandwidthChroma[k] = locals->SwathWidthYSingleDPP[k] / 2 * dml_ceil(locals->BytePerPixelInDETC[k], 2.0)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k] / 2.0;
locals->ReadBandwidth[k] = locals->ReadBandwidthLuma[k] + locals->ReadBandwidthChroma[k];
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 4.0;
} else if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 3.0;
} else if (mode_lib->vba.WritebackEnable[k] == true) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 1.5;
} else {
locals->WriteBandwidth[k] = 0.0;
}
}
mode_lib->vba.DCCEnabledInAnyPlane = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.DCCEnabledInAnyPlane = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->IdealSDPPortBandwidthPerState[i][0] = dml_min3(
mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
* mode_lib->vba.DRAMChannelWidth,
mode_lib->vba.FabricClockPerState[i]
* mode_lib->vba.FabricDatapathToDCNDataReturn);
if (mode_lib->vba.HostVMEnable == false) {
locals->ReturnBWPerState[i][0] = locals->IdealSDPPortBandwidthPerState[i][0]
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100.0;
} else {
locals->ReturnBWPerState[i][0] = locals->IdealSDPPortBandwidthPerState[i][0]
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0;
}
}
mode_lib->vba.WritebackLatencySupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
if (locals->WriteBandwidth[k]
> (mode_lib->vba.WritebackInterfaceLumaBufferSize
+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ mode_lib->vba.WritebackLatency) {
mode_lib->vba.WritebackLatencySupport = false;
}
} else {
if (locals->WriteBandwidth[k]
> 1.5
* dml_min(
mode_lib->vba.WritebackInterfaceLumaBufferSize,
2.0
* mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ mode_lib->vba.WritebackLatency) {
mode_lib->vba.WritebackLatencySupport = false;
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
(mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
+ dml_max3(mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly,
mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly)
* mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i][0];
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i][0]
> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
locals->ROBSupport[i][0] = true;
} else {
locals->ROBSupport[i][0] = false;
}
}
mode_lib->vba.TotalNumberOfActiveWriteback = 0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.ActiveWritebacksPerPlane[k] == 0)
mode_lib->vba.ActiveWritebacksPerPlane[k] = 1;
mode_lib->vba.TotalNumberOfActiveWriteback =
mode_lib->vba.TotalNumberOfActiveWriteback
+ mode_lib->vba.ActiveWritebacksPerPlane[k];
}
}
mode_lib->vba.WritebackModeSupport = true;
if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
mode_lib->vba.WritebackModeSupport = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.Writeback10bpc420Supported != true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
mode_lib->vba.WritebackModeSupport = false;
}
}
mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
&& (mode_lib->vba.WritebackHRatio[k] != 1.0
|| mode_lib->vba.WritebackVRatio[k] != 1.0)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
|| mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackMaxVSCLRatio
|| mode_lib->vba.WritebackHRatio[k]
< mode_lib->vba.WritebackMinHSCLRatio
|| mode_lib->vba.WritebackVRatio[k]
< mode_lib->vba.WritebackMinVSCLRatio
|| mode_lib->vba.WritebackLumaHTaps[k]
> mode_lib->vba.WritebackMaxHSCLTaps
|| mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackMaxVSCLTaps
|| mode_lib->vba.WritebackHRatio[k]
> mode_lib->vba.WritebackLumaHTaps[k]
|| mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackLumaVTaps[k]
|| (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
&& ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
== 1))
|| (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
&& (mode_lib->vba.WritebackChromaHTaps[k]
> mode_lib->vba.WritebackMaxHSCLTaps
|| mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackMaxVSCLTaps
|| 2.0
* mode_lib->vba.WritebackHRatio[k]
> mode_lib->vba.WritebackChromaHTaps[k]
|| 2.0
* mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackChromaVTaps[k]
|| (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
&& ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
mode_lib->vba.WritebackLumaVExtra =
dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
} else {
mode_lib->vba.WritebackLumaVExtra = -1;
}
if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
&& mode_lib->vba.WritebackLumaVTaps[k]
> (mode_lib->vba.WritebackLineBufferLumaBufferSize
+ mode_lib->vba.WritebackLineBufferChromaBufferSize)
/ 3.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
&& mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackLineBufferLumaBufferSize
* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
&& mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackLineBufferLumaBufferSize
* 8.0 / 10.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
mode_lib->vba.WritebackChromaVExtra = 0.0;
} else {
mode_lib->vba.WritebackChromaVExtra = -1;
}
if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
&& mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackLineBufferChromaBufferSize
* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackChromaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
&& mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackLineBufferChromaBufferSize
* 8.0 / 10.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackChromaVExtra)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
}
}
mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.WritebackRequiredDISPCLK =
dml_max(
mode_lib->vba.WritebackRequiredDISPCLK,
CalculateWriteBackDISPCLK(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.PixelClock[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.WritebackChromaLineBufferWidth));
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.HRatio[k] > 1.0) {
locals->PSCL_FACTOR[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ dml_ceil(
mode_lib->vba.htaps[k]
/ 6.0,
1.0));
} else {
locals->PSCL_FACTOR[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
if (locals->BytePerPixelInDETC[k] == 0.0) {
locals->PSCL_FACTOR_CHROMA[k] = 0.0;
locals->MinDPPCLKUsingSingleDPP[k] =
mode_lib->vba.PixelClock[k]
* dml_max3(
mode_lib->vba.vtaps[k] / 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]),
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ locals->PSCL_FACTOR[k],
1.0);
if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
&& locals->MinDPPCLKUsingSingleDPP[k]
< 2.0 * mode_lib->vba.PixelClock[k]) {
locals->MinDPPCLKUsingSingleDPP[k] = 2.0
* mode_lib->vba.PixelClock[k];
}
} else {
if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
locals->PSCL_FACTOR_CHROMA[k] =
dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ 2.0
/ dml_ceil(
mode_lib->vba.HTAPsChroma[k]
/ 6.0,
1.0));
} else {
locals->PSCL_FACTOR_CHROMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
locals->MinDPPCLKUsingSingleDPP[k] =
mode_lib->vba.PixelClock[k]
* dml_max5(
mode_lib->vba.vtaps[k] / 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]),
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ locals->PSCL_FACTOR[k],
mode_lib->vba.VTAPsChroma[k]
/ 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]
/ 2.0),
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ 4.0
/ locals->PSCL_FACTOR_CHROMA[k],
1.0);
if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
|| mode_lib->vba.HTAPsChroma[k] > 6.0
|| mode_lib->vba.VTAPsChroma[k] > 6.0)
&& locals->MinDPPCLKUsingSingleDPP[k]
< 2.0 * mode_lib->vba.PixelClock[k]) {
locals->MinDPPCLKUsingSingleDPP[k] = 2.0
* mode_lib->vba.PixelClock[k];
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
Calculate256BBlockSizes(
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
&locals->Read256BlockHeightY[k],
&locals->Read256BlockHeightC[k],
&locals->Read256BlockWidthY[k],
&locals->Read256BlockWidthC[k]);
if (mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MaxSwathHeightY[k] = locals->Read256BlockHeightY[k];
locals->MaxSwathHeightC[k] = locals->Read256BlockHeightC[k];
} else {
locals->MaxSwathHeightY[k] = locals->Read256BlockWidthY[k];
locals->MaxSwathHeightC[k] = locals->Read256BlockWidthC[k];
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_t
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s_x)
&& mode_lib->vba.SourceScan[k] == dm_horz)) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
} else {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
/ 2.0;
}
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
&& mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
/ 2.0;
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
&& mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k]
/ 2.0;
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
} else {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
}
}
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
} else {
mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
}
mode_lib->vba.MaximumSwathWidthInDETBuffer =
dml_min(
mode_lib->vba.MaximumSwathWidthSupport,
mode_lib->vba.DETBufferSizeInKByte[0] * 1024.0 / 2.0
/ (locals->BytePerPixelInDETY[k]
* locals->MinSwathHeightY[k]
+ locals->BytePerPixelInDETC[k]
/ 2.0
* locals->MinSwathHeightC[k]));
if (locals->BytePerPixelInDETC[k] == 0.0) {
mode_lib->vba.MaximumSwathWidthInLineBuffer =
mode_lib->vba.LineBufferSize
* dml_max(mode_lib->vba.HRatio[k], 1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.vtaps[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k],
1.0)
- 2,
0.0));
} else {
mode_lib->vba.MaximumSwathWidthInLineBuffer =
dml_min(
mode_lib->vba.LineBufferSize
* dml_max(
mode_lib->vba.HRatio[k],
1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.vtaps[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k],
1.0)
- 2,
0.0)),
2.0 * mode_lib->vba.LineBufferSize
* dml_max(
mode_lib->vba.HRatio[k]
/ 2.0,
1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.VTAPsChroma[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k]
/ 2.0,
1.0)
- 2,
0.0)));
}
locals->MaximumSwathWidth[k] = dml_min(
mode_lib->vba.MaximumSwathWidthInDETBuffer,
mode_lib->vba.MaximumSwathWidthInLineBuffer);
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown(
mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states],
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
for (j = 0; j < 2; j++) {
mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
mode_lib->vba.MaxDispclk[i],
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
mode_lib->vba.MaxDppclk[i],
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
locals->RequiredDISPCLK[i][j] = 0.0;
locals->DISPCLK_DPPCLK_Support[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
mode_lib->vba.PixelClock[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
* (1.0
+ mode_lib->vba.DISPCLKRampingMargin
/ 100.0);
if (mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine >= mode_lib->vba.MaxDispclk[i]
&& i == mode_lib->vba.soc.num_states)
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = mode_lib->vba.PixelClock[k]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
if (mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine >= mode_lib->vba.MaxDispclk[i]
&& i == mode_lib->vba.soc.num_states)
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
if (mode_lib->vba.ODMCapability) {
if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
} else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN21_MAX_DSC_IMAGE_WIDTH)) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
} else if (locals->HActive[k] > DCN21_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
}
}
if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
&& locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
locals->NoOfDPP[i][j][k] = 1;
locals->RequiredDPPCLK[i][j][k] =
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
} else {
locals->NoOfDPP[i][j][k] = 2;
locals->RequiredDPPCLK[i][j][k] =
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.PlaneRequiredDISPCLK);
if ((locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
|| (mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
}
locals->TotalNumberOfActiveDPP[i][j] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
if (j == 1) {
while (locals->TotalNumberOfActiveDPP[i][j] < mode_lib->vba.MaxNumDPP
&& locals->TotalNumberOfActiveDPP[i][j] < 2 * mode_lib->vba.NumberOfActivePlanes) {
double BWOfNonSplitPlaneOfMaximumBandwidth;
unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
BWOfNonSplitPlaneOfMaximumBandwidth = 0;
NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (locals->ReadBandwidth[k] > BWOfNonSplitPlaneOfMaximumBandwidth && locals->NoOfDPP[i][j][k] == 1) {
BWOfNonSplitPlaneOfMaximumBandwidth = locals->ReadBandwidth[k];
NumberOfNonSplitPlaneOfMaximumBandwidth = k;
}
}
locals->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
locals->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
locals->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + 1;
}
}
if (locals->TotalNumberOfActiveDPP[i][j] > mode_lib->vba.MaxNumDPP) {
locals->RequiredDISPCLK[i][j] = 0.0;
locals->DISPCLK_DPPCLK_Support[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
locals->NoOfDPP[i][j][k] = 1;
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
} else {
locals->NoOfDPP[i][j][k] = 2;
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
}
if (i != mode_lib->vba.soc.num_states) {
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PixelClock[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
} else {
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PixelClock[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.PlaneRequiredDISPCLK);
if (locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
|| mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
locals->TotalNumberOfActiveDPP[i][j] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.WritebackRequiredDISPCLK);
if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
< mode_lib->vba.WritebackRequiredDISPCLK) {
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->ViewportSizeSupport[i][0] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
> locals->MaximumSwathWidth[k]) {
locals->ViewportSizeSupport[i][0] = false;
}
} else {
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
locals->ViewportSizeSupport[i][0] = false;
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
if (locals->TotalNumberOfActiveDPP[i][j] <= mode_lib->vba.MaxNumDPP)
locals->TotalAvailablePipesSupport[i][j] = true;
else
locals->TotalAvailablePipesSupport[i][j] = false;
}
}
mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+ 1.0;
}
}
if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
mode_lib->vba.NumberOfOTGSupport = true;
} else {
mode_lib->vba.NumberOfOTGSupport = false;
}
mode_lib->vba.NonsupportedDSCInputBPC = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
mode_lib->vba.NonsupportedDSCInputBPC = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = 0;
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.Output[k] == dm_hdmi) {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = 0;
locals->OutputBppPerState[i][k] = TruncToValidBPP(
dml_min(600.0, mode_lib->vba.PHYCLKPerState[i]) / mode_lib->vba.PixelClockBackEnd[k] * 24,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
} else if (mode_lib->vba.Output[k] == dm_dp
|| mode_lib->vba.Output[k] == dm_edp) {
if (mode_lib->vba.Output[k] == dm_edp) {
mode_lib->vba.EffectiveFECOverhead = 0.0;
} else {
mode_lib->vba.EffectiveFECOverhead =
mode_lib->vba.FECOverhead;
}
if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
mode_lib->vba.Outbpp = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
mode_lib->vba.OutbppDSC = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
}
if (mode_lib->vba.Outbpp == BPP_INVALID && mode_lib->vba.PHYCLKPerState[i] >= 540.0) {
mode_lib->vba.Outbpp = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
mode_lib->vba.OutbppDSC = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
}
if (mode_lib->vba.Outbpp == BPP_INVALID
&& mode_lib->vba.PHYCLKPerState[i]
>= 810.0) {
mode_lib->vba.Outbpp = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
mode_lib->vba.OutbppDSC = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true || mode_lib->vba.Outbpp == BPP_INVALID) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] =
mode_lib->vba.Outbpp;
}
}
} else {
locals->OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->DIOSupport[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!mode_lib->vba.skip_dio_check[k]
&& (locals->OutputBppPerState[i][k] == BPP_INVALID
|| (mode_lib->vba.OutputFormat[k] == dm_420
&& mode_lib->vba.Interlace[k] == true
&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) {
locals->DIOSupport[i] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->DSCCLKRequiredMoreThanSupported[i] = false;
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if ((mode_lib->vba.Output[k] == dm_dp
|| mode_lib->vba.Output[k] == dm_edp)) {
if (mode_lib->vba.OutputFormat[k] == dm_420
|| mode_lib->vba.OutputFormat[k]
== dm_n422) {
mode_lib->vba.DSCFormatFactor = 2;
} else {
mode_lib->vba.DSCFormatFactor = 1;
}
if (locals->RequiresDSC[i][k] == true) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
locals->DSCCLKRequiredMoreThanSupported[i] =
true;
}
} else {
if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 / mode_lib->vba.DSCFormatFactor
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
locals->DSCCLKRequiredMoreThanSupported[i] =
true;
}
}
}
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->NotEnoughDSCUnits[i] = false;
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->RequiresDSC[i][k] == true) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
} else {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 1.0;
}
}
}
if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
locals->NotEnoughDSCUnits[i] = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] != k) {
mode_lib->vba.slices = 0;
} else if (locals->RequiresDSC[i][k] == 0
|| locals->RequiresDSC[i][k] == false) {
mode_lib->vba.slices = 0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
mode_lib->vba.slices = dml_ceil(
mode_lib->vba.PixelClockBackEnd[k] / 400.0,
4.0);
} else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
mode_lib->vba.slices = 8.0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
mode_lib->vba.slices = 4.0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
mode_lib->vba.slices = 2.0;
} else {
mode_lib->vba.slices = 1.0;
}
if (locals->OutputBppPerState[i][k] == BPP_BLENDED_PIPE
|| locals->OutputBppPerState[i][k] == BPP_INVALID) {
mode_lib->vba.bpp = 0.0;
} else {
mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
}
if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
locals->DSCDelayPerState[i][k] =
dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
mode_lib->vba.bpp,
dml_ceil(
mode_lib->vba.HActive[k]
/ mode_lib->vba.slices,
1.0),
mode_lib->vba.slices,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]);
} else {
locals->DSCDelayPerState[i][k] =
2.0 * (dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
mode_lib->vba.bpp,
dml_ceil(mode_lib->vba.HActive[k] / mode_lib->vba.slices, 1.0),
mode_lib->vba.slices / 2,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(mode_lib->vba.OutputFormat[k]));
}
locals->DSCDelayPerState[i][k] =
locals->DSCDelayPerState[i][k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k];
} else {
locals->DSCDelayPerState[i][k] = 0.0;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
if (mode_lib->vba.BlendingAndTiming[k] == m && locals->RequiresDSC[i][m] == true)
locals->DSCDelayPerState[i][k] = locals->DSCDelayPerState[i][m];
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; ++i) {
for (j = 0; j <= 1; ++j) {
locals->TotalNumberOfDCCActiveDPP[i][j] = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.DCCEnable[k] == true)
locals->TotalNumberOfDCCActiveDPP[i][j] = locals->TotalNumberOfDCCActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
}
}
}
mode_lib->vba.UrgentLatency = dml_max3(
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.UrgentLatencyPixelMixedWithVMData,
mode_lib->vba.UrgentLatencyVMDataOnly);
mode_lib->vba.PrefetchERROR = CalculateMinAndMaxPrefetchMode(
mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
&mode_lib->vba.MinPrefetchMode,
&mode_lib->vba.MaxPrefetchMode);
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->RequiredDPPCLKThisState[k] = locals->RequiredDPPCLK[i][j][k];
locals->NoOfDPPThisState[k] = locals->NoOfDPP[i][j][k];
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
locals->SwathWidthYThisState[k] =
dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]));
} else {
locals->SwathWidthYThisState[k] = locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
}
mode_lib->vba.SwathWidthGranularityY = 256.0
/ dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
/ locals->MaxSwathHeightY[k];
mode_lib->vba.RoundedUpMaxSwathSizeBytesY =
(dml_ceil(locals->SwathWidthYThisState[k] - 1.0, mode_lib->vba.SwathWidthGranularityY)
+ mode_lib->vba.SwathWidthGranularityY) * locals->BytePerPixelInDETY[k] * locals->MaxSwathHeightY[k];
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil(
mode_lib->vba.RoundedUpMaxSwathSizeBytesY,
256.0) + 256;
}
if (locals->MaxSwathHeightC[k] > 0.0) {
mode_lib->vba.SwathWidthGranularityC = 256.0 / dml_ceil(locals->BytePerPixelInDETC[k], 2.0) / locals->MaxSwathHeightC[k];
mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil(locals->SwathWidthYThisState[k] / 2.0 - 1.0, mode_lib->vba.SwathWidthGranularityC)
+ mode_lib->vba.SwathWidthGranularityC) * locals->BytePerPixelInDETC[k] * locals->MaxSwathHeightC[k];
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil(mode_lib->vba.RoundedUpMaxSwathSizeBytesC, 256.0) + 256;
}
} else {
mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0;
}
if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY + mode_lib->vba.RoundedUpMaxSwathSizeBytesC
<= mode_lib->vba.DETBufferSizeInKByte[0] * 1024.0 / 2.0) {
locals->SwathHeightYThisState[k] = locals->MaxSwathHeightY[k];
locals->SwathHeightCThisState[k] = locals->MaxSwathHeightC[k];
} else {
locals->SwathHeightYThisState[k] =
locals->MinSwathHeightY[k];
locals->SwathHeightCThisState[k] =
locals->MinSwathHeightC[k];
}
}
CalculateDCFCLKDeepSleep(
mode_lib,
mode_lib->vba.NumberOfActivePlanes,
locals->BytePerPixelInDETY,
locals->BytePerPixelInDETC,
mode_lib->vba.VRatio,
locals->SwathWidthYThisState,
locals->NoOfDPPThisState,
mode_lib->vba.HRatio,
mode_lib->vba.PixelClock,
locals->PSCL_FACTOR,
locals->PSCL_FACTOR_CHROMA,
locals->RequiredDPPCLKThisState,
&mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0]);
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
locals->Read256BlockHeightC[k],
locals->Read256BlockWidthC[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k] / 2.0,
mode_lib->vba.ViewportHeight[k] / 2.0,
locals->SwathWidthYThisState[k] / 2.0,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.HostVMEnable,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequestsChroma,
mode_lib->vba.PitchC[k],
0.0,
&locals->MacroTileWidthC[k],
&mode_lib->vba.MetaRowBytesC,
&mode_lib->vba.DPTEBytesPerRowC,
&locals->PTEBufferSizeNotExceededC[i][j][k],
locals->dpte_row_width_chroma_ub,
&locals->dpte_row_height_chroma[k],
&locals->meta_req_width_chroma[k],
&locals->meta_req_height_chroma[k],
&locals->meta_row_width_chroma[k],
&locals->meta_row_height_chroma[k],
&locals->vm_group_bytes_chroma,
&locals->dpte_group_bytes_chroma,
locals->PixelPTEReqWidthC,
locals->PixelPTEReqHeightC,
locals->PTERequestSizeC,
locals->dpde0_bytes_per_frame_ub_c,
locals->meta_pte_bytes_per_frame_ub_c);
locals->PrefetchLinesC[0][0][k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k]/2,
mode_lib->vba.VTAPsChroma[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
locals->SwathHeightCThisState[k],
mode_lib->vba.ViewportYStartC[k],
&locals->PrefillC[k],
&locals->MaxNumSwC[k]);
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma;
} else {
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
mode_lib->vba.MetaRowBytesC = 0.0;
mode_lib->vba.DPTEBytesPerRowC = 0.0;
locals->PrefetchLinesC[0][0][k] = 0.0;
locals->PTEBufferSizeNotExceededC[i][j][k] = true;
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
}
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
locals->Read256BlockHeightY[k],
locals->Read256BlockWidthY[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k],
mode_lib->vba.ViewportHeight[k],
locals->SwathWidthYThisState[k],
mode_lib->vba.GPUVMEnable,
mode_lib->vba.HostVMEnable,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels,
mode_lib->vba.VMMPageSize,
locals->PTEBufferSizeInRequestsForLuma,
mode_lib->vba.PitchY[k],
mode_lib->vba.DCCMetaPitchY[k],
&locals->MacroTileWidthY[k],
&mode_lib->vba.MetaRowBytesY,
&mode_lib->vba.DPTEBytesPerRowY,
&locals->PTEBufferSizeNotExceededY[i][j][k],
locals->dpte_row_width_luma_ub,
&locals->dpte_row_height[k],
&locals->meta_req_width[k],
&locals->meta_req_height[k],
&locals->meta_row_width[k],
&locals->meta_row_height[k],
&locals->vm_group_bytes[k],
&locals->dpte_group_bytes[k],
locals->PixelPTEReqWidthY,
locals->PixelPTEReqHeightY,
locals->PTERequestSizeY,
locals->dpde0_bytes_per_frame_ub_l,
locals->meta_pte_bytes_per_frame_ub_l);
locals->PrefetchLinesY[0][0][k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k],
mode_lib->vba.vtaps[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
locals->SwathHeightYThisState[k],
mode_lib->vba.ViewportYStartY[k],
&locals->PrefillY[k],
&locals->MaxNumSwY[k]);
locals->PDEAndMetaPTEBytesPerFrame[0][0][k] =
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
locals->MetaRowBytes[0][0][k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
locals->DPTEBytesPerRow[0][0][k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
CalculateActiveRowBandwidth(
mode_lib->vba.GPUVMEnable,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.VRatio[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.HTotal[k] /
mode_lib->vba.PixelClock[k],
mode_lib->vba.MetaRowBytesY,
mode_lib->vba.MetaRowBytesC,
locals->meta_row_height[k],
locals->meta_row_height_chroma[k],
mode_lib->vba.DPTEBytesPerRowY,
mode_lib->vba.DPTEBytesPerRowC,
locals->dpte_row_height[k],
locals->dpte_row_height_chroma[k],
&locals->meta_row_bw[k],
&locals->dpte_row_bw[k]);
}
mode_lib->vba.ExtraLatency = CalculateExtraLatency(
locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i],
locals->TotalNumberOfActiveDPP[i][j],
mode_lib->vba.PixelChunkSizeInKByte,
locals->TotalNumberOfDCCActiveDPP[i][j],
mode_lib->vba.MetaChunkSize,
locals->ReturnBWPerState[i][0],
mode_lib->vba.GPUVMEnable,
mode_lib->vba.HostVMEnable,
mode_lib->vba.NumberOfActivePlanes,
locals->NoOfDPPThisState,
locals->dpte_group_bytes,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels);
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.WritebackEnable[k] == true) {
locals->WritebackDelay[i][k] = mode_lib->vba.WritebackLatency
+ CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k]) / locals->RequiredDISPCLK[i][j];
} else {
locals->WritebackDelay[i][k] = 0.0;
}
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
if (mode_lib->vba.BlendingAndTiming[m] == k
&& mode_lib->vba.WritebackEnable[m]
== true) {
locals->WritebackDelay[i][k] = dml_max(locals->WritebackDelay[i][k],
mode_lib->vba.WritebackLatency + CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[m],
mode_lib->vba.WritebackHRatio[m],
mode_lib->vba.WritebackVRatio[m],
mode_lib->vba.WritebackLumaHTaps[m],
mode_lib->vba.WritebackLumaVTaps[m],
mode_lib->vba.WritebackChromaHTaps[m],
mode_lib->vba.WritebackChromaVTaps[m],
mode_lib->vba.WritebackDestinationWidth[m]) / locals->RequiredDISPCLK[i][j]);
}
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
if (mode_lib->vba.BlendingAndTiming[k] == m) {
locals->WritebackDelay[i][k] = locals->WritebackDelay[i][m];
}
}
}
mode_lib->vba.MaxMaxVStartup[0][0] = 0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->MaximumVStartup[0][0][k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
mode_lib->vba.MaxMaxVStartup[0][0] = dml_max(mode_lib->vba.MaxMaxVStartup[0][0], locals->MaximumVStartup[0][0][k]);
}
mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup[0][0];
do {
mode_lib->vba.PrefetchMode[i][j] = mode_lib->vba.NextPrefetchMode;
mode_lib->vba.MaxVStartup = mode_lib->vba.NextMaxVStartup;
mode_lib->vba.TWait = CalculateTWait(
mode_lib->vba.PrefetchMode[i][j],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatency,
mode_lib->vba.SREnterPlusExitTime);
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
CalculatePrefetchSchedulePerPlane(mode_lib, i, j, k);
mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0;
mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
unsigned int m;
locals->cursor_bw[k] = 0;
locals->cursor_bw_pre[k] = 0;
for (m = 0; m < mode_lib->vba.NumberOfCursors[k]; m++) {
locals->cursor_bw[k] = mode_lib->vba.CursorWidth[k][m] * mode_lib->vba.CursorBPP[k][m]
/ 8.0 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
locals->cursor_bw_pre[k] = mode_lib->vba.CursorWidth[k][m] * mode_lib->vba.CursorBPP[k][m]
/ 8.0 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * locals->VRatioPreY[i][j][k];
}
CalculateUrgentBurstFactor(
mode_lib->vba.DETBufferSizeInKByte[0],
locals->SwathHeightYThisState[k],
locals->SwathHeightCThisState[k],
locals->SwathWidthYThisState[k],
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.UrgentLatency,
mode_lib->vba.CursorBufferSize,
mode_lib->vba.CursorWidth[k][0] + mode_lib->vba.CursorWidth[k][1],
dml_max(mode_lib->vba.CursorBPP[k][0], mode_lib->vba.CursorBPP[k][1]),
mode_lib->vba.VRatio[k],
locals->VRatioPreY[i][j][k],
locals->VRatioPreC[i][j][k],
locals->BytePerPixelInDETY[k],
locals->BytePerPixelInDETC[k],
&locals->UrgentBurstFactorCursor[k],
&locals->UrgentBurstFactorCursorPre[k],
&locals->UrgentBurstFactorLuma[k],
&locals->UrgentBurstFactorLumaPre[k],
&locals->UrgentBurstFactorChroma[k],
&locals->UrgentBurstFactorChromaPre[k],
&locals->NotEnoughUrgentLatencyHiding[0][0],
&locals->NotEnoughUrgentLatencyHidingPre);
if (mode_lib->vba.UseUrgentBurstBandwidth == false) {
locals->UrgentBurstFactorCursor[k] = 1;
locals->UrgentBurstFactorCursorPre[k] = 1;
locals->UrgentBurstFactorLuma[k] = 1;
locals->UrgentBurstFactorLumaPre[k] = 1;
locals->UrgentBurstFactorChroma[k] = 1;
locals->UrgentBurstFactorChromaPre[k] = 1;
}
mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = mode_lib->vba.MaximumReadBandwidthWithoutPrefetch
+ locals->cursor_bw[k] * locals->UrgentBurstFactorCursor[k] + locals->ReadBandwidthLuma[k]
* locals->UrgentBurstFactorLuma[k] + locals->ReadBandwidthChroma[k]
* locals->UrgentBurstFactorChroma[k] + locals->meta_row_bw[k] + locals->dpte_row_bw[k];
mode_lib->vba.MaximumReadBandwidthWithPrefetch = mode_lib->vba.MaximumReadBandwidthWithPrefetch
+ dml_max3(locals->prefetch_vmrow_bw[k],
locals->ReadBandwidthLuma[k] * locals->UrgentBurstFactorLuma[k] + locals->ReadBandwidthChroma[k]
* locals->UrgentBurstFactorChroma[k] + locals->cursor_bw[k] * locals->UrgentBurstFactorCursor[k]
+ locals->meta_row_bw[k] + locals->dpte_row_bw[k],
locals->RequiredPrefetchPixelDataBWLuma[i][j][k] * locals->UrgentBurstFactorLumaPre[k]
+ locals->RequiredPrefetchPixelDataBWChroma[i][j][k] * locals->UrgentBurstFactorChromaPre[k]
+ locals->cursor_bw_pre[k] * locals->UrgentBurstFactorCursorPre[k]);
}
locals->BandwidthWithoutPrefetchSupported[i][0] = true;
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i][0]
|| locals->NotEnoughUrgentLatencyHiding[0][0] == 1) {
locals->BandwidthWithoutPrefetchSupported[i][0] = false;
}
locals->PrefetchSupported[i][j] = true;
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i][0]
|| locals->NotEnoughUrgentLatencyHiding[0][0] == 1
|| locals->NotEnoughUrgentLatencyHidingPre == 1) {
locals->PrefetchSupported[i][j] = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->LineTimesForPrefetch[k] < 2.0
|| locals->LinesForMetaPTE[k] >= 32.0
|| locals->LinesForMetaAndDPTERow[k] >= 16.0
|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
locals->PrefetchSupported[i][j] = false;
}
}
locals->VRatioInPrefetchSupported[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->VRatioPreY[i][j][k] > 4.0
|| locals->VRatioPreC[i][j][k] > 4.0
|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
locals->VRatioInPrefetchSupported[i][j] = false;
}
}
mode_lib->vba.AnyLinesForVMOrRowTooLarge = false;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (locals->LinesForMetaAndDPTERow[k] >= 16 || locals->LinesForMetaPTE[k] >= 32) {
mode_lib->vba.AnyLinesForVMOrRowTooLarge = true;
}
}
if (mode_lib->vba.MaxVStartup <= 13 || mode_lib->vba.AnyLinesForVMOrRowTooLarge == false) {
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup[0][0];
mode_lib->vba.NextPrefetchMode = mode_lib->vba.NextPrefetchMode + 1;
} else {
mode_lib->vba.NextMaxVStartup = mode_lib->vba.NextMaxVStartup - 1;
}
} while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true)
&& (mode_lib->vba.NextMaxVStartup != mode_lib->vba.MaxMaxVStartup[0][0]
|| mode_lib->vba.NextPrefetchMode <= mode_lib->vba.MaxPrefetchMode));
if (locals->PrefetchSupported[i][j] == true && locals->VRatioInPrefetchSupported[i][j] == true) {
mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i][0];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.BandwidthAvailableForImmediateFlip
- dml_max(locals->ReadBandwidthLuma[k] * locals->UrgentBurstFactorLuma[k]
+ locals->ReadBandwidthChroma[k] * locals->UrgentBurstFactorChroma[k]
+ locals->cursor_bw[k] * locals->UrgentBurstFactorCursor[k],
locals->RequiredPrefetchPixelDataBWLuma[i][j][k] * locals->UrgentBurstFactorLumaPre[k]
+ locals->RequiredPrefetchPixelDataBWChroma[i][j][k] * locals->UrgentBurstFactorChromaPre[k]
+ locals->cursor_bw_pre[k] * locals->UrgentBurstFactorCursorPre[k]);
}
mode_lib->vba.TotImmediateFlipBytes = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.TotImmediateFlipBytes = mode_lib->vba.TotImmediateFlipBytes
+ locals->PDEAndMetaPTEBytesPerFrame[0][0][k] + locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k];
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
CalculateFlipSchedule(
mode_lib,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
mode_lib->vba.ExtraLatency,
mode_lib->vba.UrgentLatency,
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.HostVMEnable,
mode_lib->vba.HostVMMaxPageTableLevels,
mode_lib->vba.HostVMCachedPageTableLevels,
mode_lib->vba.GPUVMEnable,
locals->PDEAndMetaPTEBytesPerFrame[0][0][k],
locals->MetaRowBytes[0][0][k],
locals->DPTEBytesPerRow[0][0][k],
mode_lib->vba.BandwidthAvailableForImmediateFlip,
mode_lib->vba.TotImmediateFlipBytes,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.VRatio[k],
locals->Tno_bw[k],
mode_lib->vba.DCCEnable[k],
locals->dpte_row_height[k],
locals->meta_row_height[k],
locals->dpte_row_height_chroma[k],
locals->meta_row_height_chroma[k],
&locals->DestinationLinesToRequestVMInImmediateFlip[k],
&locals->DestinationLinesToRequestRowInImmediateFlip[k],
&locals->final_flip_bw[k],
&locals->ImmediateFlipSupportedForPipe[k]);
}
mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.total_dcn_read_bw_with_flip = mode_lib->vba.total_dcn_read_bw_with_flip + dml_max3(
locals->prefetch_vmrow_bw[k],
locals->final_flip_bw[k] + locals->ReadBandwidthLuma[k] * locals->UrgentBurstFactorLuma[k]
+ locals->ReadBandwidthChroma[k] * locals->UrgentBurstFactorChroma[k]
+ locals->cursor_bw[k] * locals->UrgentBurstFactorCursor[k],
locals->final_flip_bw[k] + locals->RequiredPrefetchPixelDataBWLuma[i][j][k]
* locals->UrgentBurstFactorLumaPre[k] + locals->RequiredPrefetchPixelDataBWChroma[i][j][k]
* locals->UrgentBurstFactorChromaPre[k] + locals->cursor_bw_pre[k]
* locals->UrgentBurstFactorCursorPre[k]);
}
locals->ImmediateFlipSupportedForState[i][j] = true;
if (mode_lib->vba.total_dcn_read_bw_with_flip
> locals->ReturnBWPerState[i][0]) {
locals->ImmediateFlipSupportedForState[i][j] = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->ImmediateFlipSupportedForPipe[k] == false) {
locals->ImmediateFlipSupportedForState[i][j] = false;
}
}
} else {
locals->ImmediateFlipSupportedForState[i][j] = false;
}
mode_lib->vba.UrgentOutOfOrderReturnPerChannel = dml_max3(
mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly,
mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly);
CalculateWatermarksAndDRAMSpeedChangeSupport(
mode_lib,
mode_lib->vba.PrefetchMode[i][j],
mode_lib->vba.NumberOfActivePlanes,
mode_lib->vba.MaxLineBufferLines,
mode_lib->vba.LineBufferSize,
mode_lib->vba.DPPOutputBufferPixels,
mode_lib->vba.DETBufferSizeInKByte[0],
mode_lib->vba.WritebackInterfaceLumaBufferSize,
mode_lib->vba.WritebackInterfaceChromaBufferSize,
mode_lib->vba.DCFCLKPerState[i],
mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels,
locals->ReturnBWPerState[i][0],
mode_lib->vba.GPUVMEnable,
locals->dpte_group_bytes,
mode_lib->vba.MetaChunkSize,
mode_lib->vba.UrgentLatency,
mode_lib->vba.ExtraLatency,
mode_lib->vba.WritebackLatency,
mode_lib->vba.WritebackChunkSize,
mode_lib->vba.SOCCLKPerState[i],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.SRExitTime,
mode_lib->vba.SREnterPlusExitTime,
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
locals->NoOfDPPThisState,
mode_lib->vba.DCCEnable,
locals->RequiredDPPCLKThisState,
locals->SwathWidthYSingleDPP,
locals->SwathHeightYThisState,
locals->ReadBandwidthLuma,
locals->SwathHeightCThisState,
locals->ReadBandwidthChroma,
mode_lib->vba.LBBitPerPixel,
locals->SwathWidthYThisState,
mode_lib->vba.HRatio,
mode_lib->vba.vtaps,
mode_lib->vba.VTAPsChroma,
mode_lib->vba.VRatio,
mode_lib->vba.HTotal,
mode_lib->vba.PixelClock,
mode_lib->vba.BlendingAndTiming,
locals->BytePerPixelInDETY,
locals->BytePerPixelInDETC,
mode_lib->vba.WritebackEnable,
mode_lib->vba.WritebackPixelFormat,
mode_lib->vba.WritebackDestinationWidth,
mode_lib->vba.WritebackDestinationHeight,
mode_lib->vba.WritebackSourceHeight,
&locals->DRAMClockChangeSupport[i][j],
&mode_lib->vba.UrgentWatermark,
&mode_lib->vba.WritebackUrgentWatermark,
&mode_lib->vba.DRAMClockChangeWatermark,
&mode_lib->vba.WritebackDRAMClockChangeWatermark,
&mode_lib->vba.StutterExitWatermark,
&mode_lib->vba.StutterEnterPlusExitWatermark,
&mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
}
}
{
double MaxTotalVActiveRDBandwidth = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + locals->ReadBandwidth[k];
}
for (i = 0; i <= mode_lib->vba.soc.num_states; ++i) {
locals->MaxTotalVerticalActiveAvailableBandwidth[i][0] = dml_min(
locals->IdealSDPPortBandwidthPerState[i][0] *
mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation
/ 100.0, mode_lib->vba.DRAMSpeedPerState[i] *
mode_lib->vba.NumberOfChannels *
mode_lib->vba.DRAMChannelWidth *
mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation
/ 100.0);
if (MaxTotalVActiveRDBandwidth <= locals->MaxTotalVerticalActiveAvailableBandwidth[i][0]) {
locals->TotalVerticalActiveBandwidthSupport[i][0] = true;
} else {
locals->TotalVerticalActiveBandwidthSupport[i][0] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
locals->PTEBufferSizeNotExceeded[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->PTEBufferSizeNotExceededY[i][j][k] == false
|| locals->PTEBufferSizeNotExceededC[i][j][k] == false) {
locals->PTEBufferSizeNotExceeded[i][j] = false;
}
}
}
}
mode_lib->vba.CursorSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.CursorWidth[k][0] > 0.0) {
for (m = 0; m < mode_lib->vba.NumberOfCursors[k]; m++) {
if (mode_lib->vba.CursorBPP[k][m] == 64 && mode_lib->vba.Cursor64BppSupport == false) {
mode_lib->vba.CursorSupport = false;
}
}
}
}
mode_lib->vba.PitchSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->AlignedYPitch[k] = dml_ceil(
dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
locals->MacroTileWidthY[k]);
if (locals->AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
mode_lib->vba.PitchSupport = false;
}
if (mode_lib->vba.DCCEnable[k] == true) {
locals->AlignedDCCMetaPitch[k] = dml_ceil(
dml_max(
mode_lib->vba.DCCMetaPitchY[k],
mode_lib->vba.ViewportWidth[k]),
64.0 * locals->Read256BlockWidthY[k]);
} else {
locals->AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
}
if (locals->AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
mode_lib->vba.PitchSupport = false;
}
if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
locals->AlignedCPitch[k] = dml_ceil(
dml_max(
mode_lib->vba.PitchC[k],
mode_lib->vba.ViewportWidth[k] / 2.0),
locals->MacroTileWidthC[k]);
} else {
locals->AlignedCPitch[k] = mode_lib->vba.PitchC[k];
}
if (locals->AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
mode_lib->vba.PitchSupport = false;
}
}
for (i = mode_lib->vba.soc.num_states; i >= 0; i--) {
for (j = 0; j < 2; j++) {
enum dm_validation_status status = DML_VALIDATION_OK;
if (!mode_lib->vba.ScaleRatioAndTapsSupport) {
status = DML_FAIL_SCALE_RATIO_TAP;
} else if (!mode_lib->vba.SourceFormatPixelAndScanSupport) {
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
} else if (!locals->ViewportSizeSupport[i][0]) {
status = DML_FAIL_VIEWPORT_SIZE;
} else if (!locals->DIOSupport[i]) {
status = DML_FAIL_DIO_SUPPORT;
} else if (locals->NotEnoughDSCUnits[i]) {
status = DML_FAIL_NOT_ENOUGH_DSC;
} else if (locals->DSCCLKRequiredMoreThanSupported[i]) {
status = DML_FAIL_DSC_CLK_REQUIRED;
} else if (!locals->ROBSupport[i][0]) {
status = DML_FAIL_REORDERING_BUFFER;
} else if (!locals->DISPCLK_DPPCLK_Support[i][j]) {
status = DML_FAIL_DISPCLK_DPPCLK;
} else if (!locals->TotalAvailablePipesSupport[i][j]) {
status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
} else if (!mode_lib->vba.NumberOfOTGSupport) {
status = DML_FAIL_NUM_OTG;
} else if (!mode_lib->vba.WritebackModeSupport) {
status = DML_FAIL_WRITEBACK_MODE;
} else if (!mode_lib->vba.WritebackLatencySupport) {
status = DML_FAIL_WRITEBACK_LATENCY;
} else if (!mode_lib->vba.WritebackScaleRatioAndTapsSupport) {
status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
} else if (!mode_lib->vba.CursorSupport) {
status = DML_FAIL_CURSOR_SUPPORT;
} else if (!mode_lib->vba.PitchSupport) {
status = DML_FAIL_PITCH_SUPPORT;
} else if (!locals->TotalVerticalActiveBandwidthSupport[i][0]) {
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
} else if (!locals->PTEBufferSizeNotExceeded[i][j]) {
status = DML_FAIL_PTE_BUFFER_SIZE;
} else if (mode_lib->vba.NonsupportedDSCInputBPC) {
status = DML_FAIL_DSC_INPUT_BPC;
} else if ((mode_lib->vba.HostVMEnable
&& !locals->ImmediateFlipSupportedForState[i][j])) {
status = DML_FAIL_HOST_VM_IMMEDIATE_FLIP;
} else if (!locals->PrefetchSupported[i][j]) {
status = DML_FAIL_PREFETCH_SUPPORT;
} else if (!locals->VRatioInPrefetchSupported[i][j]) {
status = DML_FAIL_V_RATIO_PREFETCH;
}
if (status == DML_VALIDATION_OK) {
locals->ModeSupport[i][j] = true;
} else {
locals->ModeSupport[i][j] = false;
}
locals->ValidationStatus[i] = status;
}
}
{
unsigned int MaximumMPCCombine = 0;
mode_lib->vba.VoltageLevel = mode_lib->vba.soc.num_states + 1;
for (i = mode_lib->vba.VoltageOverrideLevel; i <= mode_lib->vba.soc.num_states; i++) {
if (locals->ModeSupport[i][0] == true || locals->ModeSupport[i][1] == true) {
mode_lib->vba.VoltageLevel = i;
if (locals->ModeSupport[i][1] == true && (locals->ModeSupport[i][0] == false
|| mode_lib->vba.WhenToDoMPCCombine == dm_mpc_always_when_possible
|| (mode_lib->vba.WhenToDoMPCCombine == dm_mpc_reduce_voltage_and_clocks
&& ((locals->DRAMClockChangeSupport[i][1] == dm_dram_clock_change_vactive
&& locals->DRAMClockChangeSupport[i][0] != dm_dram_clock_change_vactive)
|| (locals->DRAMClockChangeSupport[i][1] == dm_dram_clock_change_vblank
&& locals->DRAMClockChangeSupport[i][0] == dm_dram_clock_change_unsupported))))) {
MaximumMPCCombine = 1;
} else {
MaximumMPCCombine = 0;
}
break;
}
}
mode_lib->vba.ImmediateFlipSupport =
locals->ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.DPPPerPlane[k] = locals->NoOfDPP[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
locals->DPPCLK[k] = locals->RequiredDPPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
}
mode_lib->vba.DISPCLK = locals->RequiredDISPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
mode_lib->vba.maxMpcComb = MaximumMPCCombine;
}
mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.ODMCombineEnabled[k] =
locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
} else {
mode_lib->vba.ODMCombineEnabled[k] = dm_odm_combine_mode_disabled;
}
mode_lib->vba.DSCEnabled[k] =
locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
mode_lib->vba.OutputBpp[k] =
locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
}
}
static void CalculateWatermarksAndDRAMSpeedChangeSupport(
struct display_mode_lib *mode_lib,
unsigned int PrefetchMode,
unsigned int NumberOfActivePlanes,
unsigned int MaxLineBufferLines,
unsigned int LineBufferSize,
unsigned int DPPOutputBufferPixels,
unsigned int DETBufferSizeInKByte,
unsigned int WritebackInterfaceLumaBufferSize,
unsigned int WritebackInterfaceChromaBufferSize,
double DCFCLK,
double UrgentOutOfOrderReturn,
double ReturnBW,
bool GPUVMEnable,
int dpte_group_bytes[],
unsigned int MetaChunkSize,
double UrgentLatency,
double ExtraLatency,
double WritebackLatency,
double WritebackChunkSize,
double SOCCLK,
double DRAMClockChangeLatency,
double SRExitTime,
double SREnterPlusExitTime,
double DCFCLKDeepSleep,
int DPPPerPlane[],
bool DCCEnable[],
double DPPCLK[],
double SwathWidthSingleDPPY[],
unsigned int SwathHeightY[],
double ReadBandwidthPlaneLuma[],
unsigned int SwathHeightC[],
double ReadBandwidthPlaneChroma[],
unsigned int LBBitPerPixel[],
double SwathWidthY[],
double HRatio[],
unsigned int vtaps[],
unsigned int VTAPsChroma[],
double VRatio[],
unsigned int HTotal[],
double PixelClock[],
unsigned int BlendingAndTiming[],
double BytePerPixelDETY[],
double BytePerPixelDETC[],
bool WritebackEnable[],
enum source_format_class WritebackPixelFormat[],
double WritebackDestinationWidth[],
double WritebackDestinationHeight[],
double WritebackSourceHeight[],
enum clock_change_support *DRAMClockChangeSupport,
double *UrgentWatermark,
double *WritebackUrgentWatermark,
double *DRAMClockChangeWatermark,
double *WritebackDRAMClockChangeWatermark,
double *StutterExitWatermark,
double *StutterEnterPlusExitWatermark,
double *MinActiveDRAMClockChangeLatencySupported)
{
double EffectiveLBLatencyHidingY;
double EffectiveLBLatencyHidingC;
double DPPOutputBufferLinesY;
double DPPOutputBufferLinesC;
unsigned int DETBufferSizeY;
unsigned int DETBufferSizeC;
double LinesInDETY[DC__NUM_DPP__MAX];
double LinesInDETC;
unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX];
unsigned int LinesInDETCRoundedDownToSwath;
double FullDETBufferingTimeY[DC__NUM_DPP__MAX];
double FullDETBufferingTimeC;
double ActiveDRAMClockChangeLatencyMarginY;
double ActiveDRAMClockChangeLatencyMarginC;
double WritebackDRAMClockChangeLatencyMargin;
double PlaneWithMinActiveDRAMClockChangeMargin;
double SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank;
double FullDETBufferingTimeYStutterCriticalPlane = 0;
double TimeToFinishSwathTransferStutterCriticalPlane = 0;
unsigned int k, j;
mode_lib->vba.TotalActiveDPP = 0;
mode_lib->vba.TotalDCCActiveDPP = 0;
for (k = 0; k < NumberOfActivePlanes; ++k) {
mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP + DPPPerPlane[k];
if (DCCEnable[k] == true) {
mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP + DPPPerPlane[k];
}
}
mode_lib->vba.TotalDataReadBandwidth = 0;
for (k = 0; k < NumberOfActivePlanes; ++k) {
mode_lib->vba.TotalDataReadBandwidth = mode_lib->vba.TotalDataReadBandwidth
+ ReadBandwidthPlaneLuma[k] + ReadBandwidthPlaneChroma[k];
}
*UrgentWatermark = UrgentLatency + ExtraLatency;
*DRAMClockChangeWatermark = DRAMClockChangeLatency + *UrgentWatermark;
mode_lib->vba.TotalActiveWriteback = 0;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (WritebackEnable[k] == true) {
mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
}
}
if (mode_lib->vba.TotalActiveWriteback <= 1) {
*WritebackUrgentWatermark = WritebackLatency;
} else {
*WritebackUrgentWatermark = WritebackLatency
+ WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
}
if (mode_lib->vba.TotalActiveWriteback <= 1) {
*WritebackDRAMClockChangeWatermark = DRAMClockChangeLatency + WritebackLatency;
} else {
*WritebackDRAMClockChangeWatermark = DRAMClockChangeLatency + WritebackLatency
+ WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
}
for (k = 0; k < NumberOfActivePlanes; ++k) {
mode_lib->vba.LBLatencyHidingSourceLinesY = dml_min((double) MaxLineBufferLines,
dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(HRatio[k], 1.0)), 1))
- (vtaps[k] - 1);
mode_lib->vba.LBLatencyHidingSourceLinesC = dml_min((double) MaxLineBufferLines,
dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthY[k] / 2 / dml_max(HRatio[k] / 2, 1.0)), 1))
- (VTAPsChroma[k] - 1);
EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY / VRatio[k]
* (HTotal[k] / PixelClock[k]);
EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
/ (VRatio[k] / 2) * (HTotal[k] / PixelClock[k]);
if (SwathWidthY[k] > 2 * DPPOutputBufferPixels) {
DPPOutputBufferLinesY = (double) DPPOutputBufferPixels / SwathWidthY[k];
} else if (SwathWidthY[k] > DPPOutputBufferPixels) {
DPPOutputBufferLinesY = 0.5;
} else {
DPPOutputBufferLinesY = 1;
}
if (SwathWidthY[k] / 2.0 > 2 * DPPOutputBufferPixels) {
DPPOutputBufferLinesC = (double) DPPOutputBufferPixels
/ (SwathWidthY[k] / 2.0);
} else if (SwathWidthY[k] / 2.0 > DPPOutputBufferPixels) {
DPPOutputBufferLinesC = 0.5;
} else {
DPPOutputBufferLinesC = 1;
}
CalculateDETBufferSize(
DETBufferSizeInKByte,
SwathHeightY[k],
SwathHeightC[k],
&DETBufferSizeY,
&DETBufferSizeC);
LinesInDETY[k] = (double)DETBufferSizeY / BytePerPixelDETY[k] / SwathWidthY[k];
LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
FullDETBufferingTimeY[k] = LinesInDETYRoundedDownToSwath[k]
* (HTotal[k] / PixelClock[k]) / VRatio[k];
if (BytePerPixelDETC[k] > 0) {
LinesInDETC = (double)DETBufferSizeC / BytePerPixelDETC[k] / (SwathWidthY[k] / 2.0);
LinesInDETCRoundedDownToSwath = dml_floor(LinesInDETC, SwathHeightC[k]);
FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath
* (HTotal[k] / PixelClock[k]) / (VRatio[k] / 2);
} else {
LinesInDETC = 0;
FullDETBufferingTimeC = 999999;
}
ActiveDRAMClockChangeLatencyMarginY = HTotal[k] / PixelClock[k]
* DPPOutputBufferLinesY + EffectiveLBLatencyHidingY
+ FullDETBufferingTimeY[k] - *DRAMClockChangeWatermark;
if (NumberOfActivePlanes > 1) {
ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY
- (1 - 1.0 / NumberOfActivePlanes) * SwathHeightY[k] * HTotal[k] / PixelClock[k] / VRatio[k];
}
if (BytePerPixelDETC[k] > 0) {
ActiveDRAMClockChangeLatencyMarginC = HTotal[k] / PixelClock[k]
* DPPOutputBufferLinesC + EffectiveLBLatencyHidingC
+ FullDETBufferingTimeC - *DRAMClockChangeWatermark;
if (NumberOfActivePlanes > 1) {
ActiveDRAMClockChangeLatencyMarginC = ActiveDRAMClockChangeLatencyMarginC
- (1 - 1.0 / NumberOfActivePlanes) * SwathHeightC[k] * HTotal[k] / PixelClock[k] / (VRatio[k] / 2);
}
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
ActiveDRAMClockChangeLatencyMarginY,
ActiveDRAMClockChangeLatencyMarginC);
} else {
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = ActiveDRAMClockChangeLatencyMarginY;
}
if (WritebackEnable[k] == true) {
if (WritebackPixelFormat[k] == dm_444_32) {
WritebackDRAMClockChangeLatencyMargin = (WritebackInterfaceLumaBufferSize
+ WritebackInterfaceChromaBufferSize) / (WritebackDestinationWidth[k]
* WritebackDestinationHeight[k] / (WritebackSourceHeight[k] * HTotal[k]
/ PixelClock[k]) * 4) - *WritebackDRAMClockChangeWatermark;
} else {
WritebackDRAMClockChangeLatencyMargin = dml_min(
WritebackInterfaceLumaBufferSize * 8.0 / 10,
2 * WritebackInterfaceChromaBufferSize * 8.0 / 10) / (WritebackDestinationWidth[k]
* WritebackDestinationHeight[k] / (WritebackSourceHeight[k] * HTotal[k] / PixelClock[k]))
- *WritebackDRAMClockChangeWatermark;
}
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
WritebackDRAMClockChangeLatencyMargin);
}
}
mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
PlaneWithMinActiveDRAMClockChangeMargin = 0;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
< mode_lib->vba.MinActiveDRAMClockChangeMargin) {
mode_lib->vba.MinActiveDRAMClockChangeMargin =
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
if (BlendingAndTiming[k] == k) {
PlaneWithMinActiveDRAMClockChangeMargin = k;
} else {
for (j = 0; j < NumberOfActivePlanes; ++j) {
if (BlendingAndTiming[k] == j) {
PlaneWithMinActiveDRAMClockChangeMargin = j;
}
}
}
}
}
*MinActiveDRAMClockChangeLatencySupported = mode_lib->vba.MinActiveDRAMClockChangeMargin + DRAMClockChangeLatency;
SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (BlendingAndTiming[k] == k))
&& !(BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin)
&& mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
< SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank =
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
}
}
mode_lib->vba.TotalNumberOfActiveOTG = 0;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (BlendingAndTiming[k] == k) {
mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG + 1;
}
}
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) {
*DRAMClockChangeSupport = dm_dram_clock_change_vactive;
} else if (((mode_lib->vba.SynchronizedVBlank == true
|| mode_lib->vba.TotalNumberOfActiveOTG == 1
|| SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0)
&& PrefetchMode == 0)) {
*DRAMClockChangeSupport = dm_dram_clock_change_vblank;
} else {
*DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
}
FullDETBufferingTimeYStutterCriticalPlane = FullDETBufferingTimeY[0];
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (FullDETBufferingTimeY[k] <= FullDETBufferingTimeYStutterCriticalPlane) {
TimeToFinishSwathTransferStutterCriticalPlane = (SwathHeightY[k]
- (LinesInDETY[k] - LinesInDETYRoundedDownToSwath[k]))
* (HTotal[k] / PixelClock[k]) / VRatio[k];
}
}
*StutterExitWatermark = SRExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark
+ ExtraLatency + 10 / DCFCLKDeepSleep;
*StutterEnterPlusExitWatermark = dml_max(
SREnterPlusExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark
+ ExtraLatency + 10 / DCFCLKDeepSleep,
TimeToFinishSwathTransferStutterCriticalPlane);
}
static void CalculateDCFCLKDeepSleep(
struct display_mode_lib *mode_lib,
unsigned int NumberOfActivePlanes,
double BytePerPixelDETY[],
double BytePerPixelDETC[],
double VRatio[],
double SwathWidthY[],
int DPPPerPlane[],
double HRatio[],
double PixelClock[],
double PSCL_THROUGHPUT[],
double PSCL_THROUGHPUT_CHROMA[],
double DPPCLK[],
double *DCFCLKDeepSleep)
{
unsigned int k;
double DisplayPipeLineDeliveryTimeLuma;
double DisplayPipeLineDeliveryTimeChroma;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (VRatio[k] <= 1) {
DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerPlane[k]
/ HRatio[k] / PixelClock[k];
} else {
DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k]
/ DPPCLK[k];
}
if (BytePerPixelDETC[k] == 0) {
DisplayPipeLineDeliveryTimeChroma = 0;
} else {
if (VRatio[k] / 2 <= 1) {
DisplayPipeLineDeliveryTimeChroma = SwathWidthY[k] / 2.0
* DPPPerPlane[k] / (HRatio[k] / 2) / PixelClock[k];
} else {
DisplayPipeLineDeliveryTimeChroma = SwathWidthY[k] / 2.0
/ PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
}
}
if (BytePerPixelDETC[k] > 0) {
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(
1.1 * SwathWidthY[k] * dml_ceil(BytePerPixelDETY[k], 1)
/ 32.0 / DisplayPipeLineDeliveryTimeLuma,
1.1 * SwathWidthY[k] / 2.0
* dml_ceil(BytePerPixelDETC[k], 2) / 32.0
/ DisplayPipeLineDeliveryTimeChroma);
} else {
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = 1.1 * SwathWidthY[k]
* dml_ceil(BytePerPixelDETY[k], 1) / 64.0
/ DisplayPipeLineDeliveryTimeLuma;
}
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(
mode_lib->vba.DCFCLKDeepSleepPerPlane[k],
PixelClock[k] / 16);
}
*DCFCLKDeepSleep = 8;
for (k = 0; k < NumberOfActivePlanes; ++k) {
*DCFCLKDeepSleep = dml_max(
*DCFCLKDeepSleep,
mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
}
}
static void CalculateDETBufferSize(
unsigned int DETBufferSizeInKByte,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
unsigned int *DETBufferSizeY,
unsigned int *DETBufferSizeC)
{
if (SwathHeightC == 0) {
*DETBufferSizeY = DETBufferSizeInKByte * 1024;
*DETBufferSizeC = 0;
} else if (SwathHeightY <= SwathHeightC) {
*DETBufferSizeY = DETBufferSizeInKByte * 1024 / 2;
*DETBufferSizeC = DETBufferSizeInKByte * 1024 / 2;
} else {
*DETBufferSizeY = DETBufferSizeInKByte * 1024 * 2 / 3;
*DETBufferSizeC = DETBufferSizeInKByte * 1024 / 3;
}
}
static void CalculateUrgentBurstFactor(
unsigned int DETBufferSizeInKByte,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
unsigned int SwathWidthY,
double LineTime,
double UrgentLatency,
double CursorBufferSize,
unsigned int CursorWidth,
unsigned int CursorBPP,
double VRatio,
double VRatioPreY,
double VRatioPreC,
double BytePerPixelInDETY,
double BytePerPixelInDETC,
double *UrgentBurstFactorCursor,
double *UrgentBurstFactorCursorPre,
double *UrgentBurstFactorLuma,
double *UrgentBurstFactorLumaPre,
double *UrgentBurstFactorChroma,
double *UrgentBurstFactorChromaPre,
unsigned int *NotEnoughUrgentLatencyHiding,
unsigned int *NotEnoughUrgentLatencyHidingPre)
{
double LinesInDETLuma;
double LinesInDETChroma;
unsigned int LinesInCursorBuffer;
double CursorBufferSizeInTime;
double CursorBufferSizeInTimePre;
double DETBufferSizeInTimeLuma;
double DETBufferSizeInTimeLumaPre;
double DETBufferSizeInTimeChroma;
double DETBufferSizeInTimeChromaPre;
unsigned int DETBufferSizeY;
unsigned int DETBufferSizeC;
*NotEnoughUrgentLatencyHiding = 0;
*NotEnoughUrgentLatencyHidingPre = 0;
if (CursorWidth > 0) {
LinesInCursorBuffer = 1 << (unsigned int) dml_floor(
dml_log2(CursorBufferSize * 1024.0 / (CursorWidth * CursorBPP / 8.0)), 1.0);
CursorBufferSizeInTime = LinesInCursorBuffer * LineTime / VRatio;
if (CursorBufferSizeInTime - UrgentLatency <= 0) {
*NotEnoughUrgentLatencyHiding = 1;
*UrgentBurstFactorCursor = 0;
} else {
*UrgentBurstFactorCursor = CursorBufferSizeInTime
/ (CursorBufferSizeInTime - UrgentLatency);
}
if (VRatioPreY > 0) {
CursorBufferSizeInTimePre = LinesInCursorBuffer * LineTime / VRatioPreY;
if (CursorBufferSizeInTimePre - UrgentLatency <= 0) {
*NotEnoughUrgentLatencyHidingPre = 1;
*UrgentBurstFactorCursorPre = 0;
} else {
*UrgentBurstFactorCursorPre = CursorBufferSizeInTimePre
/ (CursorBufferSizeInTimePre - UrgentLatency);
}
} else {
*UrgentBurstFactorCursorPre = 1;
}
}
CalculateDETBufferSize(
DETBufferSizeInKByte,
SwathHeightY,
SwathHeightC,
&DETBufferSizeY,
&DETBufferSizeC);
LinesInDETLuma = (double)DETBufferSizeY / BytePerPixelInDETY / SwathWidthY;
DETBufferSizeInTimeLuma = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
*NotEnoughUrgentLatencyHiding = 1;
*UrgentBurstFactorLuma = 0;
} else {
*UrgentBurstFactorLuma = DETBufferSizeInTimeLuma
/ (DETBufferSizeInTimeLuma - UrgentLatency);
}
if (VRatioPreY > 0) {
DETBufferSizeInTimeLumaPre = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime
/ VRatioPreY;
if (DETBufferSizeInTimeLumaPre - UrgentLatency <= 0) {
*NotEnoughUrgentLatencyHidingPre = 1;
*UrgentBurstFactorLumaPre = 0;
} else {
*UrgentBurstFactorLumaPre = DETBufferSizeInTimeLumaPre
/ (DETBufferSizeInTimeLumaPre - UrgentLatency);
}
} else {
*UrgentBurstFactorLumaPre = 1;
}
if (BytePerPixelInDETC > 0) {
LinesInDETChroma = (double)DETBufferSizeC / BytePerPixelInDETC / (SwathWidthY / 2);
DETBufferSizeInTimeChroma = dml_floor(LinesInDETChroma, SwathHeightC) * LineTime
/ (VRatio / 2);
if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
*NotEnoughUrgentLatencyHiding = 1;
*UrgentBurstFactorChroma = 0;
} else {
*UrgentBurstFactorChroma = DETBufferSizeInTimeChroma
/ (DETBufferSizeInTimeChroma - UrgentLatency);
}
if (VRatioPreC > 0) {
DETBufferSizeInTimeChromaPre = dml_floor(LinesInDETChroma, SwathHeightC)
* LineTime / VRatioPreC;
if (DETBufferSizeInTimeChromaPre - UrgentLatency <= 0) {
*NotEnoughUrgentLatencyHidingPre = 1;
*UrgentBurstFactorChromaPre = 0;
} else {
*UrgentBurstFactorChromaPre = DETBufferSizeInTimeChromaPre
/ (DETBufferSizeInTimeChromaPre - UrgentLatency);
}
} else {
*UrgentBurstFactorChromaPre = 1;
}
}
}
static void CalculatePixelDeliveryTimes(
unsigned int NumberOfActivePlanes,
double VRatio[],
double VRatioPrefetchY[],
double VRatioPrefetchC[],
unsigned int swath_width_luma_ub[],
unsigned int swath_width_chroma_ub[],
int DPPPerPlane[],
double HRatio[],
double PixelClock[],
double PSCL_THROUGHPUT[],
double PSCL_THROUGHPUT_CHROMA[],
double DPPCLK[],
double BytePerPixelDETC[],
enum scan_direction_class SourceScan[],
unsigned int BlockWidth256BytesY[],
unsigned int BlockHeight256BytesY[],
unsigned int BlockWidth256BytesC[],
unsigned int BlockHeight256BytesC[],
double DisplayPipeLineDeliveryTimeLuma[],
double DisplayPipeLineDeliveryTimeChroma[],
double DisplayPipeLineDeliveryTimeLumaPrefetch[],
double DisplayPipeLineDeliveryTimeChromaPrefetch[],
double DisplayPipeRequestDeliveryTimeLuma[],
double DisplayPipeRequestDeliveryTimeChroma[],
double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
double DisplayPipeRequestDeliveryTimeChromaPrefetch[])
{
double req_per_swath_ub;
unsigned int k;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (VRatio[k] <= 1) {
DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] * DPPPerPlane[k]
/ HRatio[k] / PixelClock[k];
} else {
DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k]
/ PSCL_THROUGHPUT[k] / DPPCLK[k];
}
if (BytePerPixelDETC[k] == 0) {
DisplayPipeLineDeliveryTimeChroma[k] = 0;
} else {
if (VRatio[k] / 2 <= 1) {
DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k]
* DPPPerPlane[k] / (HRatio[k] / 2) / PixelClock[k];
} else {
DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k]
/ PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
}
}
if (VRatioPrefetchY[k] <= 1) {
DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k]
* DPPPerPlane[k] / HRatio[k] / PixelClock[k];
} else {
DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k]
/ PSCL_THROUGHPUT[k] / DPPCLK[k];
}
if (BytePerPixelDETC[k] == 0) {
DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
} else {
if (VRatioPrefetchC[k] <= 1) {
DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
swath_width_chroma_ub[k] * DPPPerPlane[k]
/ (HRatio[k] / 2) / PixelClock[k];
} else {
DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
}
}
}
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (SourceScan[k] == dm_horz) {
req_per_swath_ub = swath_width_luma_ub[k] / BlockWidth256BytesY[k];
} else {
req_per_swath_ub = swath_width_luma_ub[k] / BlockHeight256BytesY[k];
}
DisplayPipeRequestDeliveryTimeLuma[k] = DisplayPipeLineDeliveryTimeLuma[k]
/ req_per_swath_ub;
DisplayPipeRequestDeliveryTimeLumaPrefetch[k] =
DisplayPipeLineDeliveryTimeLumaPrefetch[k] / req_per_swath_ub;
if (BytePerPixelDETC[k] == 0) {
DisplayPipeRequestDeliveryTimeChroma[k] = 0;
DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0;
} else {
if (SourceScan[k] == dm_horz) {
req_per_swath_ub = swath_width_chroma_ub[k]
/ BlockWidth256BytesC[k];
} else {
req_per_swath_ub = swath_width_chroma_ub[k]
/ BlockHeight256BytesC[k];
}
DisplayPipeRequestDeliveryTimeChroma[k] =
DisplayPipeLineDeliveryTimeChroma[k] / req_per_swath_ub;
DisplayPipeRequestDeliveryTimeChromaPrefetch[k] =
DisplayPipeLineDeliveryTimeChromaPrefetch[k] / req_per_swath_ub;
}
}
}
static void CalculateMetaAndPTETimes(
unsigned int NumberOfActivePlanes,
bool GPUVMEnable,
unsigned int MetaChunkSize,
unsigned int MinMetaChunkSizeBytes,
unsigned int GPUVMMaxPageTableLevels,
unsigned int HTotal[],
double VRatio[],
double VRatioPrefetchY[],
double VRatioPrefetchC[],
double DestinationLinesToRequestRowInVBlank[],
double DestinationLinesToRequestRowInImmediateFlip[],
double DestinationLinesToRequestVMInVBlank[],
double DestinationLinesToRequestVMInImmediateFlip[],
bool DCCEnable[],
double PixelClock[],
double BytePerPixelDETY[],
double BytePerPixelDETC[],
enum scan_direction_class SourceScan[],
unsigned int dpte_row_height[],
unsigned int dpte_row_height_chroma[],
unsigned int meta_row_width[],
unsigned int meta_row_height[],
unsigned int meta_req_width[],
unsigned int meta_req_height[],
int dpte_group_bytes[],
unsigned int PTERequestSizeY[],
unsigned int PTERequestSizeC[],
unsigned int PixelPTEReqWidthY[],
unsigned int PixelPTEReqHeightY[],
unsigned int PixelPTEReqWidthC[],
unsigned int PixelPTEReqHeightC[],
unsigned int dpte_row_width_luma_ub[],
unsigned int dpte_row_width_chroma_ub[],
unsigned int vm_group_bytes[],
unsigned int dpde0_bytes_per_frame_ub_l[],
unsigned int dpde0_bytes_per_frame_ub_c[],
unsigned int meta_pte_bytes_per_frame_ub_l[],
unsigned int meta_pte_bytes_per_frame_ub_c[],
double DST_Y_PER_PTE_ROW_NOM_L[],
double DST_Y_PER_PTE_ROW_NOM_C[],
double DST_Y_PER_META_ROW_NOM_L[],
double TimePerMetaChunkNominal[],
double TimePerMetaChunkVBlank[],
double TimePerMetaChunkFlip[],
double time_per_pte_group_nom_luma[],
double time_per_pte_group_vblank_luma[],
double time_per_pte_group_flip_luma[],
double time_per_pte_group_nom_chroma[],
double time_per_pte_group_vblank_chroma[],
double time_per_pte_group_flip_chroma[],
double TimePerVMGroupVBlank[],
double TimePerVMGroupFlip[],
double TimePerVMRequestVBlank[],
double TimePerVMRequestFlip[])
{
unsigned int meta_chunk_width;
unsigned int min_meta_chunk_width;
unsigned int meta_chunk_per_row_int;
unsigned int meta_row_remainder;
unsigned int meta_chunk_threshold;
unsigned int meta_chunks_per_row_ub;
unsigned int dpte_group_width_luma;
unsigned int dpte_group_width_chroma;
unsigned int dpte_groups_per_row_luma_ub;
unsigned int dpte_groups_per_row_chroma_ub;
unsigned int num_group_per_lower_vm_stage;
unsigned int num_req_per_lower_vm_stage;
unsigned int k;
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (GPUVMEnable == true) {
DST_Y_PER_PTE_ROW_NOM_L[k] = dpte_row_height[k] / VRatio[k];
if (BytePerPixelDETC[k] == 0) {
DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
} else {
DST_Y_PER_PTE_ROW_NOM_C[k] = dpte_row_height_chroma[k] / (VRatio[k] / 2);
}
} else {
DST_Y_PER_PTE_ROW_NOM_L[k] = 0;
DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
}
if (DCCEnable[k] == true) {
DST_Y_PER_META_ROW_NOM_L[k] = meta_row_height[k] / VRatio[k];
} else {
DST_Y_PER_META_ROW_NOM_L[k] = 0;
}
}
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (DCCEnable[k] == true) {
meta_chunk_width = MetaChunkSize * 1024 * 256
/ dml_ceil(BytePerPixelDETY[k], 1) / meta_row_height[k];
min_meta_chunk_width = MinMetaChunkSizeBytes * 256
/ dml_ceil(BytePerPixelDETY[k], 1) / meta_row_height[k];
meta_chunk_per_row_int = meta_row_width[k] / meta_chunk_width;
meta_row_remainder = meta_row_width[k] % meta_chunk_width;
if (SourceScan[k] == dm_horz) {
meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width[k];
} else {
meta_chunk_threshold = 2 * min_meta_chunk_width
- meta_req_height[k];
}
if (meta_row_remainder <= meta_chunk_threshold) {
meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
} else {
meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
}
TimePerMetaChunkNominal[k] = meta_row_height[k] / VRatio[k] * HTotal[k]
/ PixelClock[k] / meta_chunks_per_row_ub;
TimePerMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k]
* HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
TimePerMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k]
* HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
} else {
TimePerMetaChunkNominal[k] = 0;
TimePerMetaChunkVBlank[k] = 0;
TimePerMetaChunkFlip[k] = 0;
}
}
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (GPUVMEnable == true) {
if (SourceScan[k] == dm_horz) {
dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k]
* PixelPTEReqWidthY[k];
} else {
dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k]
* PixelPTEReqHeightY[k];
}
dpte_groups_per_row_luma_ub = dml_ceil(
(float) dpte_row_width_luma_ub[k] / dpte_group_width_luma,
1);
time_per_pte_group_nom_luma[k] = DST_Y_PER_PTE_ROW_NOM_L[k] * HTotal[k]
/ PixelClock[k] / dpte_groups_per_row_luma_ub;
time_per_pte_group_vblank_luma[k] = DestinationLinesToRequestRowInVBlank[k]
* HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
time_per_pte_group_flip_luma[k] =
DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k]
/ PixelClock[k]
/ dpte_groups_per_row_luma_ub;
if (BytePerPixelDETC[k] == 0) {
time_per_pte_group_nom_chroma[k] = 0;
time_per_pte_group_vblank_chroma[k] = 0;
time_per_pte_group_flip_chroma[k] = 0;
} else {
if (SourceScan[k] == dm_horz) {
dpte_group_width_chroma = dpte_group_bytes[k]
/ PTERequestSizeC[k] * PixelPTEReqWidthC[k];
} else {
dpte_group_width_chroma = dpte_group_bytes[k]
/ PTERequestSizeC[k]
* PixelPTEReqHeightC[k];
}
dpte_groups_per_row_chroma_ub = dml_ceil(
(float) dpte_row_width_chroma_ub[k]
/ dpte_group_width_chroma,
1);
time_per_pte_group_nom_chroma[k] = DST_Y_PER_PTE_ROW_NOM_C[k]
* HTotal[k] / PixelClock[k]
/ dpte_groups_per_row_chroma_ub;
time_per_pte_group_vblank_chroma[k] =
DestinationLinesToRequestRowInVBlank[k] * HTotal[k]
/ PixelClock[k]
/ dpte_groups_per_row_chroma_ub;
time_per_pte_group_flip_chroma[k] =
DestinationLinesToRequestRowInImmediateFlip[k]
* HTotal[k] / PixelClock[k]
/ dpte_groups_per_row_chroma_ub;
}
} else {
time_per_pte_group_nom_luma[k] = 0;
time_per_pte_group_vblank_luma[k] = 0;
time_per_pte_group_flip_luma[k] = 0;
time_per_pte_group_nom_chroma[k] = 0;
time_per_pte_group_vblank_chroma[k] = 0;
time_per_pte_group_flip_chroma[k] = 0;
}
}
for (k = 0; k < NumberOfActivePlanes; ++k) {
if (GPUVMEnable == true && (DCCEnable[k] == true || GPUVMMaxPageTableLevels > 1)) {
if (DCCEnable[k] == false) {
if (BytePerPixelDETC[k] > 0) {
num_group_per_lower_vm_stage =
dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
+ dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
} else {
num_group_per_lower_vm_stage =
dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
}
} else {
if (GPUVMMaxPageTableLevels == 1) {
if (BytePerPixelDETC[k] > 0) {
num_group_per_lower_vm_stage =
dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
} else {
num_group_per_lower_vm_stage =
dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
}
} else {
if (BytePerPixelDETC[k] > 0) {
num_group_per_lower_vm_stage =
dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
+ dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1)
+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
} else {
num_group_per_lower_vm_stage =
dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
}
}
}
if (DCCEnable[k] == false) {
if (BytePerPixelDETC[k] > 0) {
num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k]
/ 64 + dpde0_bytes_per_frame_ub_c[k] / 64;
} else {
num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k]
/ 64;
}
} else {
if (GPUVMMaxPageTableLevels == 1) {
if (BytePerPixelDETC[k] > 0) {
num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64
+ meta_pte_bytes_per_frame_ub_c[k] / 64;
} else {
num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64;
}
} else {
if (BytePerPixelDETC[k] > 0) {
num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64
+ dpde0_bytes_per_frame_ub_c[k] / 64
+ meta_pte_bytes_per_frame_ub_l[k] / 64
+ meta_pte_bytes_per_frame_ub_c[k] / 64;
} else {
num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64
+ meta_pte_bytes_per_frame_ub_l[k] / 64;
}
}
}
TimePerVMGroupVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k]
/ PixelClock[k] / num_group_per_lower_vm_stage;
TimePerVMGroupFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k]
* HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
TimePerVMRequestVBlank[k] = DestinationLinesToRequestVMInVBlank[k]
* HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
TimePerVMRequestFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k]
* HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
if (GPUVMMaxPageTableLevels > 2) {
TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2;
TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2;
TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2;
TimePerVMRequestFlip[k] = TimePerVMRequestFlip[k] / 2;
}
} else {
TimePerVMGroupVBlank[k] = 0;
TimePerVMGroupFlip[k] = 0;
TimePerVMRequestVBlank[k] = 0;
TimePerVMRequestFlip[k] = 0;
}
}
}
static double CalculateExtraLatency(
double UrgentRoundTripAndOutOfOrderLatency,
int TotalNumberOfActiveDPP,
int PixelChunkSizeInKByte,
int TotalNumberOfDCCActiveDPP,
int MetaChunkSize,
double ReturnBW,
bool GPUVMEnable,
bool HostVMEnable,
int NumberOfActivePlanes,
int NumberOfDPP[],
int dpte_group_bytes[],
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
int HostVMMaxPageTableLevels,
int HostVMCachedPageTableLevels)
{
double CalculateExtraLatency;
double HostVMInefficiencyFactor;
int HostVMDynamicLevels;
if (GPUVMEnable && HostVMEnable) {
HostVMInefficiencyFactor =
PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData
/ PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
HostVMDynamicLevels = HostVMMaxPageTableLevels - HostVMCachedPageTableLevels;
} else {
HostVMInefficiencyFactor = 1;
HostVMDynamicLevels = 0;
}
CalculateExtraLatency = UrgentRoundTripAndOutOfOrderLatency
+ (TotalNumberOfActiveDPP * PixelChunkSizeInKByte
+ TotalNumberOfDCCActiveDPP * MetaChunkSize) * 1024.0
/ ReturnBW;
if (GPUVMEnable) {
int k;
for (k = 0; k < NumberOfActivePlanes; k++) {
CalculateExtraLatency = CalculateExtraLatency
+ NumberOfDPP[k] * dpte_group_bytes[k]
* (1 + 8 * HostVMDynamicLevels)
* HostVMInefficiencyFactor / ReturnBW;
}
}
return CalculateExtraLatency;
}