6121 lines
229 KiB
C
6121 lines
229 KiB
C
/*
|
|
* Copyright 2017 Advanced Micro Devices, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* Authors: AMD
|
|
*
|
|
*/
|
|
|
|
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
|
|
|
#include "../display_mode_lib.h"
|
|
#include "../dml_inline_defs.h"
|
|
#include "../display_mode_vba.h"
|
|
#include "display_mode_vba_21.h"
|
|
|
|
|
|
/*
|
|
* NOTE:
|
|
* This file is gcc-parsable HW gospel, coming straight from HW engineers.
|
|
*
|
|
* It doesn't adhere to Linux kernel style and sometimes will do things in odd
|
|
* ways. Unless there is something clearly wrong with it the code should
|
|
* remain as-is as it provides us with a guarantee from HW that it is correct.
|
|
*/
|
|
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
|
|
|
|
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);
|
|
// Super monster function with some 45 argument
|
|
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,
|
|
double 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,
|
|
long *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,
|
|
double DETBufferSizeInKByte,
|
|
unsigned int WritebackInterfaceLumaBufferSize,
|
|
unsigned int WritebackInterfaceChromaBufferSize,
|
|
double DCFCLK,
|
|
double UrgentOutOfOrderReturn,
|
|
double ReturnBW,
|
|
bool GPUVMEnable,
|
|
long 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[],
|
|
unsigned int SwathWidthSingleDPPY[],
|
|
unsigned int SwathHeightY[],
|
|
double ReadBandwidthPlaneLuma[],
|
|
unsigned int SwathHeightC[],
|
|
double ReadBandwidthPlaneChroma[],
|
|
unsigned int LBBitPerPixel[],
|
|
unsigned int 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[],
|
|
unsigned int SwathWidthY[],
|
|
int DPPPerPlane[],
|
|
double HRatio[],
|
|
double PixelClock[],
|
|
double PSCL_THROUGHPUT[],
|
|
double PSCL_THROUGHPUT_CHROMA[],
|
|
double DPPCLK[],
|
|
double *DCFCLKDeepSleep);
|
|
static void CalculateDETBufferSize(
|
|
double DETBufferSizeInKByte,
|
|
unsigned int SwathHeightY,
|
|
unsigned int SwathHeightC,
|
|
double *DETBufferSizeY,
|
|
double *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[],
|
|
long 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[],
|
|
long 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)
|
|
{
|
|
// valid bpc = source bits per component in the set of {8, 10, 12}
|
|
// valid bpp = increments of 1/16 of a bit
|
|
// min = 6/7/8 in N420/N422/444, respectively
|
|
// max = such that compression is 1:1
|
|
//valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
|
|
//valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
|
|
//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
|
|
|
|
// fixed value
|
|
unsigned int rcModelSize = 8192;
|
|
|
|
// N422/N420 operate at 2 pixels per clock
|
|
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;
|
|
// #all other modes operate at 1 pixel per clock
|
|
else
|
|
pixelsPerClock = 1;
|
|
|
|
//initial transmit delay as per PPS
|
|
initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
|
|
|
|
//compute ssm delay
|
|
if (bpc == 8)
|
|
D = 81;
|
|
else if (bpc == 10)
|
|
D = 89;
|
|
else
|
|
D = 113;
|
|
|
|
//divide by pixel per cycle to compute slice width as seen by DSC
|
|
w = sliceWidth / pixelsPerClock;
|
|
|
|
//422 mode has an additional cycle of delay
|
|
if (pixelFormat == dm_s422)
|
|
S = 1;
|
|
else
|
|
S = 0;
|
|
|
|
//main calculation for the dscce
|
|
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;
|
|
|
|
//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
|
|
pixels = Delay * 3 * pixelsPerClock;
|
|
return pixels;
|
|
}
|
|
|
|
static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
|
|
{
|
|
unsigned int Delay = 0;
|
|
|
|
if (pixelFormat == dm_420) {
|
|
// sfr
|
|
Delay = Delay + 2;
|
|
// dsccif
|
|
Delay = Delay + 0;
|
|
// dscc - input deserializer
|
|
Delay = Delay + 3;
|
|
// dscc gets pixels every other cycle
|
|
Delay = Delay + 2;
|
|
// dscc - input cdc fifo
|
|
Delay = Delay + 12;
|
|
// dscc gets pixels every other cycle
|
|
Delay = Delay + 13;
|
|
// dscc - cdc uncertainty
|
|
Delay = Delay + 2;
|
|
// dscc - output cdc fifo
|
|
Delay = Delay + 7;
|
|
// dscc gets pixels every other cycle
|
|
Delay = Delay + 3;
|
|
// dscc - cdc uncertainty
|
|
Delay = Delay + 2;
|
|
// dscc - output serializer
|
|
Delay = Delay + 1;
|
|
// sft
|
|
Delay = Delay + 1;
|
|
} else if (pixelFormat == dm_n422) {
|
|
// sfr
|
|
Delay = Delay + 2;
|
|
// dsccif
|
|
Delay = Delay + 1;
|
|
// dscc - input deserializer
|
|
Delay = Delay + 5;
|
|
// dscc - input cdc fifo
|
|
Delay = Delay + 25;
|
|
// dscc - cdc uncertainty
|
|
Delay = Delay + 2;
|
|
// dscc - output cdc fifo
|
|
Delay = Delay + 10;
|
|
// dscc - cdc uncertainty
|
|
Delay = Delay + 2;
|
|
// dscc - output serializer
|
|
Delay = Delay + 1;
|
|
// sft
|
|
Delay = Delay + 1;
|
|
} else {
|
|
// sfr
|
|
Delay = Delay + 2;
|
|
// dsccif
|
|
Delay = Delay + 0;
|
|
// dscc - input deserializer
|
|
Delay = Delay + 3;
|
|
// dscc - input cdc fifo
|
|
Delay = Delay + 12;
|
|
// dscc - cdc uncertainty
|
|
Delay = Delay + 2;
|
|
// dscc - output cdc fifo
|
|
Delay = Delay + 7;
|
|
// dscc - output serializer
|
|
Delay = Delay + 1;
|
|
// dscc - cdc uncertainty
|
|
Delay = Delay + 2;
|
|
// sft
|
|
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;
|
|
*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;
|
|
*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;
|
|
|
|
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 {
|
|
// 5/30/2018 - This was an optimization requested from Sy but now NumberOfCursors is no longer a factor
|
|
// so if this needs to be reinstated, then it should be officially done in the VBA code as well.
|
|
// if (mode_lib->NumberOfCursors > 0 || XFCEnabled)
|
|
TimeForFetchingMetaPTE = LineTime / 4;
|
|
// else
|
|
// TimeForFetchingMetaPTE = 0.0;
|
|
}
|
|
|
|
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 {
|
|
// See note above dated 5/30/2018
|
|
// if (NumberOfCursors > 0 || XFCEnabled)
|
|
TimeForFetchingRowInVBlank = (LineTime - TimeForFetchingMetaPTE) / 2.0;
|
|
// else // TODO: Did someone else add this??
|
|
// TimeForFetchingRowInVBlank = 0.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
|
|
// See note above dated 5/30/2018
|
|
// - ((NumberOfCursors > 0 || GPUVMEnable || DCCEnable) ?
|
|
- ((GPUVMEnable || DCCEnable) ?
|
|
(*DestinationLinesToRequestVMInVBlank + 2 * *DestinationLinesToRequestRowInVBlank) :
|
|
0.0); // TODO: Did someone else add this??
|
|
|
|
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,
|
|
double 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,
|
|
long *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;
|
|
|
|
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_lvp) {
|
|
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;
|
|
|
|
// DISPCLK and DPPCLK Calculation
|
|
//
|
|
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]);
|
|
}
|
|
|
|
// Urgent and B P-State/DRAM Clock Change Watermark
|
|
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] == true)
|
|
MainPlaneDoesODMCombine = true;
|
|
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
|
|
if (mode_lib->vba.BlendingAndTiming[k] == j
|
|
&& mode_lib->vba.ODMCombineEnabled[j] == true)
|
|
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 { // dm_420_10
|
|
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];
|
|
}
|
|
|
|
// DCFCLK Deep Sleep
|
|
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);
|
|
|
|
// DSCCLK
|
|
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);
|
|
}
|
|
}
|
|
|
|
// DSC Delay
|
|
// TODO
|
|
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) // NumberOfPlanes
|
|
if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
|
|
&& mode_lib->vba.DSCEnabled[j])
|
|
locals->DSCDelay[k] = locals->DSCDelay[j];
|
|
|
|
// Prefetch
|
|
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]);
|
|
|
|
// We don't really care to iterate between the various prefetch modes
|
|
//mode_lib->vba.PrefetchERROR = CalculateMinAndMaxPrefetchMode(mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &mode_lib->vba.MinPrefetchMode, &mode_lib->vba.MaxPrefetchMode);
|
|
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,
|
|
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,
|
|
&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 && 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));
|
|
|
|
//Watermarks and NB P-State/DRAM Clock Change Support
|
|
{
|
|
enum clock_change_support DRAMClockChangeSupport; // dummy
|
|
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,
|
|
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);
|
|
}
|
|
|
|
|
|
//Display Pipeline Delivery Time in Prefetch, Groups
|
|
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);
|
|
|
|
|
|
// Min TTUVBlank
|
|
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];
|
|
}
|
|
|
|
// DCC Configuration
|
|
mode_lib->vba.ActiveDPPs = 0;
|
|
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
|
|
locals->MaximumDCCCompressionYSurface[k] = CalculateDCCConfiguration(
|
|
mode_lib->vba.DCCEnable[k],
|
|
false, // We should always know the direction DCCProgrammingAssumesScanDirectionUnknown,
|
|
mode_lib->vba.ViewportWidth[k],
|
|
mode_lib->vba.ViewportHeight[k],
|
|
mode_lib->vba.DETBufferSizeInKByte * 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]);
|
|
}
|
|
|
|
//XFC Parameters:
|
|
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;
|
|
}
|
|
}
|
|
|
|
// Stutter Efficiency
|
|
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
|
|
CalculateDETBufferSize(
|
|
mode_lib->vba.DETBufferSizeInKByte,
|
|
mode_lib->vba.SwathHeightY[k],
|
|
mode_lib->vba.SwathHeightC[k],
|
|
&locals->DETBufferSizeY[k],
|
|
&locals->DETBufferSizeC[k]);
|
|
|
|
locals->LinesInDETY[k] = 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)
|
|
{
|
|
// Display Pipe Configuration
|
|
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] == true) {
|
|
MainPlaneDoesODMCombine = true;
|
|
}
|
|
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
|
|
if (mode_lib->vba.BlendingAndTiming[k] == j
|
|
&& mode_lib->vba.ODMCombineEnabled[j] == true) {
|
|
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 * 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,
|
|
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; // TODO: This doesn't seem to match programming guide
|
|
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;
|
|
double HostVMInefficiencyFactor;
|
|
|
|
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));
|
|
if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
|
|
if (GPUVMEnable == true && DCCEnable != true) {
|
|
min_row_time = dml_min(
|
|
dpte_row_height * LineTime / VRatio,
|
|
dpte_row_height_chroma * LineTime / (VRatio / 2));
|
|
} else if (GPUVMEnable != true && DCCEnable == true) {
|
|
min_row_time = dml_min(
|
|
meta_row_height * LineTime / VRatio,
|
|
meta_row_height_chroma * LineTime / (VRatio / 2));
|
|
} else {
|
|
min_row_time = dml_min4(
|
|
dpte_row_height * LineTime / VRatio,
|
|
meta_row_height * LineTime / VRatio,
|
|
dpte_row_height_chroma * LineTime / (VRatio / 2),
|
|
meta_row_height_chroma * LineTime / (VRatio / 2));
|
|
}
|
|
} else {
|
|
if (GPUVMEnable == true && DCCEnable != true) {
|
|
min_row_time = dpte_row_height * LineTime / VRatio;
|
|
} else if (GPUVMEnable != true && DCCEnable == true) {
|
|
min_row_time = meta_row_height * LineTime / VRatio;
|
|
} else {
|
|
min_row_time = dml_min(
|
|
dpte_row_height * LineTime / VRatio,
|
|
meta_row_height * LineTime / VRatio);
|
|
}
|
|
}
|
|
|
|
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
|
|
return BPP_INVALID;
|
|
}
|
|
}
|
|
}
|
|
|
|
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 SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
|
|
|
|
/*Scale Ratio, taps Support Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
/*Source Format, Pixel Format and Scan Support Check*/
|
|
|
|
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_lvp)
|
|
&& !((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;
|
|
}
|
|
}
|
|
/*Bandwidth Support Check*/
|
|
|
|
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] = 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] = locals->IdealSDPPortBandwidthPerState[i]
|
|
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100.0;
|
|
} else {
|
|
locals->ReturnBWPerState[i] = locals->IdealSDPPortBandwidthPerState[i]
|
|
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0;
|
|
}
|
|
}
|
|
/*Writeback Latency support check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*Re-ordering Buffer Support Check*/
|
|
|
|
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];
|
|
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i]
|
|
> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
|
|
locals->ROBSupport[i] = true;
|
|
} else {
|
|
locals->ROBSupport[i] = false;
|
|
}
|
|
}
|
|
/*Writeback Mode Support Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
/*Writeback Scale Ratio and Taps Support Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
/*Maximum DISPCLK/DPPCLK Support check*/
|
|
|
|
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 * 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++) {
|
|
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);
|
|
if (mode_lib->vba.ODMCapability == false || mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
|
|
locals->ODMCombineEnablePerState[i][k] = false;
|
|
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
|
|
} else {
|
|
locals->ODMCombineEnablePerState[i][k] = true;
|
|
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] == false) {
|
|
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] = false;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
/*Viewport Size Check*/
|
|
|
|
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
|
locals->ViewportSizeSupport[i] = true;
|
|
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
|
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
|
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] = false;
|
|
}
|
|
} else {
|
|
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
|
|
locals->ViewportSizeSupport[i] = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*Total Available Pipes Support Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
/*Total Available OTG Support Check*/
|
|
|
|
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;
|
|
}
|
|
/*Display IO and DSC Support Check*/
|
|
|
|
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] = 0;
|
|
locals->RequiresFEC[i][k] = 0;
|
|
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
|
if (mode_lib->vba.Output[k] == dm_hdmi) {
|
|
locals->RequiresDSC[i][k] = 0;
|
|
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 (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]
|
|
== true) {
|
|
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] == true) {
|
|
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;
|
|
}
|
|
}
|
|
/*DSC Delay per state*/
|
|
|
|
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] == false) {
|
|
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];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Prefetch Check
|
|
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] == true) {
|
|
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 * 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);
|
|
|
|
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[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[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[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[k] =
|
|
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
|
|
locals->MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
|
locals->DPTEBytesPerRow[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],
|
|
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;
|
|
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;
|
|
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
|
locals->MaximumVStartup[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 = dml_max(mode_lib->vba.MaxMaxVStartup, locals->MaximumVStartup[k]);
|
|
}
|
|
|
|
mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
|
|
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup;
|
|
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++) {
|
|
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;
|
|
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[k]),
|
|
locals->MaximumVStartup[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[k],
|
|
locals->MetaRowBytes[k],
|
|
locals->DPTEBytesPerRow[k],
|
|
locals->PrefetchLinesY[k],
|
|
locals->SwathWidthYThisState[k],
|
|
locals->BytePerPixelInDETY[k],
|
|
locals->PrefillY[k],
|
|
locals->MaxNumSwY[k],
|
|
locals->PrefetchLinesC[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]);
|
|
}
|
|
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,
|
|
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,
|
|
&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] = true;
|
|
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i]
|
|
|| locals->NotEnoughUrgentLatencyHiding == 1) {
|
|
locals->BandwidthWithoutPrefetchSupported[i] = false;
|
|
}
|
|
|
|
locals->PrefetchSupported[i][j] = true;
|
|
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i]
|
|
|| locals->NotEnoughUrgentLatencyHiding == 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;
|
|
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
|
|
|| 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];
|
|
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[k] + locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[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[k],
|
|
locals->MetaRowBytes[k],
|
|
locals->DPTEBytesPerRow[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]) {
|
|
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,
|
|
mode_lib->vba.WritebackInterfaceLumaBufferSize,
|
|
mode_lib->vba.WritebackInterfaceChromaBufferSize,
|
|
mode_lib->vba.DCFCLKPerState[i],
|
|
mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels,
|
|
locals->ReturnBWPerState[i],
|
|
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,
|
|
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);
|
|
}
|
|
}
|
|
|
|
/*Vertical Active BW support*/
|
|
{
|
|
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] = dml_min(
|
|
locals->IdealSDPPortBandwidthPerState[i] *
|
|
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]) {
|
|
locals->TotalVerticalActiveBandwidthSupport[i] = true;
|
|
} else {
|
|
locals->TotalVerticalActiveBandwidthSupport[i] = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*PTE Buffer Size Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*Cursor Support Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*Valid Pitch Check*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
/*Mode Support, Voltage State and SOC Configuration*/
|
|
|
|
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 != true) {
|
|
status = DML_FAIL_SCALE_RATIO_TAP;
|
|
} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
|
|
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
|
|
} else if (locals->ViewportSizeSupport[i] != true) {
|
|
status = DML_FAIL_VIEWPORT_SIZE;
|
|
} else if (locals->DIOSupport[i] != true) {
|
|
status = DML_FAIL_DIO_SUPPORT;
|
|
} else if (locals->NotEnoughDSCUnits[i] != false) {
|
|
status = DML_FAIL_NOT_ENOUGH_DSC;
|
|
} else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) {
|
|
status = DML_FAIL_DSC_CLK_REQUIRED;
|
|
} else if (locals->ROBSupport[i] != true) {
|
|
status = DML_FAIL_REORDERING_BUFFER;
|
|
} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
|
|
status = DML_FAIL_DISPCLK_DPPCLK;
|
|
} else if (locals->TotalAvailablePipesSupport[i][j] != true) {
|
|
status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
|
|
} else if (mode_lib->vba.NumberOfOTGSupport != true) {
|
|
status = DML_FAIL_NUM_OTG;
|
|
} else if (mode_lib->vba.WritebackModeSupport != true) {
|
|
status = DML_FAIL_WRITEBACK_MODE;
|
|
} else if (mode_lib->vba.WritebackLatencySupport != true) {
|
|
status = DML_FAIL_WRITEBACK_LATENCY;
|
|
} else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) {
|
|
status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
|
|
} else if (mode_lib->vba.CursorSupport != true) {
|
|
status = DML_FAIL_CURSOR_SUPPORT;
|
|
} else if (mode_lib->vba.PitchSupport != true) {
|
|
status = DML_FAIL_PITCH_SUPPORT;
|
|
} else if (locals->TotalVerticalActiveBandwidthSupport[i] != true) {
|
|
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
|
|
} else if (locals->PTEBufferSizeNotExceeded[i][j] != true) {
|
|
status = DML_FAIL_PTE_BUFFER_SIZE;
|
|
} else if (mode_lib->vba.NonsupportedDSCInputBPC != false) {
|
|
status = DML_FAIL_DSC_INPUT_BPC;
|
|
} else if ((mode_lib->vba.HostVMEnable != false
|
|
&& locals->ImmediateFlipSupportedForState[i][j] != true)) {
|
|
status = DML_FAIL_HOST_VM_IMMEDIATE_FLIP;
|
|
} else if (locals->PrefetchSupported[i][j] != true) {
|
|
status = DML_FAIL_PREFETCH_SUPPORT;
|
|
} else if (locals->VRatioInPrefetchSupported[i][j] != true) {
|
|
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];
|
|
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] = 0;
|
|
}
|
|
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,
|
|
double DETBufferSizeInKByte,
|
|
unsigned int WritebackInterfaceLumaBufferSize,
|
|
unsigned int WritebackInterfaceChromaBufferSize,
|
|
double DCFCLK,
|
|
double UrgentOutOfOrderReturn,
|
|
double ReturnBW,
|
|
bool GPUVMEnable,
|
|
long 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[],
|
|
unsigned int SwathWidthSingleDPPY[],
|
|
unsigned int SwathHeightY[],
|
|
double ReadBandwidthPlaneLuma[],
|
|
unsigned int SwathHeightC[],
|
|
double ReadBandwidthPlaneChroma[],
|
|
unsigned int LBBitPerPixel[],
|
|
unsigned int 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;
|
|
double DETBufferSizeY;
|
|
double 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] = 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 = 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) {
|
|
*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[],
|
|
unsigned int 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;
|
|
//double DCFCLKDeepSleepPerPlane[DC__NUM_DPP__MAX];
|
|
|
|
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(
|
|
double DETBufferSizeInKByte,
|
|
unsigned int SwathHeightY,
|
|
unsigned int SwathHeightC,
|
|
double *DETBufferSizeY,
|
|
double *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;
|
|
double DETBufferSizeY;
|
|
double 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 = 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 = 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[],
|
|
long 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(
|
|
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(
|
|
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[],
|
|
long 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;
|
|
}
|
|
|
|
#endif
|