/*
|
* Copyright 2020 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_DCN3_0
|
#include "dc.h"
|
#include "dc_link.h"
|
#include "../display_mode_lib.h"
|
#include "display_mode_vba_30.h"
|
#include "../dml_inline_defs.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;
|
unsigned int DCCEnable;
|
bool ODMCombineEnabled;
|
} Pipe;
|
|
#define BPP_INVALID 0
|
#define BPP_BLENDED_PIPE 0xffffffff
|
#define DCN30_MAX_DSC_IMAGE_WIDTH 5184
|
#define DCN30_MAX_FMT_420_BUFFER_WIDTH 4096
|
|
static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
|
static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
|
struct display_mode_lib *mode_lib);
|
static unsigned int dscceComputeDelay(
|
unsigned int bpc,
|
double BPP,
|
unsigned int sliceWidth,
|
unsigned int numSlices,
|
enum output_format_class pixelFormat,
|
enum output_encoder_class Output);
|
static unsigned int dscComputeDelay(
|
enum output_format_class pixelFormat,
|
enum output_encoder_class Output);
|
// 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 DPPCLKDelaySubtotalPlusCNVCFormater,
|
double DPPCLKDelaySCL,
|
double DPPCLKDelaySCLLBOnly,
|
double DPPCLKDelayCNVCCursor,
|
double DISPCLKDelaySubtotal,
|
unsigned int DPP_RECOUT_WIDTH,
|
enum output_format_class OutputFormat,
|
unsigned int MaxInterDCNTileRepeaters,
|
unsigned int VStartup,
|
unsigned int MaxVStartup,
|
unsigned int GPUVMPageTableLevels,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
unsigned int HostVMMaxNonCachedPageTableLevels,
|
double HostVMMinPageSize,
|
bool DynamicMetadataEnable,
|
bool DynamicMetadataVMEnabled,
|
int DynamicMetadataLinesBeforeActiveRequired,
|
unsigned int DynamicMetadataTransmittedBytes,
|
double UrgentLatency,
|
double UrgentExtraLatency,
|
double TCalc,
|
unsigned int PDEAndMetaPTEBytesFrame,
|
unsigned int MetaRowByte,
|
unsigned int PixelPTEBytesPerRow,
|
double PrefetchSourceLinesY,
|
unsigned int SwathWidthY,
|
int BytePerPixelY,
|
double VInitPreFillY,
|
unsigned int MaxNumSwathY,
|
double PrefetchSourceLinesC,
|
unsigned int SwathWidthC,
|
int BytePerPixelC,
|
double VInitPreFillC,
|
unsigned int MaxNumSwathC,
|
long swath_width_luma_ub,
|
long swath_width_chroma_ub,
|
unsigned int SwathHeightY,
|
unsigned int SwathHeightC,
|
double TWait,
|
bool ProgressiveToInterlaceUnitInOPP,
|
double *DSTXAfterScaler,
|
double *DSTYAfterScaler,
|
double *DestinationLinesForPrefetch,
|
double *PrefetchBandwidth,
|
double *DestinationLinesToRequestVMInVBlank,
|
double *DestinationLinesToRequestRowInVBlank,
|
double *VRatioPrefetchY,
|
double *VRatioPrefetchC,
|
double *RequiredPrefetchPixDataBWLuma,
|
double *RequiredPrefetchPixDataBWChroma,
|
bool *NotEnoughTimeForDynamicMetadata,
|
double *Tno_bw,
|
double *prefetch_vmrow_bw,
|
double *Tdmdl_vm,
|
double *Tdmdl,
|
unsigned int *VUpdateOffsetPix,
|
double *VUpdateWidthPix,
|
double *VReadyOffsetPix);
|
static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
|
static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
|
static void CalculateDCCConfiguration(
|
bool DCCEnabled,
|
bool DCCProgrammingAssumesScanDirectionUnknown,
|
enum source_format_class SourcePixelFormat,
|
unsigned int ViewportWidthLuma,
|
unsigned int ViewportWidthChroma,
|
unsigned int ViewportHeightLuma,
|
unsigned int ViewportHeightChroma,
|
double DETBufferSize,
|
unsigned int RequestHeight256ByteLuma,
|
unsigned int RequestHeight256ByteChroma,
|
enum dm_swizzle_mode TilingFormat,
|
unsigned int BytePerPixelY,
|
unsigned int BytePerPixelC,
|
double BytePerPixelDETY,
|
double BytePerPixelDETC,
|
enum scan_direction_class ScanOrientation,
|
unsigned int *MaxUncompressedBlockLuma,
|
unsigned int *MaxUncompressedBlockChroma,
|
unsigned int *MaxCompressedBlockLuma,
|
unsigned int *MaxCompressedBlockChroma,
|
unsigned int *IndependentBlockLuma,
|
unsigned int *IndependentBlockChroma);
|
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 SwathWidth,
|
unsigned int ViewportHeight,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
unsigned int HostVMMaxNonCachedPageTableLevels,
|
unsigned int GPUVMMinPageSize,
|
unsigned int HostVMMinPageSize,
|
unsigned int PTEBufferSizeInRequests,
|
unsigned int Pitch,
|
unsigned int DCCMetaPitch,
|
unsigned int *MacroTileWidth,
|
unsigned int *MetaRowByte,
|
unsigned int *PixelPTEBytesPerRow,
|
bool *PTEBufferSizeNotExceeded,
|
unsigned int *dpte_row_width_ub,
|
unsigned int *dpte_row_height,
|
unsigned int *MetaRequestWidth,
|
unsigned int *MetaRequestHeight,
|
unsigned int *meta_row_width,
|
unsigned int *meta_row_height,
|
unsigned int *vm_group_bytes,
|
unsigned int *dpte_group_bytes,
|
unsigned int *PixelPTEReqWidth,
|
unsigned int *PixelPTEReqHeight,
|
unsigned int *PTERequestSize,
|
unsigned int *DPDE0BytesFrame,
|
unsigned int *MetaPTEBytesFrame);
|
static double CalculateTWait(
|
unsigned int PrefetchMode,
|
double DRAMClockChangeLatency,
|
double UrgentLatency,
|
double SREnterPlusExitTime);
|
static void CalculateRowBandwidth(
|
bool GPUVMEnable,
|
enum source_format_class SourcePixelFormat,
|
double VRatio,
|
double VRatioChroma,
|
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 HostVMMaxNonCachedPageTableLevels,
|
bool GPUVMEnable,
|
double HostVMMinPageSize,
|
double PDEAndMetaPTEBytesPerFrame,
|
double MetaRowBytes,
|
double DPTEBytesPerRow,
|
double BandwidthAvailableForImmediateFlip,
|
unsigned int TotImmediateFlipBytes,
|
enum source_format_class SourcePixelFormat,
|
double LineTime,
|
double VRatio,
|
double VRatioChroma,
|
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 WritebackVTaps,
|
long WritebackDestinationWidth,
|
long WritebackDestinationHeight,
|
long WritebackSourceHeight,
|
unsigned int HTotal);
|
static void CalculateDynamicMetadataParameters(
|
int MaxInterDCNTileRepeaters,
|
double DPPCLK,
|
double DISPCLK,
|
double DCFClkDeepSleep,
|
double PixelClock,
|
long HTotal,
|
long VBlank,
|
long DynamicMetadataTransmittedBytes,
|
long DynamicMetadataLinesBeforeActiveRequired,
|
int InterlaceEnable,
|
bool ProgressiveToInterlaceUnitInOPP,
|
double *Tsetup,
|
double *Tdmbf,
|
double *Tdmec,
|
double *Tdmsks);
|
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 WritebackInterfaceBufferSize,
|
double DCFCLK,
|
double ReturnBW,
|
bool GPUVMEnable,
|
unsigned int dpte_group_bytes[],
|
unsigned int MetaChunkSize,
|
double UrgentLatency,
|
double ExtraLatency,
|
double WritebackLatency,
|
double WritebackChunkSize,
|
double SOCCLK,
|
double DRAMClockChangeLatency,
|
double SRExitTime,
|
double SREnterPlusExitTime,
|
double DCFCLKDeepSleep,
|
unsigned int DPPPerPlane[],
|
bool DCCEnable[],
|
double DPPCLK[],
|
double DETBufferSizeY[],
|
double DETBufferSizeC[],
|
unsigned int SwathHeightY[],
|
unsigned int SwathHeightC[],
|
unsigned int LBBitPerPixel[],
|
double SwathWidthY[],
|
double SwathWidthC[],
|
double HRatio[],
|
double HRatioChroma[],
|
unsigned int vtaps[],
|
unsigned int VTAPsChroma[],
|
double VRatio[],
|
double VRatioChroma[],
|
unsigned int HTotal[],
|
double PixelClock[],
|
unsigned int BlendingAndTiming[],
|
double BytePerPixelDETY[],
|
double BytePerPixelDETC[],
|
double DSTXAfterScaler[],
|
double DSTYAfterScaler[],
|
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,
|
int BytePerPixelY[],
|
int BytePerPixelC[],
|
double VRatio[],
|
double VRatioChroma[],
|
double SwathWidthY[],
|
double SwathWidthC[],
|
unsigned int DPPPerPlane[],
|
double HRatio[],
|
double HRatioChroma[],
|
double PixelClock[],
|
double PSCL_THROUGHPUT[],
|
double PSCL_THROUGHPUT_CHROMA[],
|
double DPPCLK[],
|
double ReadBandwidthLuma[],
|
double ReadBandwidthChroma[],
|
int ReturnBusWidth,
|
double *DCFCLKDeepSleep);
|
static void CalculateUrgentBurstFactor(
|
long swath_width_luma_ub,
|
long swath_width_chroma_ub,
|
unsigned int DETBufferSizeInKByte,
|
unsigned int SwathHeightY,
|
unsigned int SwathHeightC,
|
double LineTime,
|
double UrgentLatency,
|
double CursorBufferSize,
|
unsigned int CursorWidth,
|
unsigned int CursorBPP,
|
double VRatio,
|
double VRatioC,
|
double BytePerPixelInDETY,
|
double BytePerPixelInDETC,
|
double DETBufferSizeY,
|
double DETBufferSizeC,
|
double *UrgentBurstFactorCursor,
|
double *UrgentBurstFactorLuma,
|
double *UrgentBurstFactorChroma,
|
bool *NotEnoughUrgentLatencyHiding);
|
|
static void UseMinimumDCFCLK(
|
struct display_mode_lib *mode_lib,
|
int MaxInterDCNTileRepeaters,
|
int MaxPrefetchMode,
|
double FinalDRAMClockChangeLatency,
|
double SREnterPlusExitTime,
|
int ReturnBusWidth,
|
int RoundTripPingLatencyCycles,
|
int ReorderingBytes,
|
int PixelChunkSizeInKByte,
|
int MetaChunkSize,
|
bool GPUVMEnable,
|
int GPUVMMaxPageTableLevels,
|
bool HostVMEnable,
|
int NumberOfActivePlanes,
|
double HostVMMinPageSize,
|
int HostVMMaxNonCachedPageTableLevels,
|
bool DynamicMetadataVMEnabled,
|
enum immediate_flip_requirement ImmediateFlipRequirement,
|
bool ProgressiveToInterlaceUnitInOPP,
|
double MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly,
|
int VTotal[],
|
int VActive[],
|
int DynamicMetadataTransmittedBytes[],
|
int DynamicMetadataLinesBeforeActiveRequired[],
|
bool Interlace[],
|
double RequiredDPPCLK[][2][DC__NUM_DPP__MAX],
|
double RequiredDISPCLK[][2],
|
double UrgLatency[],
|
unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX],
|
double ProjectedDCFCLKDeepSleep[][2],
|
double MaximumVStartup[][2][DC__NUM_DPP__MAX],
|
double TotalVActivePixelBandwidth[][2],
|
double TotalVActiveCursorBandwidth[][2],
|
double TotalMetaRowBandwidth[][2],
|
double TotalDPTERowBandwidth[][2],
|
unsigned int TotalNumberOfActiveDPP[][2],
|
unsigned int TotalNumberOfDCCActiveDPP[][2],
|
int dpte_group_bytes[],
|
double PrefetchLinesY[][2][DC__NUM_DPP__MAX],
|
double PrefetchLinesC[][2][DC__NUM_DPP__MAX],
|
int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX],
|
int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX],
|
int BytePerPixelY[],
|
int BytePerPixelC[],
|
int HTotal[],
|
double PixelClock[],
|
double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX],
|
double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX],
|
double MetaRowBytes[][2][DC__NUM_DPP__MAX],
|
bool DynamicMetadataEnable[],
|
double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX],
|
double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX],
|
double ReadBandwidthLuma[],
|
double ReadBandwidthChroma[],
|
double DCFCLKPerState[],
|
double DCFCLKState[][2]);
|
static void CalculatePixelDeliveryTimes(
|
unsigned int NumberOfActivePlanes,
|
double VRatio[],
|
double VRatioChroma[],
|
double VRatioPrefetchY[],
|
double VRatioPrefetchC[],
|
unsigned int swath_width_luma_ub[],
|
unsigned int swath_width_chroma_ub[],
|
unsigned int DPPPerPlane[],
|
double HRatio[],
|
double HRatioChroma[],
|
double PixelClock[],
|
double PSCL_THROUGHPUT[],
|
double PSCL_THROUGHPUT_CHROMA[],
|
double DPPCLK[],
|
int BytePerPixelC[],
|
enum scan_direction_class SourceScan[],
|
unsigned int NumberOfCursors[],
|
unsigned int CursorWidth[][2],
|
unsigned int CursorBPP[][2],
|
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 CursorRequestDeliveryTime[],
|
double CursorRequestDeliveryTimePrefetch[]);
|
|
static void CalculateMetaAndPTETimes(
|
int NumberOfActivePlanes,
|
bool GPUVMEnable,
|
int MetaChunkSize,
|
int MinMetaChunkSizeBytes,
|
int HTotal[],
|
double VRatio[],
|
double VRatioChroma[],
|
double DestinationLinesToRequestRowInVBlank[],
|
double DestinationLinesToRequestRowInImmediateFlip[],
|
bool DCCEnable[],
|
double PixelClock[],
|
int BytePerPixelY[],
|
int BytePerPixelC[],
|
enum scan_direction_class SourceScan[],
|
int dpte_row_height[],
|
int dpte_row_height_chroma[],
|
int meta_row_width[],
|
int meta_row_width_chroma[],
|
int meta_row_height[],
|
int meta_row_height_chroma[],
|
int meta_req_width[],
|
int meta_req_width_chroma[],
|
int meta_req_height[],
|
int meta_req_height_chroma[],
|
int dpte_group_bytes[],
|
int PTERequestSizeY[],
|
int PTERequestSizeC[],
|
int PixelPTEReqWidthY[],
|
int PixelPTEReqHeightY[],
|
int PixelPTEReqWidthC[],
|
int PixelPTEReqHeightC[],
|
int dpte_row_width_luma_ub[],
|
int dpte_row_width_chroma_ub[],
|
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 DST_Y_PER_META_ROW_NOM_C[],
|
double TimePerMetaChunkNominal[],
|
double TimePerChromaMetaChunkNominal[],
|
double TimePerMetaChunkVBlank[],
|
double TimePerChromaMetaChunkVBlank[],
|
double TimePerMetaChunkFlip[],
|
double TimePerChromaMetaChunkFlip[],
|
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[]);
|
|
static void CalculateVMGroupAndRequestTimes(
|
unsigned int NumberOfActivePlanes,
|
bool GPUVMEnable,
|
unsigned int GPUVMMaxPageTableLevels,
|
unsigned int HTotal[],
|
int BytePerPixelC[],
|
double DestinationLinesToRequestVMInVBlank[],
|
double DestinationLinesToRequestVMInImmediateFlip[],
|
bool DCCEnable[],
|
double PixelClock[],
|
int dpte_row_width_luma_ub[],
|
int dpte_row_width_chroma_ub[],
|
int vm_group_bytes[],
|
unsigned int dpde0_bytes_per_frame_ub_l[],
|
unsigned int dpde0_bytes_per_frame_ub_c[],
|
int meta_pte_bytes_per_frame_ub_l[],
|
int meta_pte_bytes_per_frame_ub_c[],
|
double TimePerVMGroupVBlank[],
|
double TimePerVMGroupFlip[],
|
double TimePerVMRequestVBlank[],
|
double TimePerVMRequestFlip[]);
|
|
static void CalculateStutterEfficiency(
|
int NumberOfActivePlanes,
|
long ROBBufferSizeInKByte,
|
double TotalDataReadBandwidth,
|
double DCFCLK,
|
double ReturnBW,
|
double SRExitTime,
|
bool SynchronizedVBlank,
|
int DPPPerPlane[],
|
double DETBufferSizeY[],
|
int BytePerPixelY[],
|
double BytePerPixelDETY[],
|
double SwathWidthY[],
|
int SwathHeightY[],
|
int SwathHeightC[],
|
double DCCRateLuma[],
|
double DCCRateChroma[],
|
int HTotal[],
|
int VTotal[],
|
double PixelClock[],
|
double VRatio[],
|
enum scan_direction_class SourceScan[],
|
int BlockHeight256BytesY[],
|
int BlockWidth256BytesY[],
|
int BlockHeight256BytesC[],
|
int BlockWidth256BytesC[],
|
int DCCYMaxUncompressedBlock[],
|
int DCCCMaxUncompressedBlock[],
|
int VActive[],
|
bool DCCEnable[],
|
bool WritebackEnable[],
|
double ReadBandwidthPlaneLuma[],
|
double ReadBandwidthPlaneChroma[],
|
double meta_row_bw[],
|
double dpte_row_bw[],
|
double *StutterEfficiencyNotIncludingVBlank,
|
double *StutterEfficiency,
|
double *StutterPeriodOut);
|
|
static void CalculateSwathAndDETConfiguration(
|
bool ForceSingleDPP,
|
int NumberOfActivePlanes,
|
long DETBufferSizeInKByte,
|
double MaximumSwathWidthLuma[],
|
double MaximumSwathWidthChroma[],
|
enum scan_direction_class SourceScan[],
|
enum source_format_class SourcePixelFormat[],
|
enum dm_swizzle_mode SurfaceTiling[],
|
int ViewportWidth[],
|
int ViewportHeight[],
|
int SurfaceWidthY[],
|
int SurfaceWidthC[],
|
int SurfaceHeightY[],
|
int SurfaceHeightC[],
|
int Read256BytesBlockHeightY[],
|
int Read256BytesBlockHeightC[],
|
int Read256BytesBlockWidthY[],
|
int Read256BytesBlockWidthC[],
|
enum odm_combine_mode ODMCombineEnabled[],
|
int BlendingAndTiming[],
|
int BytePerPixY[],
|
int BytePerPixC[],
|
double BytePerPixDETY[],
|
double BytePerPixDETC[],
|
int HActive[],
|
double HRatio[],
|
double HRatioChroma[],
|
int DPPPerPlane[],
|
int swath_width_luma_ub[],
|
int swath_width_chroma_ub[],
|
double SwathWidth[],
|
double SwathWidthChroma[],
|
int SwathHeightY[],
|
int SwathHeightC[],
|
double DETBufferSizeY[],
|
double DETBufferSizeC[],
|
bool ViewportSizeSupportPerPlane[],
|
bool *ViewportSizeSupport);
|
static void CalculateSwathWidth(
|
bool ForceSingleDPP,
|
int NumberOfActivePlanes,
|
enum source_format_class SourcePixelFormat[],
|
enum scan_direction_class SourceScan[],
|
unsigned int ViewportWidth[],
|
unsigned int ViewportHeight[],
|
unsigned int SurfaceWidthY[],
|
unsigned int SurfaceWidthC[],
|
unsigned int SurfaceHeightY[],
|
unsigned int SurfaceHeightC[],
|
enum odm_combine_mode ODMCombineEnabled[],
|
int BytePerPixY[],
|
int BytePerPixC[],
|
int Read256BytesBlockHeightY[],
|
int Read256BytesBlockHeightC[],
|
int Read256BytesBlockWidthY[],
|
int Read256BytesBlockWidthC[],
|
int BlendingAndTiming[],
|
unsigned int HActive[],
|
double HRatio[],
|
int DPPPerPlane[],
|
double SwathWidthSingleDPPY[],
|
double SwathWidthSingleDPPC[],
|
double SwathWidthY[],
|
double SwathWidthC[],
|
int MaximumSwathHeightY[],
|
int MaximumSwathHeightC[],
|
unsigned int swath_width_luma_ub[],
|
unsigned int swath_width_chroma_ub[]);
|
static double CalculateExtraLatency(
|
long RoundTripPingLatencyCycles,
|
long ReorderingBytes,
|
double DCFCLK,
|
int TotalNumberOfActiveDPP,
|
int PixelChunkSizeInKByte,
|
int TotalNumberOfDCCActiveDPP,
|
int MetaChunkSize,
|
double ReturnBW,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
int NumberOfActivePlanes,
|
int NumberOfDPP[],
|
int dpte_group_bytes[],
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
double HostVMMinPageSize,
|
int HostVMMaxNonCachedPageTableLevels);
|
static double CalculateExtraLatencyBytes(
|
long ReorderingBytes,
|
int TotalNumberOfActiveDPP,
|
int PixelChunkSizeInKByte,
|
int TotalNumberOfDCCActiveDPP,
|
int MetaChunkSize,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
int NumberOfActivePlanes,
|
int NumberOfDPP[],
|
int dpte_group_bytes[],
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
double HostVMMinPageSize,
|
int HostVMMaxNonCachedPageTableLevels);
|
static double CalculateUrgentLatency(
|
double UrgentLatencyPixelDataOnly,
|
double UrgentLatencyPixelMixedWithVMData,
|
double UrgentLatencyVMDataOnly,
|
bool DoUrgentLatencyAdjustment,
|
double UrgentLatencyAdjustmentFabricClockComponent,
|
double UrgentLatencyAdjustmentFabricClockReference,
|
double FabricClockSingle);
|
|
static bool CalculateBytePerPixelAnd256BBlockSizes(
|
enum source_format_class SourcePixelFormat,
|
enum dm_swizzle_mode SurfaceTiling,
|
unsigned int *BytePerPixelY,
|
unsigned int *BytePerPixelC,
|
double *BytePerPixelDETY,
|
double *BytePerPixelDETC,
|
unsigned int *BlockHeight256BytesY,
|
unsigned int *BlockHeight256BytesC,
|
unsigned int *BlockWidth256BytesY,
|
unsigned int *BlockWidth256BytesC);
|
|
void dml30_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,
|
enum output_encoder_class Output)
|
{
|
// 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_420)
|
pixelsPerClock = 2;
|
// #all other modes operate at 1 pixel per clock
|
else if (pixelFormat == dm_444)
|
pixelsPerClock = 1;
|
else if (pixelFormat == dm_n422)
|
pixelsPerClock = 2;
|
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_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
|
s = 0;
|
else
|
s = 1;
|
|
//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, enum output_encoder_class Output)
|
{
|
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 DPPCLKDelaySubtotalPlusCNVCFormater,
|
double DPPCLKDelaySCL,
|
double DPPCLKDelaySCLLBOnly,
|
double DPPCLKDelayCNVCCursor,
|
double DISPCLKDelaySubtotal,
|
unsigned int DPP_RECOUT_WIDTH,
|
enum output_format_class OutputFormat,
|
unsigned int MaxInterDCNTileRepeaters,
|
unsigned int VStartup,
|
unsigned int MaxVStartup,
|
unsigned int GPUVMPageTableLevels,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
unsigned int HostVMMaxNonCachedPageTableLevels,
|
double HostVMMinPageSize,
|
bool DynamicMetadataEnable,
|
bool DynamicMetadataVMEnabled,
|
int DynamicMetadataLinesBeforeActiveRequired,
|
unsigned int DynamicMetadataTransmittedBytes,
|
double UrgentLatency,
|
double UrgentExtraLatency,
|
double TCalc,
|
unsigned int PDEAndMetaPTEBytesFrame,
|
unsigned int MetaRowByte,
|
unsigned int PixelPTEBytesPerRow,
|
double PrefetchSourceLinesY,
|
unsigned int SwathWidthY,
|
int BytePerPixelY,
|
double VInitPreFillY,
|
unsigned int MaxNumSwathY,
|
double PrefetchSourceLinesC,
|
unsigned int SwathWidthC,
|
int BytePerPixelC,
|
double VInitPreFillC,
|
unsigned int MaxNumSwathC,
|
long swath_width_luma_ub,
|
long swath_width_chroma_ub,
|
unsigned int SwathHeightY,
|
unsigned int SwathHeightC,
|
double TWait,
|
bool ProgressiveToInterlaceUnitInOPP,
|
double *DSTXAfterScaler,
|
double *DSTYAfterScaler,
|
double *DestinationLinesForPrefetch,
|
double *PrefetchBandwidth,
|
double *DestinationLinesToRequestVMInVBlank,
|
double *DestinationLinesToRequestRowInVBlank,
|
double *VRatioPrefetchY,
|
double *VRatioPrefetchC,
|
double *RequiredPrefetchPixDataBWLuma,
|
double *RequiredPrefetchPixDataBWChroma,
|
bool *NotEnoughTimeForDynamicMetadata,
|
double *Tno_bw,
|
double *prefetch_vmrow_bw,
|
double *Tdmdl_vm,
|
double *Tdmdl,
|
unsigned int *VUpdateOffsetPix,
|
double *VUpdateWidthPix,
|
double *VReadyOffsetPix)
|
{
|
bool MyError = false;
|
unsigned int DPPCycles = 0, DISPCLKCycles = 0;
|
double DSTTotalPixelsAfterScaler = 0;
|
double LineTime = 0, Tsetup = 0;
|
double dst_y_prefetch_equ = 0;
|
double Tsw_oto = 0;
|
double prefetch_bw_oto = 0;
|
double Tvm_oto = 0;
|
double Tr0_oto = 0;
|
double Tvm_oto_lines = 0;
|
double Tr0_oto_lines = 0;
|
double dst_y_prefetch_oto = 0;
|
double TimeForFetchingMetaPTE = 0;
|
double TimeForFetchingRowInVBlank = 0;
|
double LinesToRequestPrefetchPixelData = 0;
|
double HostVMInefficiencyFactor = 0;
|
unsigned int HostVMDynamicLevelsTrips = 0;
|
double trip_to_mem = 0;
|
double Tvm_trips = 0;
|
double Tr0_trips = 0;
|
double Tvm_trips_rounded = 0;
|
double Tr0_trips_rounded = 0;
|
double Lsw_oto = 0;
|
double Tpre_rounded = 0;
|
double prefetch_bw_equ = 0;
|
double Tvm_equ = 0;
|
double Tr0_equ = 0;
|
double Tdmbf = 0;
|
double Tdmec = 0;
|
double Tdmsks = 0;
|
|
if (GPUVMEnable == true && HostVMEnable == true) {
|
HostVMInefficiencyFactor = PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
|
HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
|
} else {
|
HostVMInefficiencyFactor = 1;
|
HostVMDynamicLevelsTrips = 0;
|
}
|
|
CalculateDynamicMetadataParameters(
|
MaxInterDCNTileRepeaters,
|
myPipe->DPPCLK,
|
myPipe->DISPCLK,
|
myPipe->DCFCLKDeepSleep,
|
myPipe->PixelClock,
|
myPipe->HTotal,
|
myPipe->VBlank,
|
DynamicMetadataTransmittedBytes,
|
DynamicMetadataLinesBeforeActiveRequired,
|
myPipe->InterlaceEnable,
|
ProgressiveToInterlaceUnitInOPP,
|
&Tsetup,
|
&Tdmbf,
|
&Tdmec,
|
&Tdmsks);
|
|
LineTime = myPipe->HTotal / myPipe->PixelClock;
|
trip_to_mem = UrgentLatency;
|
Tvm_trips = UrgentExtraLatency + trip_to_mem * (GPUVMPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1);
|
|
if (DynamicMetadataVMEnabled == true && GPUVMEnable == true) {
|
*Tdmdl = TWait + Tvm_trips + trip_to_mem;
|
} else {
|
*Tdmdl = TWait + UrgentExtraLatency;
|
}
|
|
if (DynamicMetadataEnable == true) {
|
if (VStartup * LineTime < Tsetup + *Tdmdl + Tdmbf + Tdmec + Tdmsks) {
|
*NotEnoughTimeForDynamicMetadata = true;
|
} else {
|
*NotEnoughTimeForDynamicMetadata = false;
|
dml_print("DML: Not Enough Time for Dynamic Meta!\n");
|
dml_print("DML: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", Tdmbf);
|
dml_print("DML: Tdmec: %fus - time dio takes to transfer dmd\n", Tdmec);
|
dml_print("DML: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", Tdmsks);
|
dml_print("DML: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", *Tdmdl);
|
}
|
} else {
|
*NotEnoughTimeForDynamicMetadata = false;
|
}
|
|
*Tdmdl_vm = (DynamicMetadataEnable == true && DynamicMetadataVMEnabled == true && GPUVMEnable == true ? TWait + Tvm_trips : 0);
|
|
if (myPipe->ScalerEnabled)
|
DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCL;
|
else
|
DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCLLBOnly;
|
|
DPPCycles = DPPCycles + 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;
|
|
*DSTXAfterScaler = *DSTXAfterScaler + ((myPipe->ODMCombineEnabled)?18:0) + (myPipe->DPPPerPlane - 1) * DPP_RECOUT_WIDTH;
|
|
if (OutputFormat == dm_420 || (myPipe->InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
|
*DSTYAfterScaler = 1;
|
else
|
*DSTYAfterScaler = 0;
|
|
DSTTotalPixelsAfterScaler = *DSTYAfterScaler * myPipe->HTotal + *DSTXAfterScaler;
|
*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / myPipe->HTotal, 1);
|
*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * myPipe->HTotal));
|
|
MyError = false;
|
|
|
Tr0_trips = trip_to_mem * (HostVMDynamicLevelsTrips + 1);
|
Tvm_trips_rounded = dml_ceil(4.0 * Tvm_trips / LineTime, 1) / 4 * LineTime;
|
Tr0_trips_rounded = dml_ceil(4.0 * Tr0_trips / LineTime, 1) / 4 * LineTime;
|
|
if (GPUVMEnable) {
|
if (GPUVMPageTableLevels >= 3) {
|
*Tno_bw = UrgentExtraLatency + trip_to_mem * ((GPUVMPageTableLevels - 2) - 1);
|
} else
|
*Tno_bw = 0;
|
} else if (!myPipe->DCCEnable)
|
*Tno_bw = LineTime;
|
else
|
*Tno_bw = LineTime / 4;
|
|
dst_y_prefetch_equ = VStartup - (Tsetup + dml_max(TWait + TCalc, *Tdmdl)) / LineTime
|
- (*DSTYAfterScaler + *DSTXAfterScaler / myPipe->HTotal);
|
|
Lsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC);
|
Tsw_oto = Lsw_oto * LineTime;
|
|
prefetch_bw_oto = (PrefetchSourceLinesY * swath_width_luma_ub * BytePerPixelY + PrefetchSourceLinesC * swath_width_chroma_ub * BytePerPixelC) / Tsw_oto;
|
|
if (GPUVMEnable == true) {
|
Tvm_oto = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_oto,
|
Tvm_trips,
|
LineTime / 4.0);
|
} else
|
Tvm_oto = LineTime / 4.0;
|
|
if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
|
Tr0_oto = dml_max3(
|
(MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_oto,
|
LineTime - Tvm_oto, LineTime / 4);
|
} else
|
Tr0_oto = (LineTime - Tvm_oto) / 2.0;
|
|
Tvm_oto_lines = dml_ceil(4.0 * Tvm_oto / LineTime, 1) / 4.0;
|
Tr0_oto_lines = dml_ceil(4.0 * Tr0_oto / LineTime, 1) / 4.0;
|
dst_y_prefetch_oto = Tvm_oto_lines + 2 * Tr0_oto_lines + Lsw_oto;
|
|
dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0;
|
Tpre_rounded = dst_y_prefetch_equ * LineTime;
|
|
dml_print("DML: dst_y_prefetch_oto: %f\n", dst_y_prefetch_oto);
|
dml_print("DML: dst_y_prefetch_equ: %f\n", dst_y_prefetch_equ);
|
|
dml_print("DML: LineTime: %f\n", LineTime);
|
dml_print("DML: VStartup: %d\n", VStartup);
|
dml_print("DML: Tvstartup: %fus - time between vstartup and first pixel of active\n", VStartup * LineTime);
|
dml_print("DML: Tsetup: %fus - time from vstartup to vready\n", Tsetup);
|
dml_print("DML: TCalc: %fus - time for calculations in dchub starting at vready\n", TCalc);
|
dml_print("DML: TWait: %fus - time for fabric to become ready max(pstate exit,cstate enter/exit, urgent latency) after TCalc\n", TWait);
|
dml_print("DML: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", Tdmbf);
|
dml_print("DML: Tdmec: %fus - time dio takes to transfer dmd\n", Tdmec);
|
dml_print("DML: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", Tdmsks);
|
dml_print("DML: Tdmdl_vm: %fus - time for vm stages of dmd \n", *Tdmdl_vm);
|
dml_print("DML: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", *Tdmdl);
|
dml_print("DML: dst_x_after_scl: %f pixels - number of pixel clocks pipeline and buffer delay after scaler \n", *DSTXAfterScaler);
|
dml_print("DML: dst_y_after_scl: %d lines - number of lines of pipeline and buffer delay after scaler \n", (int)*DSTYAfterScaler);
|
|
*PrefetchBandwidth = 0;
|
*DestinationLinesToRequestVMInVBlank = 0;
|
*DestinationLinesToRequestRowInVBlank = 0;
|
*VRatioPrefetchY = 0;
|
*VRatioPrefetchC = 0;
|
*RequiredPrefetchPixDataBWLuma = 0;
|
if (dst_y_prefetch_equ > 1) {
|
double PrefetchBandwidth1 = 0;
|
double PrefetchBandwidth2 = 0;
|
double PrefetchBandwidth3 = 0;
|
double PrefetchBandwidth4 = 0;
|
|
if (Tpre_rounded - *Tno_bw > 0)
|
PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte
|
+ 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
|
+ PrefetchSourceLinesY * swath_width_luma_ub * BytePerPixelY
|
+ PrefetchSourceLinesC * swath_width_chroma_ub * BytePerPixelC)
|
/ (Tpre_rounded - *Tno_bw);
|
else
|
PrefetchBandwidth1 = 0;
|
|
if (VStartup == MaxVStartup && (PrefetchBandwidth1 > 4 * prefetch_bw_oto) && (Tpre_rounded - Tsw_oto / 4 - 0.75 * LineTime - *Tno_bw) > 0) {
|
PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor) / (Tpre_rounded - Tsw_oto / 4 - 0.75 * LineTime - *Tno_bw);
|
}
|
|
if (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded > 0)
|
PrefetchBandwidth2 = (PDEAndMetaPTEBytesFrame *
|
HostVMInefficiencyFactor + PrefetchSourceLinesY *
|
swath_width_luma_ub * BytePerPixelY +
|
PrefetchSourceLinesC * swath_width_chroma_ub *
|
BytePerPixelC) /
|
(Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded);
|
else
|
PrefetchBandwidth2 = 0;
|
|
if (Tpre_rounded - Tvm_trips_rounded > 0)
|
PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow *
|
HostVMInefficiencyFactor + PrefetchSourceLinesY *
|
swath_width_luma_ub * BytePerPixelY + PrefetchSourceLinesC *
|
swath_width_chroma_ub * BytePerPixelC) / (Tpre_rounded -
|
Tvm_trips_rounded);
|
else
|
PrefetchBandwidth3 = 0;
|
|
if (VStartup == MaxVStartup && (PrefetchBandwidth3 > 4 * prefetch_bw_oto) && Tpre_rounded - Tsw_oto / 4 - 0.75 * LineTime - Tvm_trips_rounded > 0) {
|
PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor) / (Tpre_rounded - Tsw_oto / 4 - 0.75 * LineTime - Tvm_trips_rounded);
|
}
|
|
if (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded > 0)
|
PrefetchBandwidth4 = (PrefetchSourceLinesY * swath_width_luma_ub * BytePerPixelY + PrefetchSourceLinesC * swath_width_chroma_ub * BytePerPixelC)
|
/ (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded);
|
else
|
PrefetchBandwidth4 = 0;
|
|
{
|
bool Case1OK;
|
bool Case2OK;
|
bool Case3OK;
|
|
if (PrefetchBandwidth1 > 0) {
|
if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth1
|
>= Tvm_trips_rounded && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth1 >= Tr0_trips_rounded) {
|
Case1OK = true;
|
} else {
|
Case1OK = false;
|
}
|
} else {
|
Case1OK = false;
|
}
|
|
if (PrefetchBandwidth2 > 0) {
|
if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth2
|
>= Tvm_trips_rounded && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth2 < Tr0_trips_rounded) {
|
Case2OK = true;
|
} else {
|
Case2OK = false;
|
}
|
} else {
|
Case2OK = false;
|
}
|
|
if (PrefetchBandwidth3 > 0) {
|
if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth3
|
< Tvm_trips_rounded && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth3 >= Tr0_trips_rounded) {
|
Case3OK = true;
|
} else {
|
Case3OK = false;
|
}
|
} else {
|
Case3OK = false;
|
}
|
|
if (Case1OK) {
|
prefetch_bw_equ = PrefetchBandwidth1;
|
} else if (Case2OK) {
|
prefetch_bw_equ = PrefetchBandwidth2;
|
} else if (Case3OK) {
|
prefetch_bw_equ = PrefetchBandwidth3;
|
} else {
|
prefetch_bw_equ = PrefetchBandwidth4;
|
}
|
|
dml_print("DML: prefetch_bw_equ: %f\n", prefetch_bw_equ);
|
|
if (prefetch_bw_equ > 0) {
|
if (GPUVMEnable == true) {
|
Tvm_equ = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_equ, Tvm_trips, LineTime / 4);
|
} else {
|
Tvm_equ = LineTime / 4;
|
}
|
|
if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
|
Tr0_equ = dml_max4(
|
(MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_equ,
|
Tr0_trips,
|
(LineTime - Tvm_equ) / 2,
|
LineTime / 4);
|
} else {
|
Tr0_equ = (LineTime - Tvm_equ) / 2;
|
}
|
} else {
|
Tvm_equ = 0;
|
Tr0_equ = 0;
|
dml_print("DML: prefetch_bw_equ equals 0! %s:%d\n", __FILE__, __LINE__);
|
}
|
}
|
|
if (dst_y_prefetch_oto < dst_y_prefetch_equ) {
|
*DestinationLinesForPrefetch = dst_y_prefetch_oto;
|
TimeForFetchingMetaPTE = Tvm_oto;
|
TimeForFetchingRowInVBlank = Tr0_oto;
|
*PrefetchBandwidth = prefetch_bw_oto;
|
} else {
|
*DestinationLinesForPrefetch = dst_y_prefetch_equ;
|
TimeForFetchingMetaPTE = Tvm_equ;
|
TimeForFetchingRowInVBlank = Tr0_equ;
|
*PrefetchBandwidth = prefetch_bw_equ;
|
}
|
|
*DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
|
|
*DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0;
|
|
|
LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch - *DestinationLinesToRequestVMInVBlank
|
- 2 * *DestinationLinesToRequestRowInVBlank;
|
|
if (LinesToRequestPrefetchPixelData > 0 && prefetch_bw_equ > 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;
|
dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
|
*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;
|
dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
|
*VRatioPrefetchC = 0;
|
}
|
}
|
|
*RequiredPrefetchPixDataBWLuma = (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData * BytePerPixelY * swath_width_luma_ub / LineTime;
|
*RequiredPrefetchPixDataBWChroma = (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData * BytePerPixelC * swath_width_chroma_ub / LineTime;
|
} else {
|
MyError = true;
|
dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
|
dml_print("DML: LinesToRequestPrefetchPixelData: %f, should be > 0\n", LinesToRequestPrefetchPixelData);
|
*VRatioPrefetchY = 0;
|
*VRatioPrefetchC = 0;
|
*RequiredPrefetchPixDataBWLuma = 0;
|
*RequiredPrefetchPixDataBWChroma = 0;
|
}
|
|
dml_print("DML: Tpre: %fus - sum of tim to request meta pte, 2 x data pte + meta data, swaths\n", (double)LinesToRequestPrefetchPixelData * LineTime + 2.0*TimeForFetchingRowInVBlank + TimeForFetchingMetaPTE);
|
dml_print("DML: Tvm: %fus - time to fetch page tables for meta surface\n", TimeForFetchingMetaPTE);
|
dml_print("DML: Tr0: %fus - time to fetch first row of data pagetables and first row of meta data (done in parallel)\n", TimeForFetchingRowInVBlank);
|
dml_print("DML: Tr1: %fus - time to fetch second row of data pagetables and second row of meta data (done in parallel)\n", TimeForFetchingRowInVBlank);
|
dml_print("DML: Tsw: %fus = time to fetch enough pixel data and cursor data to feed the scalers init position and detile\n", (double)LinesToRequestPrefetchPixelData * LineTime);
|
dml_print("DML: To: %fus - time for propagation from scaler to optc\n", (*DSTYAfterScaler + ((*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime);
|
dml_print("DML: Tvstartup - Tsetup - Tcalc - Twait - Tpre - To > 0\n");
|
dml_print("DML: Tslack(pre): %fus - time left over in schedule\n", VStartup * LineTime - TimeForFetchingMetaPTE - 2 * TimeForFetchingRowInVBlank - (*DSTYAfterScaler + ((*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime - TWait - TCalc - Tsetup);
|
dml_print("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %d\n", PixelPTEBytesPerRow);
|
|
} else {
|
MyError = true;
|
dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
|
}
|
|
{
|
double prefetch_vm_bw = 0;
|
double prefetch_row_bw = 0;
|
|
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;
|
dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
|
}
|
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;
|
dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
|
}
|
|
*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.0 / Clock, 1);
|
}
|
|
static void CalculateDCCConfiguration(
|
bool DCCEnabled,
|
bool DCCProgrammingAssumesScanDirectionUnknown,
|
enum source_format_class SourcePixelFormat,
|
unsigned int SurfaceWidthLuma,
|
unsigned int SurfaceWidthChroma,
|
unsigned int SurfaceHeightLuma,
|
unsigned int SurfaceHeightChroma,
|
double DETBufferSize,
|
unsigned int RequestHeight256ByteLuma,
|
unsigned int RequestHeight256ByteChroma,
|
enum dm_swizzle_mode TilingFormat,
|
unsigned int BytePerPixelY,
|
unsigned int BytePerPixelC,
|
double BytePerPixelDETY,
|
double BytePerPixelDETC,
|
enum scan_direction_class ScanOrientation,
|
unsigned int *MaxUncompressedBlockLuma,
|
unsigned int *MaxUncompressedBlockChroma,
|
unsigned int *MaxCompressedBlockLuma,
|
unsigned int *MaxCompressedBlockChroma,
|
unsigned int *IndependentBlockLuma,
|
unsigned int *IndependentBlockChroma)
|
{
|
int yuv420 = 0;
|
int horz_div_l = 0;
|
int horz_div_c = 0;
|
int vert_div_l = 0;
|
int vert_div_c = 0;
|
|
int req128_horz_wc_l = 0;
|
int req128_horz_wc_c = 0;
|
int req128_vert_wc_l = 0;
|
int req128_vert_wc_c = 0;
|
int segment_order_horz_contiguous_luma = 0;
|
int segment_order_horz_contiguous_chroma = 0;
|
int segment_order_vert_contiguous_luma = 0;
|
int segment_order_vert_contiguous_chroma = 0;
|
|
long full_swath_bytes_horz_wc_l = 0;
|
long full_swath_bytes_horz_wc_c = 0;
|
long full_swath_bytes_vert_wc_l = 0;
|
long full_swath_bytes_vert_wc_c = 0;
|
|
long swath_buf_size = 0;
|
double detile_buf_vp_horz_limit = 0;
|
double detile_buf_vp_vert_limit = 0;
|
|
long MAS_vp_horz_limit = 0;
|
long MAS_vp_vert_limit = 0;
|
long max_vp_horz_width = 0;
|
long max_vp_vert_height = 0;
|
long eff_surf_width_l = 0;
|
long eff_surf_width_c = 0;
|
long eff_surf_height_l = 0;
|
long eff_surf_height_c = 0;
|
|
typedef enum {
|
REQ_256Bytes,
|
REQ_128BytesNonContiguous,
|
REQ_128BytesContiguous,
|
REQ_NA
|
} RequestType;
|
|
RequestType RequestLuma;
|
RequestType RequestChroma;
|
|
yuv420 = ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12) ? 1 : 0);
|
horz_div_l = 1;
|
horz_div_c = 1;
|
vert_div_l = 1;
|
vert_div_c = 1;
|
|
if (BytePerPixelY == 1)
|
vert_div_l = 0;
|
if (BytePerPixelC == 1)
|
vert_div_c = 0;
|
if (BytePerPixelY == 8
|
&& (TilingFormat == dm_sw_64kb_s || TilingFormat == dm_sw_64kb_s_t
|
|| TilingFormat == dm_sw_64kb_s_x))
|
horz_div_l = 0;
|
if (BytePerPixelC == 8
|
&& (TilingFormat == dm_sw_64kb_s || TilingFormat == dm_sw_64kb_s_t
|
|| TilingFormat == dm_sw_64kb_s_x))
|
horz_div_c = 0;
|
|
if (BytePerPixelC == 0) {
|
swath_buf_size = DETBufferSize / 2 - 2 * 256;
|
detile_buf_vp_horz_limit = (double) swath_buf_size
|
/ ((double) RequestHeight256ByteLuma * BytePerPixelY
|
/ (1 + horz_div_l));
|
detile_buf_vp_vert_limit = (double) swath_buf_size
|
/ (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l));
|
} else {
|
swath_buf_size = DETBufferSize / 2 - 2 * 2 * 256;
|
detile_buf_vp_horz_limit = (double) swath_buf_size
|
/ ((double) RequestHeight256ByteLuma * BytePerPixelY
|
/ (1 + horz_div_l)
|
+ (double) RequestHeight256ByteChroma
|
* BytePerPixelC / (1 + horz_div_c)
|
/ (1 + yuv420));
|
detile_buf_vp_vert_limit = (double) swath_buf_size
|
/ (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l)
|
+ 256.0 / RequestHeight256ByteChroma
|
/ (1 + vert_div_c) / (1 + yuv420));
|
}
|
|
if (SourcePixelFormat == dm_420_10) {
|
detile_buf_vp_horz_limit = 1.5 * detile_buf_vp_horz_limit;
|
detile_buf_vp_vert_limit = 1.5 * detile_buf_vp_vert_limit;
|
}
|
|
detile_buf_vp_horz_limit = dml_floor(detile_buf_vp_horz_limit - 1, 16);
|
detile_buf_vp_vert_limit = dml_floor(detile_buf_vp_vert_limit - 1, 16);
|
|
MAS_vp_horz_limit = 5760;
|
MAS_vp_vert_limit = (BytePerPixelC > 0 ? 2880 : 5760);
|
max_vp_horz_width = dml_min((double) MAS_vp_horz_limit, detile_buf_vp_horz_limit);
|
max_vp_vert_height = dml_min((double) MAS_vp_vert_limit, detile_buf_vp_vert_limit);
|
eff_surf_width_l =
|
(SurfaceWidthLuma > max_vp_horz_width ? max_vp_horz_width : SurfaceWidthLuma);
|
eff_surf_width_c = eff_surf_width_l / (1 + yuv420);
|
eff_surf_height_l = (
|
SurfaceHeightLuma > max_vp_vert_height ?
|
max_vp_vert_height : SurfaceHeightLuma);
|
eff_surf_height_c = eff_surf_height_l / (1 + yuv420);
|
|
full_swath_bytes_horz_wc_l = eff_surf_width_l * RequestHeight256ByteLuma * BytePerPixelY;
|
full_swath_bytes_vert_wc_l = eff_surf_height_l * 256 / RequestHeight256ByteLuma;
|
if (BytePerPixelC > 0) {
|
full_swath_bytes_horz_wc_c = eff_surf_width_c * RequestHeight256ByteChroma
|
* BytePerPixelC;
|
full_swath_bytes_vert_wc_c = eff_surf_height_c * 256 / RequestHeight256ByteChroma;
|
} else {
|
full_swath_bytes_horz_wc_c = 0;
|
full_swath_bytes_vert_wc_c = 0;
|
}
|
|
if (SourcePixelFormat == dm_420_10) {
|
full_swath_bytes_horz_wc_l = dml_ceil(full_swath_bytes_horz_wc_l * 2 / 3, 256);
|
full_swath_bytes_horz_wc_c = dml_ceil(full_swath_bytes_horz_wc_c * 2 / 3, 256);
|
full_swath_bytes_vert_wc_l = dml_ceil(full_swath_bytes_vert_wc_l * 2 / 3, 256);
|
full_swath_bytes_vert_wc_c = dml_ceil(full_swath_bytes_vert_wc_c * 2 / 3, 256);
|
}
|
|
if (2 * full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSize) {
|
req128_horz_wc_l = 0;
|
req128_horz_wc_c = 0;
|
} else if (full_swath_bytes_horz_wc_l < 1.5 * full_swath_bytes_horz_wc_c
|
&& 2 * full_swath_bytes_horz_wc_l + full_swath_bytes_horz_wc_c
|
<= DETBufferSize) {
|
req128_horz_wc_l = 0;
|
req128_horz_wc_c = 1;
|
} else if (full_swath_bytes_horz_wc_l >= 1.5 * full_swath_bytes_horz_wc_c
|
&& full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c
|
<= DETBufferSize) {
|
req128_horz_wc_l = 1;
|
req128_horz_wc_c = 0;
|
} else {
|
req128_horz_wc_l = 1;
|
req128_horz_wc_c = 1;
|
}
|
|
if (2 * full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSize) {
|
req128_vert_wc_l = 0;
|
req128_vert_wc_c = 0;
|
} else if (full_swath_bytes_vert_wc_l < 1.5 * full_swath_bytes_vert_wc_c
|
&& 2 * full_swath_bytes_vert_wc_l + full_swath_bytes_vert_wc_c
|
<= DETBufferSize) {
|
req128_vert_wc_l = 0;
|
req128_vert_wc_c = 1;
|
} else if (full_swath_bytes_vert_wc_l >= 1.5 * full_swath_bytes_vert_wc_c
|
&& full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c
|
<= DETBufferSize) {
|
req128_vert_wc_l = 1;
|
req128_vert_wc_c = 0;
|
} else {
|
req128_vert_wc_l = 1;
|
req128_vert_wc_c = 1;
|
}
|
|
if (BytePerPixelY == 2 || (BytePerPixelY == 4 && TilingFormat != dm_sw_64kb_r_x)) {
|
segment_order_horz_contiguous_luma = 0;
|
} else {
|
segment_order_horz_contiguous_luma = 1;
|
}
|
if ((BytePerPixelY == 8
|
&& (TilingFormat == dm_sw_64kb_d || TilingFormat == dm_sw_64kb_d_x
|
|| TilingFormat == dm_sw_64kb_d_t
|
|| TilingFormat == dm_sw_64kb_r_x))
|
|| (BytePerPixelY == 4 && TilingFormat == dm_sw_64kb_r_x)) {
|
segment_order_vert_contiguous_luma = 0;
|
} else {
|
segment_order_vert_contiguous_luma = 1;
|
}
|
if (BytePerPixelC == 2 || (BytePerPixelC == 4 && TilingFormat != dm_sw_64kb_r_x)) {
|
segment_order_horz_contiguous_chroma = 0;
|
} else {
|
segment_order_horz_contiguous_chroma = 1;
|
}
|
if ((BytePerPixelC == 8
|
&& (TilingFormat == dm_sw_64kb_d || TilingFormat == dm_sw_64kb_d_x
|
|| TilingFormat == dm_sw_64kb_d_t
|
|| TilingFormat == dm_sw_64kb_r_x))
|
|| (BytePerPixelC == 4 && TilingFormat == dm_sw_64kb_r_x)) {
|
segment_order_vert_contiguous_chroma = 0;
|
} else {
|
segment_order_vert_contiguous_chroma = 1;
|
}
|
|
if (DCCProgrammingAssumesScanDirectionUnknown == true) {
|
if (req128_horz_wc_l == 0 && req128_vert_wc_l == 0) {
|
RequestLuma = REQ_256Bytes;
|
} else if ((req128_horz_wc_l == 1 && segment_order_horz_contiguous_luma == 0)
|
|| (req128_vert_wc_l == 1 && segment_order_vert_contiguous_luma == 0)) {
|
RequestLuma = REQ_128BytesNonContiguous;
|
} else {
|
RequestLuma = REQ_128BytesContiguous;
|
}
|
if (req128_horz_wc_c == 0 && req128_vert_wc_c == 0) {
|
RequestChroma = REQ_256Bytes;
|
} else if ((req128_horz_wc_c == 1 && segment_order_horz_contiguous_chroma == 0)
|
|| (req128_vert_wc_c == 1
|
&& segment_order_vert_contiguous_chroma == 0)) {
|
RequestChroma = REQ_128BytesNonContiguous;
|
} else {
|
RequestChroma = REQ_128BytesContiguous;
|
}
|
} else if (ScanOrientation != dm_vert) {
|
if (req128_horz_wc_l == 0) {
|
RequestLuma = REQ_256Bytes;
|
} else if (segment_order_horz_contiguous_luma == 0) {
|
RequestLuma = REQ_128BytesNonContiguous;
|
} else {
|
RequestLuma = REQ_128BytesContiguous;
|
}
|
if (req128_horz_wc_c == 0) {
|
RequestChroma = REQ_256Bytes;
|
} else if (segment_order_horz_contiguous_chroma == 0) {
|
RequestChroma = REQ_128BytesNonContiguous;
|
} else {
|
RequestChroma = REQ_128BytesContiguous;
|
}
|
} else {
|
if (req128_vert_wc_l == 0) {
|
RequestLuma = REQ_256Bytes;
|
} else if (segment_order_vert_contiguous_luma == 0) {
|
RequestLuma = REQ_128BytesNonContiguous;
|
} else {
|
RequestLuma = REQ_128BytesContiguous;
|
}
|
if (req128_vert_wc_c == 0) {
|
RequestChroma = REQ_256Bytes;
|
} else if (segment_order_vert_contiguous_chroma == 0) {
|
RequestChroma = REQ_128BytesNonContiguous;
|
} else {
|
RequestChroma = REQ_128BytesContiguous;
|
}
|
}
|
|
if (RequestLuma == REQ_256Bytes) {
|
*MaxUncompressedBlockLuma = 256;
|
*MaxCompressedBlockLuma = 256;
|
*IndependentBlockLuma = 0;
|
} else if (RequestLuma == REQ_128BytesContiguous) {
|
*MaxUncompressedBlockLuma = 256;
|
*MaxCompressedBlockLuma = 128;
|
*IndependentBlockLuma = 128;
|
} else {
|
*MaxUncompressedBlockLuma = 256;
|
*MaxCompressedBlockLuma = 64;
|
*IndependentBlockLuma = 64;
|
}
|
|
if (RequestChroma == REQ_256Bytes) {
|
*MaxUncompressedBlockChroma = 256;
|
*MaxCompressedBlockChroma = 256;
|
*IndependentBlockChroma = 0;
|
} else if (RequestChroma == REQ_128BytesContiguous) {
|
*MaxUncompressedBlockChroma = 256;
|
*MaxCompressedBlockChroma = 128;
|
*IndependentBlockChroma = 128;
|
} else {
|
*MaxUncompressedBlockChroma = 256;
|
*MaxCompressedBlockChroma = 64;
|
*IndependentBlockChroma = 64;
|
}
|
|
if (DCCEnabled != true || BytePerPixelC == 0) {
|
*MaxUncompressedBlockChroma = 0;
|
*MaxCompressedBlockChroma = 0;
|
*IndependentBlockChroma = 0;
|
}
|
|
if (DCCEnabled != true) {
|
*MaxUncompressedBlockLuma = 0;
|
*MaxCompressedBlockLuma = 0;
|
*IndependentBlockLuma = 0;
|
}
|
}
|
|
|
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 = 0;
|
|
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 SwathWidth,
|
unsigned int ViewportHeight,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
unsigned int HostVMMaxNonCachedPageTableLevels,
|
unsigned int GPUVMMinPageSize,
|
unsigned int HostVMMinPageSize,
|
unsigned int PTEBufferSizeInRequests,
|
unsigned int Pitch,
|
unsigned int DCCMetaPitch,
|
unsigned int *MacroTileWidth,
|
unsigned int *MetaRowByte,
|
unsigned int *PixelPTEBytesPerRow,
|
bool *PTEBufferSizeNotExceeded,
|
unsigned int *dpte_row_width_ub,
|
unsigned int *dpte_row_height,
|
unsigned int *MetaRequestWidth,
|
unsigned int *MetaRequestHeight,
|
unsigned int *meta_row_width,
|
unsigned int *meta_row_height,
|
unsigned int *vm_group_bytes,
|
unsigned int *dpte_group_bytes,
|
unsigned int *PixelPTEReqWidth,
|
unsigned int *PixelPTEReqHeight,
|
unsigned int *PTERequestSize,
|
unsigned int *DPDE0BytesFrame,
|
unsigned int *MetaPTEBytesFrame)
|
{
|
unsigned int MPDEBytesFrame = 0;
|
unsigned int DCCMetaSurfaceBytes = 0;
|
unsigned int MacroTileSizeBytes = 0;
|
unsigned int MacroTileHeight = 0;
|
unsigned int ExtraDPDEBytesFrame = 0;
|
unsigned int PDEAndMetaPTEBytesFrame = 0;
|
unsigned int PixelPTEReqHeightPTEs = 0;
|
unsigned int HostVMDynamicLevels = 0;
|
|
double FractionOfPTEReturnDrop;
|
|
if (GPUVMEnable == true && HostVMEnable == true) {
|
if (HostVMMinPageSize < 2048) {
|
HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
|
} else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) {
|
HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
|
} else {
|
HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
|
}
|
}
|
|
*MetaRequestHeight = 8 * BlockHeight256Bytes;
|
*MetaRequestWidth = 8 * BlockWidth256Bytes;
|
if (ScanDirection != dm_vert) {
|
*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;
|
}
|
DCCMetaSurfaceBytes = DCCMetaPitch * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
|
+ 64 * BlockHeight256Bytes) * BytePerPixel / 256;
|
if (GPUVMEnable == true) {
|
*MetaPTEBytesFrame = (dml_ceil((double) (DCCMetaSurfaceBytes - 4.0 * 1024.0) / (8 * 4.0 * 1024), 1) + 1) * 64;
|
MPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 1);
|
} else {
|
*MetaPTEBytesFrame = 0;
|
MPDEBytesFrame = 0;
|
}
|
|
if (DCCEnable != true) {
|
*MetaPTEBytesFrame = 0;
|
MPDEBytesFrame = 0;
|
*MetaRowByte = 0;
|
}
|
|
if (SurfaceTiling == dm_sw_linear) {
|
MacroTileSizeBytes = 256;
|
MacroTileHeight = BlockHeight256Bytes;
|
} else {
|
MacroTileSizeBytes = 65536;
|
MacroTileHeight = 16 * BlockHeight256Bytes;
|
}
|
*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
|
|
if (GPUVMEnable == true && mode_lib->vba.GPUVMMaxPageTableLevels > 1) {
|
if (ScanDirection != dm_vert) {
|
*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 - 2);
|
} else {
|
*DPDE0BytesFrame = 0;
|
ExtraDPDEBytesFrame = 0;
|
}
|
|
PDEAndMetaPTEBytesFrame = *MetaPTEBytesFrame + MPDEBytesFrame + *DPDE0BytesFrame
|
+ ExtraDPDEBytesFrame;
|
|
if (HostVMEnable == true) {
|
PDEAndMetaPTEBytesFrame = PDEAndMetaPTEBytesFrame * (1 + 8 * HostVMDynamicLevels);
|
}
|
|
if (SurfaceTiling == dm_sw_linear) {
|
PixelPTEReqHeightPTEs = 1;
|
*PixelPTEReqHeight = 1;
|
*PixelPTEReqWidth = 32768.0 / BytePerPixel;
|
*PTERequestSize = 64;
|
FractionOfPTEReturnDrop = 0;
|
} else if (MacroTileSizeBytes == 4096) {
|
PixelPTEReqHeightPTEs = 1;
|
*PixelPTEReqHeight = MacroTileHeight;
|
*PixelPTEReqWidth = 8 * *MacroTileWidth;
|
*PTERequestSize = 64;
|
if (ScanDirection != dm_vert)
|
FractionOfPTEReturnDrop = 0;
|
else
|
FractionOfPTEReturnDrop = 7 / 8;
|
} else if (GPUVMMinPageSize == 4 && 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) {
|
if (PTEBufferSizeInRequests == 0)
|
*dpte_row_height = 1;
|
else
|
*dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
|
*dpte_row_width_ub = (dml_ceil(((double) SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
|
*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
|
} else if (ScanDirection != dm_vert) {
|
*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;
|
}
|
|
if (GPUVMEnable != true) {
|
*PixelPTEBytesPerRow = 0;
|
*PTEBufferSizeNotExceeded = true;
|
}
|
dml_print("DML: vm_bytes = meta_pte_bytes_per_frame (per_pipe) = MetaPTEBytesFrame = : %i\n", *MetaPTEBytesFrame);
|
|
if (HostVMEnable == true) {
|
*PixelPTEBytesPerRow = *PixelPTEBytesPerRow * (1 + 8 * HostVMDynamicLevels);
|
}
|
|
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_vert) {
|
*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 *v = &mode_lib->vba;
|
unsigned int j, k;
|
long ReorderBytes = 0;
|
unsigned int PrefetchMode = v->PrefetchModePerState[v->VoltageLevel][v->maxMpcComb];
|
double MaxTotalRDBandwidth = 0;
|
double MaxTotalRDBandwidthNoUrgentBurst = 0;
|
bool DestinationLineTimesForPrefetchLessThan2 = false;
|
bool VRatioPrefetchMoreThan4 = false;
|
double TWait;
|
|
v->WritebackDISPCLK = 0.0;
|
v->DISPCLKWithRamping = 0;
|
v->DISPCLKWithoutRamping = 0;
|
v->GlobalDPPCLK = 0.0;
|
/* DAL custom code: need to update ReturnBW in case min dcfclk is overriden */
|
v->IdealSDPPortBandwidthPerState[v->VoltageLevel][v->maxMpcComb] = dml_min3(
|
v->ReturnBusWidth * v->DCFCLK,
|
v->DRAMSpeedPerState[v->VoltageLevel] * v->NumberOfChannels * v->DRAMChannelWidth,
|
v->FabricClockPerState[v->VoltageLevel] * v->FabricDatapathToDCNDataReturn);
|
if (v->HostVMEnable != true) {
|
v->ReturnBW = v->IdealSDPPortBandwidthPerState[v->VoltageLevel][v->maxMpcComb] * v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
|
} else {
|
v->ReturnBW = v->IdealSDPPortBandwidthPerState[v->VoltageLevel][v->maxMpcComb] * v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100;
|
}
|
/* End DAL custom code */
|
|
// DISPCLK and DPPCLK Calculation
|
//
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->WritebackEnable[k]) {
|
v->WritebackDISPCLK = dml_max(v->WritebackDISPCLK,
|
dml30_CalculateWriteBackDISPCLK(
|
v->WritebackPixelFormat[k],
|
v->PixelClock[k],
|
v->WritebackHRatio[k],
|
v->WritebackVRatio[k],
|
v->WritebackHTaps[k],
|
v->WritebackVTaps[k],
|
v->WritebackSourceWidth[k],
|
v->WritebackDestinationWidth[k],
|
v->HTotal[k],
|
v->WritebackLineBufferSize));
|
}
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->HRatio[k] > 1) {
|
v->PSCL_THROUGHPUT_LUMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput,
|
v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1));
|
} else {
|
v->PSCL_THROUGHPUT_LUMA[k] = dml_min(
|
v->MaxDCHUBToPSCLThroughput,
|
v->MaxPSCLToLBThroughput);
|
}
|
|
v->DPPCLKUsingSingleDPPLuma = v->PixelClock[k]
|
* dml_max(v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
|
dml_max(v->HRatio[k] * v->VRatio[k] / v->PSCL_THROUGHPUT_LUMA[k], 1.0));
|
|
if ((v->htaps[k] > 6 || v->vtaps[k] > 6)
|
&& v->DPPCLKUsingSingleDPPLuma < 2 * v->PixelClock[k]) {
|
v->DPPCLKUsingSingleDPPLuma = 2 * v->PixelClock[k];
|
}
|
|
if ((v->SourcePixelFormat[k] != dm_420_8
|
&& v->SourcePixelFormat[k] != dm_420_10
|
&& v->SourcePixelFormat[k] != dm_420_12
|
&& v->SourcePixelFormat[k] != dm_rgbe_alpha)) {
|
v->PSCL_THROUGHPUT_CHROMA[k] = 0.0;
|
v->DPPCLKUsingSingleDPP[k] = v->DPPCLKUsingSingleDPPLuma;
|
} else {
|
if (v->HRatioChroma[k] > 1) {
|
v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput,
|
v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
|
} else {
|
v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(
|
v->MaxDCHUBToPSCLThroughput,
|
v->MaxPSCLToLBThroughput);
|
}
|
v->DPPCLKUsingSingleDPPChroma = v->PixelClock[k]
|
* dml_max3(v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
|
v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_THROUGHPUT_CHROMA[k], 1.0);
|
|
if ((v->HTAPsChroma[k] > 6 || v->VTAPsChroma[k] > 6)
|
&& v->DPPCLKUsingSingleDPPChroma
|
< 2 * v->PixelClock[k]) {
|
v->DPPCLKUsingSingleDPPChroma = 2
|
* v->PixelClock[k];
|
}
|
|
v->DPPCLKUsingSingleDPP[k] = dml_max(
|
v->DPPCLKUsingSingleDPPLuma,
|
v->DPPCLKUsingSingleDPPChroma);
|
}
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->BlendingAndTiming[k] != k)
|
continue;
|
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1) {
|
v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping,
|
v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
|
* (1 + v->DISPCLKRampingMargin / 100));
|
v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping,
|
v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
|
} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping,
|
v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
|
* (1 + v->DISPCLKRampingMargin / 100));
|
v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping,
|
v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
|
} else {
|
v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping,
|
v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
|
* (1 + v->DISPCLKRampingMargin / 100));
|
v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping,
|
v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
|
}
|
}
|
|
v->DISPCLKWithRamping = dml_max(
|
v->DISPCLKWithRamping,
|
v->WritebackDISPCLK);
|
v->DISPCLKWithoutRamping = dml_max(
|
v->DISPCLKWithoutRamping,
|
v->WritebackDISPCLK);
|
|
ASSERT(v->DISPCLKDPPCLKVCOSpeed != 0);
|
v->DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
|
v->DISPCLKWithRamping,
|
v->DISPCLKDPPCLKVCOSpeed);
|
v->DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
|
v->DISPCLKWithoutRamping,
|
v->DISPCLKDPPCLKVCOSpeed);
|
v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
|
v->soc.clock_limits[mode_lib->soc.num_states - 1].dispclk_mhz,
|
v->DISPCLKDPPCLKVCOSpeed);
|
if (v->DISPCLKWithoutRampingRoundedToDFSGranularity
|
> v->MaxDispclkRoundedToDFSGranularity) {
|
v->DISPCLK_calculated =
|
v->DISPCLKWithoutRampingRoundedToDFSGranularity;
|
} else if (v->DISPCLKWithRampingRoundedToDFSGranularity
|
> v->MaxDispclkRoundedToDFSGranularity) {
|
v->DISPCLK_calculated = v->MaxDispclkRoundedToDFSGranularity;
|
} else {
|
v->DISPCLK_calculated =
|
v->DISPCLKWithRampingRoundedToDFSGranularity;
|
}
|
v->DISPCLK = v->DISPCLK_calculated;
|
DTRACE(" dispclk_mhz (calculated) = %f", v->DISPCLK_calculated);
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->DPPCLK_calculated[k] = v->DPPCLKUsingSingleDPP[k]
|
/ v->DPPPerPlane[k]
|
* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
|
v->GlobalDPPCLK = dml_max(
|
v->GlobalDPPCLK,
|
v->DPPCLK_calculated[k]);
|
}
|
v->GlobalDPPCLK = RoundToDFSGranularityUp(
|
v->GlobalDPPCLK,
|
v->DISPCLKDPPCLKVCOSpeed);
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->DPPCLK_calculated[k] = v->GlobalDPPCLK / 255
|
* dml_ceil(
|
v->DPPCLK_calculated[k] * 255.0
|
/ v->GlobalDPPCLK,
|
1);
|
DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, v->DPPCLK_calculated[k]);
|
v->DPPCLK[k] = v->DPPCLK_calculated[k];
|
}
|
|
// Urgent and B P-State/DRAM Clock Change Watermark
|
DTRACE(" dcfclk_mhz = %f", v->DCFCLK);
|
DTRACE(" return_bus_bw = %f", v->ReturnBW);
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
CalculateBytePerPixelAnd256BBlockSizes(
|
v->SourcePixelFormat[k],
|
v->SurfaceTiling[k],
|
&v->BytePerPixelY[k],
|
&v->BytePerPixelC[k],
|
&v->BytePerPixelDETY[k],
|
&v->BytePerPixelDETC[k],
|
&v->BlockHeight256BytesY[k],
|
&v->BlockHeight256BytesC[k],
|
&v->BlockWidth256BytesY[k],
|
&v->BlockWidth256BytesC[k]);
|
}
|
|
CalculateSwathWidth(
|
false,
|
v->NumberOfActivePlanes,
|
v->SourcePixelFormat,
|
v->SourceScan,
|
v->ViewportWidth,
|
v->ViewportHeight,
|
v->SurfaceWidthY,
|
v->SurfaceWidthC,
|
v->SurfaceHeightY,
|
v->SurfaceHeightC,
|
v->ODMCombineEnabled,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->BlockHeight256BytesY,
|
v->BlockHeight256BytesC,
|
v->BlockWidth256BytesY,
|
v->BlockWidth256BytesC,
|
v->BlendingAndTiming,
|
v->HActive,
|
v->HRatio,
|
v->DPPPerPlane,
|
v->SwathWidthSingleDPPY,
|
v->SwathWidthSingleDPPC,
|
v->SwathWidthY,
|
v->SwathWidthC,
|
v->dummyinteger3,
|
v->dummyinteger4,
|
v->swath_width_luma_ub,
|
v->swath_width_chroma_ub);
|
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->ReadBandwidthPlaneLuma[k] = v->SwathWidthSingleDPPY[k] * v->BytePerPixelY[k] / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
|
v->ReadBandwidthPlaneChroma[k] = v->SwathWidthSingleDPPC[k] * v->BytePerPixelC[k] / (v->HTotal[k] / v->PixelClock[k]) * v->VRatioChroma[k];
|
DTRACE("read_bw[%i] = %fBps", k, v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
|
}
|
|
|
// DCFCLK Deep Sleep
|
CalculateDCFCLKDeepSleep(
|
mode_lib,
|
v->NumberOfActivePlanes,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->VRatio,
|
v->VRatioChroma,
|
v->SwathWidthY,
|
v->SwathWidthC,
|
v->DPPPerPlane,
|
v->HRatio,
|
v->HRatioChroma,
|
v->PixelClock,
|
v->PSCL_THROUGHPUT_LUMA,
|
v->PSCL_THROUGHPUT_CHROMA,
|
v->DPPCLK,
|
v->ReadBandwidthPlaneLuma,
|
v->ReadBandwidthPlaneChroma,
|
v->ReturnBusWidth,
|
&v->DCFCLKDeepSleep);
|
|
// DSCCLK
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if ((v->BlendingAndTiming[k] != k) || !v->DSCEnabled[k]) {
|
v->DSCCLK_calculated[k] = 0.0;
|
} else {
|
if (v->OutputFormat[k] == dm_420)
|
v->DSCFormatFactor = 2;
|
else if (v->OutputFormat[k] == dm_444)
|
v->DSCFormatFactor = 1;
|
else if (v->OutputFormat[k] == dm_n422)
|
v->DSCFormatFactor = 2;
|
else
|
v->DSCFormatFactor = 1;
|
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
|
v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 12
|
/ v->DSCFormatFactor / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
|
else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 6
|
/ v->DSCFormatFactor / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
|
else
|
v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 3
|
/ v->DSCFormatFactor / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
|
}
|
}
|
|
// DSC Delay
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
double BPP = v->OutputBppPerState[k][v->VoltageLevel];
|
|
if (v->DSCEnabled[k] && BPP != 0) {
|
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_disabled) {
|
v->DSCDelay[k] = dscceComputeDelay(v->DSCInputBitPerComponent[k],
|
BPP,
|
dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
|
v->NumberOfDSCSlices[k],
|
v->OutputFormat[k],
|
v->Output[k])
|
+ dscComputeDelay(v->OutputFormat[k], v->Output[k]);
|
} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
v->DSCDelay[k] = 2 * dscceComputeDelay(v->DSCInputBitPerComponent[k],
|
BPP,
|
dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
|
v->NumberOfDSCSlices[k] / 2.0,
|
v->OutputFormat[k],
|
v->Output[k])
|
+ dscComputeDelay(v->OutputFormat[k], v->Output[k]);
|
} else {
|
v->DSCDelay[k] = 4 * dscceComputeDelay(v->DSCInputBitPerComponent[k],
|
BPP,
|
dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
|
v->NumberOfDSCSlices[k] / 4.0,
|
v->OutputFormat[k],
|
v->Output[k])
|
+ dscComputeDelay(v->OutputFormat[k], v->Output[k]);
|
}
|
v->DSCDelay[k] = v->DSCDelay[k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
|
} else {
|
v->DSCDelay[k] = 0;
|
}
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k)
|
for (j = 0; j < v->NumberOfActivePlanes; ++j) // NumberOfPlanes
|
if (j != k && v->BlendingAndTiming[k] == j
|
&& v->DSCEnabled[j])
|
v->DSCDelay[k] = v->DSCDelay[j];
|
|
// Prefetch
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
unsigned int PDEAndMetaPTEBytesFrameY = 0;
|
unsigned int PixelPTEBytesPerRowY = 0;
|
unsigned int MetaRowByteY = 0;
|
unsigned int MetaRowByteC = 0;
|
unsigned int PDEAndMetaPTEBytesFrameC = 0;
|
unsigned int PixelPTEBytesPerRowC = 0;
|
bool PTEBufferSizeNotExceededY = 0;
|
bool PTEBufferSizeNotExceededC = 0;
|
|
|
if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12 || v->SourcePixelFormat[k] == dm_rgbe_alpha) {
|
if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
|
v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
|
v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
|
} else {
|
v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
|
v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
|
|
}
|
PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(
|
mode_lib,
|
v->DCCEnable[k],
|
v->BlockHeight256BytesC[k],
|
v->BlockWidth256BytesC[k],
|
v->SourcePixelFormat[k],
|
v->SurfaceTiling[k],
|
v->BytePerPixelC[k],
|
v->SourceScan[k],
|
v->SwathWidthC[k],
|
v->ViewportHeightChroma[k],
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->GPUVMMinPageSize,
|
v->HostVMMinPageSize,
|
v->PTEBufferSizeInRequestsForChroma,
|
v->PitchC[k],
|
v->DCCMetaPitchC[k],
|
&v->MacroTileWidthC[k],
|
&MetaRowByteC,
|
&PixelPTEBytesPerRowC,
|
&PTEBufferSizeNotExceededC,
|
&v->dpte_row_width_chroma_ub[k],
|
&v->dpte_row_height_chroma[k],
|
&v->meta_req_width_chroma[k],
|
&v->meta_req_height_chroma[k],
|
&v->meta_row_width_chroma[k],
|
&v->meta_row_height_chroma[k],
|
&v->dummyinteger1,
|
&v->dummyinteger2,
|
&v->PixelPTEReqWidthC[k],
|
&v->PixelPTEReqHeightC[k],
|
&v->PTERequestSizeC[k],
|
&v->dpde0_bytes_per_frame_ub_c[k],
|
&v->meta_pte_bytes_per_frame_ub_c[k]);
|
|
v->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
|
mode_lib,
|
v->VRatioChroma[k],
|
v->VTAPsChroma[k],
|
v->Interlace[k],
|
v->ProgressiveToInterlaceUnitInOPP,
|
v->SwathHeightC[k],
|
v->ViewportYStartC[k],
|
&v->VInitPreFillC[k],
|
&v->MaxNumSwathC[k]);
|
} else {
|
v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
|
v->PTEBufferSizeInRequestsForChroma = 0;
|
PixelPTEBytesPerRowC = 0;
|
PDEAndMetaPTEBytesFrameC = 0;
|
MetaRowByteC = 0;
|
v->MaxNumSwathC[k] = 0;
|
v->PrefetchSourceLinesC[k] = 0;
|
}
|
|
PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
|
mode_lib,
|
v->DCCEnable[k],
|
v->BlockHeight256BytesY[k],
|
v->BlockWidth256BytesY[k],
|
v->SourcePixelFormat[k],
|
v->SurfaceTiling[k],
|
v->BytePerPixelY[k],
|
v->SourceScan[k],
|
v->SwathWidthY[k],
|
v->ViewportHeight[k],
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->GPUVMMinPageSize,
|
v->HostVMMinPageSize,
|
v->PTEBufferSizeInRequestsForLuma,
|
v->PitchY[k],
|
v->DCCMetaPitchY[k],
|
&v->MacroTileWidthY[k],
|
&MetaRowByteY,
|
&PixelPTEBytesPerRowY,
|
&PTEBufferSizeNotExceededY,
|
&v->dpte_row_width_luma_ub[k],
|
&v->dpte_row_height[k],
|
&v->meta_req_width[k],
|
&v->meta_req_height[k],
|
&v->meta_row_width[k],
|
&v->meta_row_height[k],
|
&v->vm_group_bytes[k],
|
&v->dpte_group_bytes[k],
|
&v->PixelPTEReqWidthY[k],
|
&v->PixelPTEReqHeightY[k],
|
&v->PTERequestSizeY[k],
|
&v->dpde0_bytes_per_frame_ub_l[k],
|
&v->meta_pte_bytes_per_frame_ub_l[k]);
|
|
v->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
|
mode_lib,
|
v->VRatio[k],
|
v->vtaps[k],
|
v->Interlace[k],
|
v->ProgressiveToInterlaceUnitInOPP,
|
v->SwathHeightY[k],
|
v->ViewportYStartY[k],
|
&v->VInitPreFillY[k],
|
&v->MaxNumSwathY[k]);
|
v->PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
|
v->PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
|
+ PDEAndMetaPTEBytesFrameC;
|
v->MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
|
|
CalculateRowBandwidth(
|
v->GPUVMEnable,
|
v->SourcePixelFormat[k],
|
v->VRatio[k],
|
v->VRatioChroma[k],
|
v->DCCEnable[k],
|
v->HTotal[k] / v->PixelClock[k],
|
MetaRowByteY,
|
MetaRowByteC,
|
v->meta_row_height[k],
|
v->meta_row_height_chroma[k],
|
PixelPTEBytesPerRowY,
|
PixelPTEBytesPerRowC,
|
v->dpte_row_height[k],
|
v->dpte_row_height_chroma[k],
|
&v->meta_row_bw[k],
|
&v->dpte_row_bw[k]);
|
}
|
|
v->TotalDCCActiveDPP = 0;
|
v->TotalActiveDPP = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->TotalActiveDPP = v->TotalActiveDPP
|
+ v->DPPPerPlane[k];
|
if (v->DCCEnable[k])
|
v->TotalDCCActiveDPP = v->TotalDCCActiveDPP
|
+ v->DPPPerPlane[k];
|
}
|
|
|
ReorderBytes = v->NumberOfChannels * dml_max3(
|
v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
|
v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
|
v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
|
|
v->UrgentExtraLatency = CalculateExtraLatency(
|
v->RoundTripPingLatencyCycles,
|
ReorderBytes,
|
v->DCFCLK,
|
v->TotalActiveDPP,
|
v->PixelChunkSizeInKByte,
|
v->TotalDCCActiveDPP,
|
v->MetaChunkSize,
|
v->ReturnBW,
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->NumberOfActivePlanes,
|
v->DPPPerPlane,
|
v->dpte_group_bytes,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
v->HostVMMinPageSize,
|
v->HostVMMaxNonCachedPageTableLevels);
|
|
v->TCalc = 24.0 / v->DCFCLKDeepSleep;
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->BlendingAndTiming[k] == k) {
|
if (v->WritebackEnable[k] == true) {
|
v->WritebackDelay[v->VoltageLevel][k] = v->WritebackLatency +
|
CalculateWriteBackDelay(v->WritebackPixelFormat[k],
|
v->WritebackHRatio[k],
|
v->WritebackVRatio[k],
|
v->WritebackVTaps[k],
|
v->WritebackDestinationWidth[k],
|
v->WritebackDestinationHeight[k],
|
v->WritebackSourceHeight[k],
|
v->HTotal[k]) / v->DISPCLK;
|
} else
|
v->WritebackDelay[v->VoltageLevel][k] = 0;
|
for (j = 0; j < v->NumberOfActivePlanes; ++j) {
|
if (v->BlendingAndTiming[j] == k
|
&& v->WritebackEnable[j] == true) {
|
v->WritebackDelay[v->VoltageLevel][k] = dml_max(v->WritebackDelay[v->VoltageLevel][k],
|
v->WritebackLatency + CalculateWriteBackDelay(
|
v->WritebackPixelFormat[j],
|
v->WritebackHRatio[j],
|
v->WritebackVRatio[j],
|
v->WritebackVTaps[j],
|
v->WritebackDestinationWidth[j],
|
v->WritebackDestinationHeight[j],
|
v->WritebackSourceHeight[j],
|
v->HTotal[k]) / v->DISPCLK);
|
}
|
}
|
}
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k)
|
for (j = 0; j < v->NumberOfActivePlanes; ++j)
|
if (v->BlendingAndTiming[k] == j)
|
v->WritebackDelay[v->VoltageLevel][k] = v->WritebackDelay[v->VoltageLevel][j];
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->MaxVStartupLines[k] = v->VTotal[k] - v->VActive[k] - dml_max(1.0, dml_ceil((double) v->WritebackDelay[v->VoltageLevel][k] / (v->HTotal[k] / v->PixelClock[k]), 1));
|
}
|
|
v->MaximumMaxVStartupLines = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k)
|
v->MaximumMaxVStartupLines = dml_max(v->MaximumMaxVStartupLines, v->MaxVStartupLines[k]);
|
|
if (v->DRAMClockChangeLatencyOverride > 0.0) {
|
v->FinalDRAMClockChangeLatency = v->DRAMClockChangeLatencyOverride;
|
} else {
|
v->FinalDRAMClockChangeLatency = v->DRAMClockChangeLatency;
|
}
|
v->UrgentLatency = CalculateUrgentLatency(v->UrgentLatencyPixelDataOnly, v->UrgentLatencyPixelMixedWithVMData, v->UrgentLatencyVMDataOnly, v->DoUrgentLatencyAdjustment, v->UrgentLatencyAdjustmentFabricClockComponent, v->UrgentLatencyAdjustmentFabricClockReference, v->FabricClock);
|
|
|
v->FractionOfUrgentBandwidth = 0.0;
|
v->FractionOfUrgentBandwidthImmediateFlip = 0.0;
|
|
v->VStartupLines = 13;
|
|
do {
|
MaxTotalRDBandwidth = 0;
|
MaxTotalRDBandwidthNoUrgentBurst = 0;
|
DestinationLineTimesForPrefetchLessThan2 = false;
|
VRatioPrefetchMoreThan4 = false;
|
TWait = CalculateTWait(
|
PrefetchMode,
|
v->FinalDRAMClockChangeLatency,
|
v->UrgentLatency,
|
v->SREnterPlusExitTime);
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
Pipe myPipe = { 0 };
|
|
myPipe.DPPCLK = v->DPPCLK[k];
|
myPipe.DISPCLK = v->DISPCLK;
|
myPipe.PixelClock = v->PixelClock[k];
|
myPipe.DCFCLKDeepSleep = v->DCFCLKDeepSleep;
|
myPipe.DPPPerPlane = v->DPPPerPlane[k];
|
myPipe.ScalerEnabled = v->ScalerEnabled[k];
|
myPipe.SourceScan = v->SourceScan[k];
|
myPipe.BlockWidth256BytesY = v->BlockWidth256BytesY[k];
|
myPipe.BlockHeight256BytesY = v->BlockHeight256BytesY[k];
|
myPipe.BlockWidth256BytesC = v->BlockWidth256BytesC[k];
|
myPipe.BlockHeight256BytesC = v->BlockHeight256BytesC[k];
|
myPipe.InterlaceEnable = v->Interlace[k];
|
myPipe.NumberOfCursors = v->NumberOfCursors[k];
|
myPipe.VBlank = v->VTotal[k] - v->VActive[k];
|
myPipe.HTotal = v->HTotal[k];
|
myPipe.DCCEnable = v->DCCEnable[k];
|
myPipe.ODMCombineEnabled = !!v->ODMCombineEnabled[k];
|
|
v->ErrorResult[k] = CalculatePrefetchSchedule(
|
mode_lib,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
&myPipe,
|
v->DSCDelay[k],
|
v->DPPCLKDelaySubtotal
|
+ v->DPPCLKDelayCNVCFormater,
|
v->DPPCLKDelaySCL,
|
v->DPPCLKDelaySCLLBOnly,
|
v->DPPCLKDelayCNVCCursor,
|
v->DISPCLKDelaySubtotal,
|
(unsigned int) (v->SwathWidthY[k] / v->HRatio[k]),
|
v->OutputFormat[k],
|
v->MaxInterDCNTileRepeaters,
|
dml_min(v->VStartupLines, v->MaxVStartupLines[k]),
|
v->MaxVStartupLines[k],
|
v->GPUVMMaxPageTableLevels,
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->HostVMMinPageSize,
|
v->DynamicMetadataEnable[k],
|
v->DynamicMetadataVMEnabled,
|
v->DynamicMetadataLinesBeforeActiveRequired[k],
|
v->DynamicMetadataTransmittedBytes[k],
|
v->UrgentLatency,
|
v->UrgentExtraLatency,
|
v->TCalc,
|
v->PDEAndMetaPTEBytesFrame[k],
|
v->MetaRowByte[k],
|
v->PixelPTEBytesPerRow[k],
|
v->PrefetchSourceLinesY[k],
|
v->SwathWidthY[k],
|
v->BytePerPixelY[k],
|
v->VInitPreFillY[k],
|
v->MaxNumSwathY[k],
|
v->PrefetchSourceLinesC[k],
|
v->SwathWidthC[k],
|
v->BytePerPixelC[k],
|
v->VInitPreFillC[k],
|
v->MaxNumSwathC[k],
|
v->swath_width_luma_ub[k],
|
v->swath_width_chroma_ub[k],
|
v->SwathHeightY[k],
|
v->SwathHeightC[k],
|
TWait,
|
v->ProgressiveToInterlaceUnitInOPP,
|
&v->DSTXAfterScaler[k],
|
&v->DSTYAfterScaler[k],
|
&v->DestinationLinesForPrefetch[k],
|
&v->PrefetchBandwidth[k],
|
&v->DestinationLinesToRequestVMInVBlank[k],
|
&v->DestinationLinesToRequestRowInVBlank[k],
|
&v->VRatioPrefetchY[k],
|
&v->VRatioPrefetchC[k],
|
&v->RequiredPrefetchPixDataBWLuma[k],
|
&v->RequiredPrefetchPixDataBWChroma[k],
|
&v->NotEnoughTimeForDynamicMetadata[k],
|
&v->Tno_bw[k],
|
&v->prefetch_vmrow_bw[k],
|
&v->Tdmdl_vm[k],
|
&v->Tdmdl[k],
|
&v->VUpdateOffsetPix[k],
|
&v->VUpdateWidthPix[k],
|
&v->VReadyOffsetPix[k]);
|
if (v->BlendingAndTiming[k] == k) {
|
double TotalRepeaterDelayTime = v->MaxInterDCNTileRepeaters * (2 / v->DPPCLK[k] + 3 / v->DISPCLK);
|
v->VUpdateWidthPix[k] = (14 / v->DCFCLKDeepSleep + 12 / v->DPPCLK[k] + TotalRepeaterDelayTime) * v->PixelClock[k];
|
v->VReadyOffsetPix[k] = dml_max(150.0 / v->DPPCLK[k], TotalRepeaterDelayTime + 20 / v->DCFCLKDeepSleep + 10 / v->DPPCLK[k]) * v->PixelClock[k];
|
v->VUpdateOffsetPix[k] = dml_ceil(v->HTotal[k] / 4.0, 1);
|
v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[k]);
|
} else {
|
int x = v->BlendingAndTiming[k];
|
double TotalRepeaterDelayTime = v->MaxInterDCNTileRepeaters * (2 / v->DPPCLK[k] + 3 / v->DISPCLK);
|
v->VUpdateWidthPix[k] = (14 / v->DCFCLKDeepSleep + 12 / v->DPPCLK[k] + TotalRepeaterDelayTime) * v->PixelClock[x];
|
v->VReadyOffsetPix[k] = dml_max(150.0 / v->DPPCLK[k], TotalRepeaterDelayTime + 20 / v->DCFCLKDeepSleep + 10 / v->DPPCLK[k]) * v->PixelClock[x];
|
v->VUpdateOffsetPix[k] = dml_ceil(v->HTotal[x] / 4.0, 1);
|
if (!v->MaxVStartupLines[x])
|
v->MaxVStartupLines[x] = v->MaxVStartupLines[k];
|
v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[x]);
|
}
|
}
|
|
v->NotEnoughUrgentLatencyHiding = false;
|
v->NotEnoughUrgentLatencyHidingPre = false;
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->cursor_bw[k] = v->NumberOfCursors[k]
|
* v->CursorWidth[k][0] * v->CursorBPP[k][0]
|
/ 8.0
|
/ (v->HTotal[k] / v->PixelClock[k])
|
* v->VRatio[k];
|
v->cursor_bw_pre[k] = v->NumberOfCursors[k]
|
* v->CursorWidth[k][0] * v->CursorBPP[k][0]
|
/ 8.0
|
/ (v->HTotal[k] / v->PixelClock[k])
|
* v->VRatioPrefetchY[k];
|
|
CalculateUrgentBurstFactor(
|
v->swath_width_luma_ub[k],
|
v->swath_width_chroma_ub[k],
|
v->DETBufferSizeInKByte,
|
v->SwathHeightY[k],
|
v->SwathHeightC[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->UrgentLatency,
|
v->CursorBufferSize,
|
v->CursorWidth[k][0],
|
v->CursorBPP[k][0],
|
v->VRatio[k],
|
v->VRatioChroma[k],
|
v->BytePerPixelDETY[k],
|
v->BytePerPixelDETC[k],
|
v->DETBufferSizeY[k],
|
v->DETBufferSizeC[k],
|
&v->UrgentBurstFactorCursor[k],
|
&v->UrgentBurstFactorLuma[k],
|
&v->UrgentBurstFactorChroma[k],
|
&v->NoUrgentLatencyHiding[k]);
|
|
CalculateUrgentBurstFactor(
|
v->swath_width_luma_ub[k],
|
v->swath_width_chroma_ub[k],
|
v->DETBufferSizeInKByte,
|
v->SwathHeightY[k],
|
v->SwathHeightC[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->UrgentLatency,
|
v->CursorBufferSize,
|
v->CursorWidth[k][0],
|
v->CursorBPP[k][0],
|
v->VRatioPrefetchY[k],
|
v->VRatioPrefetchC[k],
|
v->BytePerPixelDETY[k],
|
v->BytePerPixelDETC[k],
|
v->DETBufferSizeY[k],
|
v->DETBufferSizeC[k],
|
&v->UrgentBurstFactorCursorPre[k],
|
&v->UrgentBurstFactorLumaPre[k],
|
&v->UrgentBurstFactorChromaPre[k],
|
&v->NoUrgentLatencyHidingPre[k]);
|
|
MaxTotalRDBandwidth = MaxTotalRDBandwidth +
|
dml_max3(v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
|
v->ReadBandwidthPlaneLuma[k] *
|
v->UrgentBurstFactorLuma[k] +
|
v->ReadBandwidthPlaneChroma[k] *
|
v->UrgentBurstFactorChroma[k] +
|
v->cursor_bw[k] *
|
v->UrgentBurstFactorCursor[k] +
|
v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
|
v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgentBurstFactorLumaPre[k] +
|
v->RequiredPrefetchPixDataBWChroma[k] * v->UrgentBurstFactorChromaPre[k]) + v->cursor_bw_pre[k] *
|
v->UrgentBurstFactorCursorPre[k]);
|
|
MaxTotalRDBandwidthNoUrgentBurst = MaxTotalRDBandwidthNoUrgentBurst +
|
dml_max3(v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
|
v->ReadBandwidthPlaneLuma[k] +
|
v->ReadBandwidthPlaneChroma[k] +
|
v->cursor_bw[k] +
|
v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
|
v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
|
|
if (v->DestinationLinesForPrefetch[k] < 2)
|
DestinationLineTimesForPrefetchLessThan2 = true;
|
if (v->VRatioPrefetchY[k] > 4 || v->VRatioPrefetchC[k] > 4)
|
VRatioPrefetchMoreThan4 = true;
|
if (v->NoUrgentLatencyHiding[k] == true)
|
v->NotEnoughUrgentLatencyHiding = true;
|
|
if (v->NoUrgentLatencyHidingPre[k] == true)
|
v->NotEnoughUrgentLatencyHidingPre = true;
|
}
|
v->FractionOfUrgentBandwidth = MaxTotalRDBandwidthNoUrgentBurst / v->ReturnBW;
|
|
|
if (MaxTotalRDBandwidth <= v->ReturnBW && v->NotEnoughUrgentLatencyHiding == 0 && v->NotEnoughUrgentLatencyHidingPre == 0 && !VRatioPrefetchMoreThan4
|
&& !DestinationLineTimesForPrefetchLessThan2)
|
v->PrefetchModeSupported = true;
|
else {
|
v->PrefetchModeSupported = false;
|
dml_print("DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
|
dml_print("DML: MaxTotalRDBandwidth:%f AvailReturnBandwidth:%f\n", MaxTotalRDBandwidth, v->ReturnBW);
|
dml_print("DML: VRatioPrefetch %s more than 4\n", (VRatioPrefetchMoreThan4) ? "is" : "is not");
|
dml_print("DML: DestinationLines for Prefetch %s less than 2\n", (DestinationLineTimesForPrefetchLessThan2) ? "is" : "is not");
|
}
|
|
if (v->PrefetchModeSupported == true && v->ImmediateFlipSupport == true) {
|
v->BandwidthAvailableForImmediateFlip = v->ReturnBW;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->BandwidthAvailableForImmediateFlip =
|
v->BandwidthAvailableForImmediateFlip
|
- dml_max(
|
v->ReadBandwidthPlaneLuma[k] * v->UrgentBurstFactorLuma[k]
|
+ v->ReadBandwidthPlaneChroma[k] * v->UrgentBurstFactorChroma[k]
|
+ v->cursor_bw[k] * v->UrgentBurstFactorCursor[k],
|
v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgentBurstFactorLumaPre[k] +
|
v->RequiredPrefetchPixDataBWChroma[k] * v->UrgentBurstFactorChromaPre[k]) +
|
v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
|
}
|
|
v->TotImmediateFlipBytes = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->TotImmediateFlipBytes = v->TotImmediateFlipBytes + v->DPPPerPlane[k] * (v->PDEAndMetaPTEBytesFrame[k] + v->MetaRowByte[k] + v->PixelPTEBytesPerRow[k]);
|
}
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
CalculateFlipSchedule(
|
mode_lib,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
v->UrgentExtraLatency,
|
v->UrgentLatency,
|
v->GPUVMMaxPageTableLevels,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->GPUVMEnable,
|
v->HostVMMinPageSize,
|
v->PDEAndMetaPTEBytesFrame[k],
|
v->MetaRowByte[k],
|
v->PixelPTEBytesPerRow[k],
|
v->BandwidthAvailableForImmediateFlip,
|
v->TotImmediateFlipBytes,
|
v->SourcePixelFormat[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->VRatio[k],
|
v->VRatioChroma[k],
|
v->Tno_bw[k],
|
v->DCCEnable[k],
|
v->dpte_row_height[k],
|
v->meta_row_height[k],
|
v->dpte_row_height_chroma[k],
|
v->meta_row_height_chroma[k],
|
&v->DestinationLinesToRequestVMInImmediateFlip[k],
|
&v->DestinationLinesToRequestRowInImmediateFlip[k],
|
&v->final_flip_bw[k],
|
&v->ImmediateFlipSupportedForPipe[k]);
|
}
|
v->total_dcn_read_bw_with_flip = 0.0;
|
v->total_dcn_read_bw_with_flip_no_urgent_burst = 0.0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip + dml_max3(
|
v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
|
v->DPPPerPlane[k] * v->final_flip_bw[k] +
|
v->ReadBandwidthLuma[k] * v->UrgentBurstFactorLuma[k] +
|
v->ReadBandwidthChroma[k] * v->UrgentBurstFactorChroma[k] +
|
v->cursor_bw[k] * v->UrgentBurstFactorCursor[k],
|
v->DPPPerPlane[k] * (v->final_flip_bw[k] +
|
v->RequiredPrefetchPixDataBWLuma[k] * v->UrgentBurstFactorLumaPre[k] +
|
v->RequiredPrefetchPixDataBWChroma[k] * v->UrgentBurstFactorChromaPre[k]) +
|
v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
|
v->total_dcn_read_bw_with_flip_no_urgent_burst =
|
v->total_dcn_read_bw_with_flip_no_urgent_burst +
|
dml_max3(v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
|
v->DPPPerPlane[k] * v->final_flip_bw[k] + v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k],
|
v->DPPPerPlane[k] * (v->final_flip_bw[k] + v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
|
|
}
|
v->FractionOfUrgentBandwidthImmediateFlip = v->total_dcn_read_bw_with_flip_no_urgent_burst / v->ReturnBW;
|
|
v->ImmediateFlipSupported = true;
|
if (v->total_dcn_read_bw_with_flip > v->ReturnBW) {
|
v->ImmediateFlipSupported = false;
|
v->total_dcn_read_bw_with_flip = MaxTotalRDBandwidth;
|
}
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->ImmediateFlipSupportedForPipe[k] == false) {
|
v->ImmediateFlipSupported = false;
|
}
|
}
|
} else {
|
v->ImmediateFlipSupported = false;
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->ErrorResult[k] || v->NotEnoughTimeForDynamicMetadata[k]) {
|
v->PrefetchModeSupported = false;
|
dml_print("DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
|
}
|
}
|
|
v->VStartupLines = v->VStartupLines + 1;
|
v->PrefetchAndImmediateFlipSupported = (v->PrefetchModeSupported == true && ((!v->ImmediateFlipSupport && !v->HostVMEnable && v->ImmediateFlipRequirement != dm_immediate_flip_required) || v->ImmediateFlipSupported)) ? true : false;
|
|
} while (!v->PrefetchModeSupported && v->VStartupLines <= v->MaximumMaxVStartupLines);
|
ASSERT(v->PrefetchModeSupported);
|
|
//Watermarks and NB P-State/DRAM Clock Change Support
|
{
|
enum clock_change_support DRAMClockChangeSupport = 0; // dummy
|
CalculateWatermarksAndDRAMSpeedChangeSupport(
|
mode_lib,
|
PrefetchMode,
|
v->NumberOfActivePlanes,
|
v->MaxLineBufferLines,
|
v->LineBufferSize,
|
v->DPPOutputBufferPixels,
|
v->DETBufferSizeInKByte,
|
v->WritebackInterfaceBufferSize,
|
v->DCFCLK,
|
v->ReturnBW,
|
v->GPUVMEnable,
|
v->dpte_group_bytes,
|
v->MetaChunkSize,
|
v->UrgentLatency,
|
v->UrgentExtraLatency,
|
v->WritebackLatency,
|
v->WritebackChunkSize,
|
v->SOCCLK,
|
v->FinalDRAMClockChangeLatency,
|
v->SRExitTime,
|
v->SREnterPlusExitTime,
|
v->DCFCLKDeepSleep,
|
v->DPPPerPlane,
|
v->DCCEnable,
|
v->DPPCLK,
|
v->DETBufferSizeY,
|
v->DETBufferSizeC,
|
v->SwathHeightY,
|
v->SwathHeightC,
|
v->LBBitPerPixel,
|
v->SwathWidthY,
|
v->SwathWidthC,
|
v->HRatio,
|
v->HRatioChroma,
|
v->vtaps,
|
v->VTAPsChroma,
|
v->VRatio,
|
v->VRatioChroma,
|
v->HTotal,
|
v->PixelClock,
|
v->BlendingAndTiming,
|
v->BytePerPixelDETY,
|
v->BytePerPixelDETC,
|
v->DSTXAfterScaler,
|
v->DSTYAfterScaler,
|
v->WritebackEnable,
|
v->WritebackPixelFormat,
|
v->WritebackDestinationWidth,
|
v->WritebackDestinationHeight,
|
v->WritebackSourceHeight,
|
&DRAMClockChangeSupport,
|
&v->UrgentWatermark,
|
&v->WritebackUrgentWatermark,
|
&v->DRAMClockChangeWatermark,
|
&v->WritebackDRAMClockChangeWatermark,
|
&v->StutterExitWatermark,
|
&v->StutterEnterPlusExitWatermark,
|
&v->MinActiveDRAMClockChangeLatencySupported);
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->WritebackEnable[k] == true) {
|
if (v->BlendingAndTiming[k] == k) {
|
v->ThisVStartup = v->VStartup[k];
|
} else {
|
for (j = 0; j < v->NumberOfActivePlanes; ++j) {
|
if (v->BlendingAndTiming[k] == j) {
|
v->ThisVStartup = v->VStartup[j];
|
}
|
}
|
}
|
v->WritebackAllowDRAMClockChangeEndPosition[k] = dml_max(0,
|
v->ThisVStartup * v->HTotal[k] / v->PixelClock[k] - v->WritebackDRAMClockChangeWatermark);
|
} else {
|
v->WritebackAllowDRAMClockChangeEndPosition[k] = 0;
|
}
|
}
|
|
}
|
|
|
//Display Pipeline Delivery Time in Prefetch, Groups
|
CalculatePixelDeliveryTimes(
|
v->NumberOfActivePlanes,
|
v->VRatio,
|
v->VRatioChroma,
|
v->VRatioPrefetchY,
|
v->VRatioPrefetchC,
|
v->swath_width_luma_ub,
|
v->swath_width_chroma_ub,
|
v->DPPPerPlane,
|
v->HRatio,
|
v->HRatioChroma,
|
v->PixelClock,
|
v->PSCL_THROUGHPUT_LUMA,
|
v->PSCL_THROUGHPUT_CHROMA,
|
v->DPPCLK,
|
v->BytePerPixelC,
|
v->SourceScan,
|
v->NumberOfCursors,
|
v->CursorWidth,
|
v->CursorBPP,
|
v->BlockWidth256BytesY,
|
v->BlockHeight256BytesY,
|
v->BlockWidth256BytesC,
|
v->BlockHeight256BytesC,
|
v->DisplayPipeLineDeliveryTimeLuma,
|
v->DisplayPipeLineDeliveryTimeChroma,
|
v->DisplayPipeLineDeliveryTimeLumaPrefetch,
|
v->DisplayPipeLineDeliveryTimeChromaPrefetch,
|
v->DisplayPipeRequestDeliveryTimeLuma,
|
v->DisplayPipeRequestDeliveryTimeChroma,
|
v->DisplayPipeRequestDeliveryTimeLumaPrefetch,
|
v->DisplayPipeRequestDeliveryTimeChromaPrefetch,
|
v->CursorRequestDeliveryTime,
|
v->CursorRequestDeliveryTimePrefetch);
|
|
CalculateMetaAndPTETimes(
|
v->NumberOfActivePlanes,
|
v->GPUVMEnable,
|
v->MetaChunkSize,
|
v->MinMetaChunkSizeBytes,
|
v->HTotal,
|
v->VRatio,
|
v->VRatioChroma,
|
v->DestinationLinesToRequestRowInVBlank,
|
v->DestinationLinesToRequestRowInImmediateFlip,
|
v->DCCEnable,
|
v->PixelClock,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->SourceScan,
|
v->dpte_row_height,
|
v->dpte_row_height_chroma,
|
v->meta_row_width,
|
v->meta_row_width_chroma,
|
v->meta_row_height,
|
v->meta_row_height_chroma,
|
v->meta_req_width,
|
v->meta_req_width_chroma,
|
v->meta_req_height,
|
v->meta_req_height_chroma,
|
v->dpte_group_bytes,
|
v->PTERequestSizeY,
|
v->PTERequestSizeC,
|
v->PixelPTEReqWidthY,
|
v->PixelPTEReqHeightY,
|
v->PixelPTEReqWidthC,
|
v->PixelPTEReqHeightC,
|
v->dpte_row_width_luma_ub,
|
v->dpte_row_width_chroma_ub,
|
v->DST_Y_PER_PTE_ROW_NOM_L,
|
v->DST_Y_PER_PTE_ROW_NOM_C,
|
v->DST_Y_PER_META_ROW_NOM_L,
|
v->DST_Y_PER_META_ROW_NOM_C,
|
v->TimePerMetaChunkNominal,
|
v->TimePerChromaMetaChunkNominal,
|
v->TimePerMetaChunkVBlank,
|
v->TimePerChromaMetaChunkVBlank,
|
v->TimePerMetaChunkFlip,
|
v->TimePerChromaMetaChunkFlip,
|
v->time_per_pte_group_nom_luma,
|
v->time_per_pte_group_vblank_luma,
|
v->time_per_pte_group_flip_luma,
|
v->time_per_pte_group_nom_chroma,
|
v->time_per_pte_group_vblank_chroma,
|
v->time_per_pte_group_flip_chroma);
|
|
CalculateVMGroupAndRequestTimes(
|
v->NumberOfActivePlanes,
|
v->GPUVMEnable,
|
v->GPUVMMaxPageTableLevels,
|
v->HTotal,
|
v->BytePerPixelC,
|
v->DestinationLinesToRequestVMInVBlank,
|
v->DestinationLinesToRequestVMInImmediateFlip,
|
v->DCCEnable,
|
v->PixelClock,
|
v->dpte_row_width_luma_ub,
|
v->dpte_row_width_chroma_ub,
|
v->vm_group_bytes,
|
v->dpde0_bytes_per_frame_ub_l,
|
v->dpde0_bytes_per_frame_ub_c,
|
v->meta_pte_bytes_per_frame_ub_l,
|
v->meta_pte_bytes_per_frame_ub_c,
|
v->TimePerVMGroupVBlank,
|
v->TimePerVMGroupFlip,
|
v->TimePerVMRequestVBlank,
|
v->TimePerVMRequestFlip);
|
|
|
// Min TTUVBlank
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (PrefetchMode == 0) {
|
v->AllowDRAMClockChangeDuringVBlank[k] = true;
|
v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
|
v->MinTTUVBlank[k] = dml_max(
|
v->DRAMClockChangeWatermark,
|
dml_max(
|
v->StutterEnterPlusExitWatermark,
|
v->UrgentWatermark));
|
} else if (PrefetchMode == 1) {
|
v->AllowDRAMClockChangeDuringVBlank[k] = false;
|
v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
|
v->MinTTUVBlank[k] = dml_max(
|
v->StutterEnterPlusExitWatermark,
|
v->UrgentWatermark);
|
} else {
|
v->AllowDRAMClockChangeDuringVBlank[k] = false;
|
v->AllowDRAMSelfRefreshDuringVBlank[k] = false;
|
v->MinTTUVBlank[k] = v->UrgentWatermark;
|
}
|
if (!v->DynamicMetadataEnable[k])
|
v->MinTTUVBlank[k] = v->TCalc
|
+ v->MinTTUVBlank[k];
|
}
|
|
// DCC Configuration
|
v->ActiveDPPs = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
CalculateDCCConfiguration(v->DCCEnable[k], false, // We should always know the direction DCCProgrammingAssumesScanDirectionUnknown,
|
v->SourcePixelFormat[k],
|
v->SurfaceWidthY[k],
|
v->SurfaceWidthC[k],
|
v->SurfaceHeightY[k],
|
v->SurfaceHeightC[k],
|
v->DETBufferSizeInKByte * 1024,
|
v->BlockHeight256BytesY[k],
|
v->BlockHeight256BytesC[k],
|
v->SurfaceTiling[k],
|
v->BytePerPixelY[k],
|
v->BytePerPixelC[k],
|
v->BytePerPixelDETY[k],
|
v->BytePerPixelDETC[k],
|
v->SourceScan[k],
|
&v->DCCYMaxUncompressedBlock[k],
|
&v->DCCCMaxUncompressedBlock[k],
|
&v->DCCYMaxCompressedBlock[k],
|
&v->DCCCMaxCompressedBlock[k],
|
&v->DCCYIndependentBlock[k],
|
&v->DCCCIndependentBlock[k]);
|
}
|
|
{
|
//Maximum Bandwidth Used
|
double TotalWRBandwidth = 0;
|
double MaxPerPlaneVActiveWRBandwidth = 0;
|
double WRBandwidth = 0;
|
double MaxUsedBW = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->WritebackEnable[k] == true
|
&& v->WritebackPixelFormat[k] == dm_444_32) {
|
WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
|
/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 4;
|
} else if (v->WritebackEnable[k] == true) {
|
WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
|
/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 8;
|
}
|
TotalWRBandwidth = TotalWRBandwidth + WRBandwidth;
|
MaxPerPlaneVActiveWRBandwidth = dml_max(MaxPerPlaneVActiveWRBandwidth, WRBandwidth);
|
}
|
|
v->TotalDataReadBandwidth = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->TotalDataReadBandwidth = v->TotalDataReadBandwidth
|
+ v->ReadBandwidthPlaneLuma[k]
|
+ v->ReadBandwidthPlaneChroma[k];
|
}
|
|
{
|
double MaxPerPlaneVActiveRDBandwidth = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
MaxPerPlaneVActiveRDBandwidth = dml_max(MaxPerPlaneVActiveRDBandwidth,
|
v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
|
|
}
|
}
|
|
MaxUsedBW = MaxTotalRDBandwidth + TotalWRBandwidth;
|
}
|
|
// VStartup Margin
|
v->VStartupMargin = 0;
|
v->FirstMainPlane = true;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->BlendingAndTiming[k] == k) {
|
double margin = (v->MaxVStartupLines[k] - v->VStartup[k]) * v->HTotal[k]
|
/ v->PixelClock[k];
|
if (v->FirstMainPlane == true) {
|
v->VStartupMargin = margin;
|
v->FirstMainPlane = false;
|
} else {
|
v->VStartupMargin = dml_min(v->VStartupMargin, margin);
|
}
|
}
|
}
|
|
// Stutter Efficiency
|
CalculateStutterEfficiency(
|
v->NumberOfActivePlanes,
|
v->ROBBufferSizeInKByte,
|
v->TotalDataReadBandwidth,
|
v->DCFCLK,
|
v->ReturnBW,
|
v->SRExitTime,
|
v->SynchronizedVBlank,
|
v->DPPPerPlane,
|
v->DETBufferSizeY,
|
v->BytePerPixelY,
|
v->BytePerPixelDETY,
|
v->SwathWidthY,
|
v->SwathHeightY,
|
v->SwathHeightC,
|
v->DCCRateLuma,
|
v->DCCRateChroma,
|
v->HTotal,
|
v->VTotal,
|
v->PixelClock,
|
v->VRatio,
|
v->SourceScan,
|
v->BlockHeight256BytesY,
|
v->BlockWidth256BytesY,
|
v->BlockHeight256BytesC,
|
v->BlockWidth256BytesC,
|
v->DCCYMaxUncompressedBlock,
|
v->DCCCMaxUncompressedBlock,
|
v->VActive,
|
v->DCCEnable,
|
v->WritebackEnable,
|
v->ReadBandwidthPlaneLuma,
|
v->ReadBandwidthPlaneChroma,
|
v->meta_row_bw,
|
v->dpte_row_bw,
|
&v->StutterEfficiencyNotIncludingVBlank,
|
&v->StutterEfficiency,
|
&v->StutterPeriod);
|
}
|
|
static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
|
{
|
// Display Pipe Configuration
|
double BytePerPixDETY[DC__NUM_DPP__MAX] = { 0 };
|
double BytePerPixDETC[DC__NUM_DPP__MAX] = { 0 };
|
int BytePerPixY[DC__NUM_DPP__MAX] = { 0 };
|
int BytePerPixC[DC__NUM_DPP__MAX] = { 0 };
|
int Read256BytesBlockHeightY[DC__NUM_DPP__MAX] = { 0 };
|
int Read256BytesBlockHeightC[DC__NUM_DPP__MAX] = { 0 };
|
int Read256BytesBlockWidthY[DC__NUM_DPP__MAX] = { 0 };
|
int Read256BytesBlockWidthC[DC__NUM_DPP__MAX] = { 0 };
|
double dummy1[DC__NUM_DPP__MAX] = { 0 };
|
double dummy2[DC__NUM_DPP__MAX] = { 0 };
|
double dummy3[DC__NUM_DPP__MAX] = { 0 };
|
double dummy4[DC__NUM_DPP__MAX] = { 0 };
|
int dummy5[DC__NUM_DPP__MAX] = { 0 };
|
int dummy6[DC__NUM_DPP__MAX] = { 0 };
|
bool dummy7[DC__NUM_DPP__MAX] = { 0 };
|
bool dummysinglestring = 0;
|
unsigned int k;
|
|
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
|
|
CalculateBytePerPixelAnd256BBlockSizes(
|
mode_lib->vba.SourcePixelFormat[k],
|
mode_lib->vba.SurfaceTiling[k],
|
&BytePerPixY[k],
|
&BytePerPixC[k],
|
&BytePerPixDETY[k],
|
&BytePerPixDETC[k],
|
&Read256BytesBlockHeightY[k],
|
&Read256BytesBlockHeightC[k],
|
&Read256BytesBlockWidthY[k],
|
&Read256BytesBlockWidthC[k]);
|
}
|
CalculateSwathAndDETConfiguration(
|
false,
|
mode_lib->vba.NumberOfActivePlanes,
|
mode_lib->vba.DETBufferSizeInKByte,
|
dummy1,
|
dummy2,
|
mode_lib->vba.SourceScan,
|
mode_lib->vba.SourcePixelFormat,
|
mode_lib->vba.SurfaceTiling,
|
mode_lib->vba.ViewportWidth,
|
mode_lib->vba.ViewportHeight,
|
mode_lib->vba.SurfaceWidthY,
|
mode_lib->vba.SurfaceWidthC,
|
mode_lib->vba.SurfaceHeightY,
|
mode_lib->vba.SurfaceHeightC,
|
Read256BytesBlockHeightY,
|
Read256BytesBlockHeightC,
|
Read256BytesBlockWidthY,
|
Read256BytesBlockWidthC,
|
mode_lib->vba.ODMCombineEnabled,
|
mode_lib->vba.BlendingAndTiming,
|
BytePerPixY,
|
BytePerPixC,
|
BytePerPixDETY,
|
BytePerPixDETC,
|
mode_lib->vba.HActive,
|
mode_lib->vba.HRatio,
|
mode_lib->vba.HRatioChroma,
|
mode_lib->vba.DPPPerPlane,
|
dummy5,
|
dummy6,
|
dummy3,
|
dummy4,
|
mode_lib->vba.SwathHeightY,
|
mode_lib->vba.SwathHeightC,
|
mode_lib->vba.DETBufferSizeY,
|
mode_lib->vba.DETBufferSizeC,
|
dummy7,
|
&dummysinglestring);
|
}
|
|
static bool CalculateBytePerPixelAnd256BBlockSizes(
|
enum source_format_class SourcePixelFormat,
|
enum dm_swizzle_mode SurfaceTiling,
|
unsigned int *BytePerPixelY,
|
unsigned int *BytePerPixelC,
|
double *BytePerPixelDETY,
|
double *BytePerPixelDETC,
|
unsigned int *BlockHeight256BytesY,
|
unsigned int *BlockHeight256BytesC,
|
unsigned int *BlockWidth256BytesY,
|
unsigned int *BlockWidth256BytesC)
|
{
|
if (SourcePixelFormat == dm_444_64) {
|
*BytePerPixelDETY = 8;
|
*BytePerPixelDETC = 0;
|
*BytePerPixelY = 8;
|
*BytePerPixelC = 0;
|
} else if (SourcePixelFormat == dm_444_32 || SourcePixelFormat == dm_rgbe) {
|
*BytePerPixelDETY = 4;
|
*BytePerPixelDETC = 0;
|
*BytePerPixelY = 4;
|
*BytePerPixelC = 0;
|
} else if (SourcePixelFormat == dm_444_16) {
|
*BytePerPixelDETY = 2;
|
*BytePerPixelDETC = 0;
|
*BytePerPixelY = 2;
|
*BytePerPixelC = 0;
|
} else if (SourcePixelFormat == dm_444_8) {
|
*BytePerPixelDETY = 1;
|
*BytePerPixelDETC = 0;
|
*BytePerPixelY = 1;
|
*BytePerPixelC = 0;
|
} else if (SourcePixelFormat == dm_rgbe_alpha) {
|
*BytePerPixelDETY = 4;
|
*BytePerPixelDETC = 1;
|
*BytePerPixelY = 4;
|
*BytePerPixelC = 1;
|
} else if (SourcePixelFormat == dm_420_8) {
|
*BytePerPixelDETY = 1;
|
*BytePerPixelDETC = 2;
|
*BytePerPixelY = 1;
|
*BytePerPixelC = 2;
|
} else if (SourcePixelFormat == dm_420_12) {
|
*BytePerPixelDETY = 2;
|
*BytePerPixelDETC = 4;
|
*BytePerPixelY = 2;
|
*BytePerPixelC = 4;
|
} else {
|
*BytePerPixelDETY = 4.0 / 3;
|
*BytePerPixelDETC = 8.0 / 3;
|
*BytePerPixelY = 2;
|
*BytePerPixelC = 4;
|
}
|
|
if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
|
|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8
|
|| SourcePixelFormat == dm_mono_16 || SourcePixelFormat == dm_mono_8
|
|| SourcePixelFormat == dm_rgbe)) {
|
if (SurfaceTiling == dm_sw_linear) {
|
*BlockHeight256BytesY = 1;
|
} else if (SourcePixelFormat == dm_444_64) {
|
*BlockHeight256BytesY = 4;
|
} else if (SourcePixelFormat == dm_444_8) {
|
*BlockHeight256BytesY = 16;
|
} else {
|
*BlockHeight256BytesY = 8;
|
}
|
*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
|
*BlockHeight256BytesC = 0;
|
*BlockWidth256BytesC = 0;
|
} else {
|
if (SurfaceTiling == dm_sw_linear) {
|
*BlockHeight256BytesY = 1;
|
*BlockHeight256BytesC = 1;
|
} else if (SourcePixelFormat == dm_rgbe_alpha) {
|
*BlockHeight256BytesY = 8;
|
*BlockHeight256BytesC = 16;
|
} else if (SourcePixelFormat == dm_420_8) {
|
*BlockHeight256BytesY = 16;
|
*BlockHeight256BytesC = 8;
|
} else {
|
*BlockHeight256BytesY = 8;
|
*BlockHeight256BytesC = 8;
|
}
|
*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
|
*BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC;
|
}
|
return true;
|
}
|
|
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;
|
}
|
}
|
|
double dml30_CalculateWriteBackDISPCLK(
|
enum source_format_class WritebackPixelFormat,
|
double PixelClock,
|
double WritebackHRatio,
|
double WritebackVRatio,
|
unsigned int WritebackHTaps,
|
unsigned int WritebackVTaps,
|
long WritebackSourceWidth,
|
long WritebackDestinationWidth,
|
unsigned int HTotal,
|
unsigned int WritebackLineBufferSize)
|
{
|
double DISPCLK_H = 0, DISPCLK_V = 0, DISPCLK_HB = 0;
|
|
DISPCLK_H = PixelClock * dml_ceil(WritebackHTaps / 8.0, 1) / WritebackHRatio;
|
DISPCLK_V = PixelClock * (WritebackVTaps * dml_ceil(WritebackDestinationWidth / 6.0, 1) + 8.0) / HTotal;
|
DISPCLK_HB = PixelClock * WritebackVTaps * (WritebackDestinationWidth * WritebackVTaps - WritebackLineBufferSize / 57.0) / 6.0 / WritebackSourceWidth;
|
return dml_max3(DISPCLK_H, DISPCLK_V, DISPCLK_HB);
|
}
|
|
static double CalculateWriteBackDelay(
|
enum source_format_class WritebackPixelFormat,
|
double WritebackHRatio,
|
double WritebackVRatio,
|
unsigned int WritebackVTaps,
|
long WritebackDestinationWidth,
|
long WritebackDestinationHeight,
|
long WritebackSourceHeight,
|
unsigned int HTotal)
|
{
|
double CalculateWriteBackDelay = 0;
|
double Line_length = 0;
|
double Output_lines_last_notclamped = 0;
|
double WritebackVInit = 0;
|
|
WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2;
|
Line_length = dml_max((double) WritebackDestinationWidth, dml_ceil(WritebackDestinationWidth / 6.0, 1) * WritebackVTaps);
|
Output_lines_last_notclamped = WritebackDestinationHeight - 1 - dml_ceil((WritebackSourceHeight - WritebackVInit) / WritebackVRatio, 1);
|
if (Output_lines_last_notclamped < 0) {
|
CalculateWriteBackDelay = 0;
|
} else {
|
CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackDestinationWidth) + 80;
|
}
|
return CalculateWriteBackDelay;
|
}
|
|
|
static void CalculateDynamicMetadataParameters(int MaxInterDCNTileRepeaters, double DPPCLK, double DISPCLK,
|
double DCFClkDeepSleep, double PixelClock, long HTotal, long VBlank, long DynamicMetadataTransmittedBytes,
|
long DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP,
|
double *Tsetup, double *Tdmbf, double *Tdmec, double *Tdmsks)
|
{
|
double TotalRepeaterDelayTime = 0;
|
double VUpdateWidthPix = 0;
|
double VReadyOffsetPix = 0;
|
double VUpdateOffsetPix = 0;
|
TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / DPPCLK + 3 / DISPCLK);
|
VUpdateWidthPix = (14 / DCFClkDeepSleep + 12 / DPPCLK + TotalRepeaterDelayTime) * PixelClock;
|
VReadyOffsetPix = dml_max(150.0 / DPPCLK, TotalRepeaterDelayTime + 20 / DCFClkDeepSleep + 10 / DPPCLK) * PixelClock;
|
VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
|
*Tsetup = (VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock;
|
*Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
|
*Tdmec = HTotal / PixelClock;
|
if (DynamicMetadataLinesBeforeActiveRequired == 0) {
|
*Tdmsks = VBlank * HTotal / PixelClock / 2.0;
|
} else {
|
*Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock;
|
}
|
if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) {
|
*Tdmsks = *Tdmsks / 2;
|
}
|
}
|
|
static void CalculateRowBandwidth(
|
bool GPUVMEnable,
|
enum source_format_class SourcePixelFormat,
|
double VRatio,
|
double VRatioChroma,
|
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 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
|
*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
|
+ VRatioChroma * 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 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
|
*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
|
+ VRatioChroma * 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 HostVMMaxNonCachedPageTableLevels,
|
bool GPUVMEnable,
|
double HostVMMinPageSize,
|
double PDEAndMetaPTEBytesPerFrame,
|
double MetaRowBytes,
|
double DPTEBytesPerRow,
|
double BandwidthAvailableForImmediateFlip,
|
unsigned int TotImmediateFlipBytes,
|
enum source_format_class SourcePixelFormat,
|
double LineTime,
|
double VRatio,
|
double VRatioChroma,
|
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 HostVMDynamicLevelsTrips = 0;
|
double TimeForFetchingMetaPTEImmediateFlip = 0;
|
double TimeForFetchingRowInVBlankImmediateFlip = 0;
|
double ImmediateFlipBW = 0;
|
double HostVMInefficiencyFactor = 0;
|
|
if (GPUVMEnable == true && HostVMEnable == true) {
|
HostVMInefficiencyFactor = PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
|
HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
|
} else {
|
HostVMInefficiencyFactor = 1;
|
HostVMDynamicLevelsTrips = 0;
|
}
|
|
if (GPUVMEnable == true || DCCEnable == true) {
|
ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * BandwidthAvailableForImmediateFlip / TotImmediateFlipBytes;
|
}
|
|
if (GPUVMEnable == true) {
|
TimeForFetchingMetaPTEImmediateFlip = dml_max3(Tno_bw + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW,
|
UrgentExtraLatency + UrgentLatency * (GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 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 * (HostVMDynamicLevelsTrips + 1), LineTime / 4);
|
} else {
|
TimeForFetchingRowInVBlankImmediateFlip = 0;
|
}
|
|
*DestinationLinesToRequestRowInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0;
|
|
if (GPUVMEnable == true) {
|
*final_flip_bw = dml_max(PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInImmediateFlip * LineTime),
|
(MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime));
|
} else if ((GPUVMEnable == true || DCCEnable == true)) {
|
*final_flip_bw = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime);
|
} else {
|
*final_flip_bw = 0;
|
}
|
|
|
if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_rgbe_alpha) {
|
if (GPUVMEnable == true && DCCEnable != true) {
|
min_row_time = dml_min(dpte_row_height * LineTime / VRatio, dpte_row_height_chroma * LineTime / VRatioChroma);
|
} else if (GPUVMEnable != true && DCCEnable == true) {
|
min_row_time = dml_min(meta_row_height * LineTime / VRatio, meta_row_height_chroma * LineTime / VRatioChroma);
|
} else {
|
min_row_time = dml_min4(dpte_row_height * LineTime / VRatio, meta_row_height * LineTime / VRatio,
|
dpte_row_height_chroma * LineTime / VRatioChroma, meta_row_height_chroma * LineTime / VRatioChroma);
|
}
|
} 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 double TruncToValidBPP(
|
double LinkBitRate,
|
int Lanes,
|
long HTotal,
|
long HActive,
|
double PixelClock,
|
double DesiredBPP,
|
bool DSCEnable,
|
enum output_encoder_class Output,
|
enum output_format_class Format,
|
unsigned int DSCInputBitPerComponent,
|
int DSCSlices,
|
int AudioRate,
|
int AudioLayout,
|
enum odm_combine_mode ODMCombine)
|
{
|
double MaxLinkBPP = 0;
|
int MinDSCBPP = 0;
|
double MaxDSCBPP = 0;
|
int NonDSCBPP0 = 0;
|
int NonDSCBPP1 = 0;
|
int NonDSCBPP2 = 0;
|
|
if (Format == dm_420) {
|
NonDSCBPP0 = 12;
|
NonDSCBPP1 = 15;
|
NonDSCBPP2 = 18;
|
MinDSCBPP = 6;
|
MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
|
} else if (Format == dm_444) {
|
NonDSCBPP0 = 24;
|
NonDSCBPP1 = 30;
|
NonDSCBPP2 = 36;
|
MinDSCBPP = 8;
|
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
} else {
|
if (Output == dm_hdmi) {
|
NonDSCBPP0 = 24;
|
NonDSCBPP1 = 24;
|
NonDSCBPP2 = 24;
|
}
|
else {
|
NonDSCBPP0 = 16;
|
NonDSCBPP1 = 20;
|
NonDSCBPP2 = 24;
|
}
|
|
if (Format == dm_n422) {
|
MinDSCBPP = 7;
|
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
}
|
else {
|
MinDSCBPP = 8;
|
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
|
}
|
}
|
|
if (DSCEnable && Output == dm_dp) {
|
MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
|
} else {
|
MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock;
|
}
|
|
if (ODMCombine == dm_odm_combine_mode_4to1 && MaxLinkBPP > 16) {
|
MaxLinkBPP = 16;
|
} else if (ODMCombine == dm_odm_combine_mode_2to1 && MaxLinkBPP > 32) {
|
MaxLinkBPP = 32;
|
}
|
|
|
if (DesiredBPP == 0) {
|
if (DSCEnable) {
|
if (MaxLinkBPP < MinDSCBPP) {
|
return BPP_INVALID;
|
} else if (MaxLinkBPP >= MaxDSCBPP) {
|
return MaxDSCBPP;
|
} else {
|
return dml_floor(16.0 * MaxLinkBPP, 1.0) / 16.0;
|
}
|
} else {
|
if (MaxLinkBPP >= NonDSCBPP2) {
|
return NonDSCBPP2;
|
} else if (MaxLinkBPP >= NonDSCBPP1) {
|
return NonDSCBPP1;
|
} else if (MaxLinkBPP >= NonDSCBPP0) {
|
return NonDSCBPP0;
|
} else {
|
return BPP_INVALID;
|
}
|
}
|
} else {
|
if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP == NonDSCBPP0)) ||
|
(DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
|
return BPP_INVALID;
|
} else {
|
return DesiredBPP;
|
}
|
}
|
return BPP_INVALID;
|
}
|
|
void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
|
{
|
struct vba_vars_st *v = &mode_lib->vba;
|
int MinPrefetchMode = 0;
|
int MaxPrefetchMode = 2;
|
int i;
|
unsigned int j, k, m;
|
bool EnoughWritebackUnits = true;
|
bool WritebackModeSupport = true;
|
bool ViewportExceedsSurface = false;
|
double MaxTotalVActiveRDBandwidth = 0;
|
long ReorderingBytes = 0;
|
bool NotUrgentLatencyHiding[DC__NUM_DPP__MAX] = { 0 };
|
|
/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
|
|
/*Scale Ratio, taps Support Check*/
|
|
v->ScaleRatioAndTapsSupport = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->ScalerEnabled[k] == false
|
&& ((v->SourcePixelFormat[k] != dm_444_64
|
&& v->SourcePixelFormat[k] != dm_444_32
|
&& v->SourcePixelFormat[k] != dm_444_16
|
&& v->SourcePixelFormat[k] != dm_mono_16
|
&& v->SourcePixelFormat[k] != dm_mono_8
|
&& v->SourcePixelFormat[k] != dm_rgbe
|
&& v->SourcePixelFormat[k] != dm_rgbe_alpha)
|
|| v->HRatio[k] != 1.0
|
|| v->htaps[k] != 1.0
|
|| v->VRatio[k] != 1.0
|
|| v->vtaps[k] != 1.0)) {
|
v->ScaleRatioAndTapsSupport = false;
|
} else if (v->vtaps[k] < 1.0 || v->vtaps[k] > 8.0
|
|| v->htaps[k] < 1.0 || v->htaps[k] > 8.0
|
|| (v->htaps[k] > 1.0
|
&& (v->htaps[k] % 2) == 1)
|
|| v->HRatio[k] > v->MaxHSCLRatio
|
|| v->VRatio[k] > v->MaxVSCLRatio
|
|| v->HRatio[k] > v->htaps[k]
|
|| v->VRatio[k] > v->vtaps[k]
|
|| (v->SourcePixelFormat[k] != dm_444_64
|
&& v->SourcePixelFormat[k] != dm_444_32
|
&& v->SourcePixelFormat[k] != dm_444_16
|
&& v->SourcePixelFormat[k] != dm_mono_16
|
&& v->SourcePixelFormat[k] != dm_mono_8
|
&& v->SourcePixelFormat[k] != dm_rgbe
|
&& (v->VTAPsChroma[k] < 1
|
|| v->VTAPsChroma[k] > 8
|
|| v->HTAPsChroma[k] < 1
|
|| v->HTAPsChroma[k] > 8
|
|| (v->HTAPsChroma[k] > 1 && v->HTAPsChroma[k] % 2 == 1)
|
|| v->HRatioChroma[k] > v->MaxHSCLRatio
|
|| v->VRatioChroma[k] > v->MaxVSCLRatio
|
|| v->HRatioChroma[k] > v->HTAPsChroma[k]
|
|| v->VRatioChroma[k] > v->VTAPsChroma[k]))) {
|
v->ScaleRatioAndTapsSupport = false;
|
}
|
}
|
/*Source Format, Pixel Format and Scan Support Check*/
|
|
v->SourceFormatPixelAndScanSupport = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if ((v->SurfaceTiling[k] == dm_sw_linear && (!(v->SourceScan[k] != dm_vert) || v->DCCEnable[k] == true))
|
|| ((v->SurfaceTiling[k] == dm_sw_64kb_d || v->SurfaceTiling[k] == dm_sw_64kb_d_t || v->SurfaceTiling[k] == dm_sw_64kb_d_x)
|
&& !(v->SourcePixelFormat[k] == dm_444_64))) {
|
v->SourceFormatPixelAndScanSupport = false;
|
}
|
}
|
/*Bandwidth Support Check*/
|
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
CalculateBytePerPixelAnd256BBlockSizes(
|
v->SourcePixelFormat[k],
|
v->SurfaceTiling[k],
|
&v->BytePerPixelY[k],
|
&v->BytePerPixelC[k],
|
&v->BytePerPixelInDETY[k],
|
&v->BytePerPixelInDETC[k],
|
&v->Read256BlockHeightY[k],
|
&v->Read256BlockHeightC[k],
|
&v->Read256BlockWidthY[k],
|
&v->Read256BlockWidthC[k]);
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->SourceScan[k] != dm_vert) {
|
v->SwathWidthYSingleDPP[k] = v->ViewportWidth[k];
|
v->SwathWidthCSingleDPP[k] = v->ViewportWidthChroma[k];
|
} else {
|
v->SwathWidthYSingleDPP[k] = v->ViewportHeight[k];
|
v->SwathWidthCSingleDPP[k] = v->ViewportHeightChroma[k];
|
}
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->ReadBandwidthLuma[k] = v->SwathWidthYSingleDPP[k] * dml_ceil(v->BytePerPixelInDETY[k], 1.0) / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
|
v->ReadBandwidthChroma[k] = v->SwathWidthYSingleDPP[k] / 2 * dml_ceil(v->BytePerPixelInDETC[k], 2.0) / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k] / 2.0;
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->WritebackEnable[k] == true
|
&& v->WritebackPixelFormat[k] == dm_444_64) {
|
v->WriteBandwidth[k] = v->WritebackDestinationWidth[k]
|
* v->WritebackDestinationHeight[k]
|
/ (v->WritebackSourceHeight[k]
|
* v->HTotal[k]
|
/ v->PixelClock[k]) * 8.0;
|
} else if (v->WritebackEnable[k] == true) {
|
v->WriteBandwidth[k] = v->WritebackDestinationWidth[k]
|
* v->WritebackDestinationHeight[k]
|
/ (v->WritebackSourceHeight[k]
|
* v->HTotal[k]
|
/ v->PixelClock[k]) * 4.0;
|
} else {
|
v->WriteBandwidth[k] = 0.0;
|
}
|
}
|
|
/*Writeback Latency support check*/
|
|
v->WritebackLatencySupport = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->WritebackEnable[k] == true) {
|
if (v->WritebackConfiguration == dm_whole_buffer_for_single_stream_no_interleave ||
|
v->WritebackConfiguration == dm_whole_buffer_for_single_stream_interleave) {
|
if (v->WriteBandwidth[k]
|
> 2.0 * v->WritebackInterfaceBufferSize * 1024
|
/ v->WritebackLatency) {
|
v->WritebackLatencySupport = false;
|
}
|
} else {
|
if (v->WriteBandwidth[k]
|
> v->WritebackInterfaceBufferSize * 1024
|
/ v->WritebackLatency) {
|
v->WritebackLatencySupport = false;
|
}
|
}
|
}
|
}
|
|
/*Writeback Mode Support Check*/
|
|
v->TotalNumberOfActiveWriteback = 0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->WritebackEnable[k] == true) {
|
v->TotalNumberOfActiveWriteback =
|
v->TotalNumberOfActiveWriteback + 1;
|
}
|
}
|
|
if (v->TotalNumberOfActiveWriteback > v->MaxNumWriteback) {
|
EnoughWritebackUnits = false;
|
}
|
if (!v->WritebackSupportInterleaveAndUsingWholeBufferForASingleStream
|
&& (v->WritebackConfiguration == dm_whole_buffer_for_single_stream_no_interleave
|
|| v->WritebackConfiguration == dm_whole_buffer_for_single_stream_interleave)) {
|
|
WritebackModeSupport = false;
|
}
|
if (v->WritebackConfiguration == dm_whole_buffer_for_single_stream_no_interleave && v->TotalNumberOfActiveWriteback > 1) {
|
WritebackModeSupport = false;
|
}
|
|
/*Writeback Scale Ratio and Taps Support Check*/
|
|
v->WritebackScaleRatioAndTapsSupport = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->WritebackEnable[k] == true) {
|
if (v->WritebackHRatio[k] > v->WritebackMaxHSCLRatio
|
|| v->WritebackVRatio[k]
|
> v->WritebackMaxVSCLRatio
|
|| v->WritebackHRatio[k]
|
< v->WritebackMinHSCLRatio
|
|| v->WritebackVRatio[k]
|
< v->WritebackMinVSCLRatio
|
|| v->WritebackHTaps[k]
|
> v->WritebackMaxHSCLTaps
|
|| v->WritebackVTaps[k]
|
> v->WritebackMaxVSCLTaps
|
|| v->WritebackHRatio[k]
|
> v->WritebackHTaps[k]
|
|| v->WritebackVRatio[k]
|
> v->WritebackVTaps[k]
|
|| (v->WritebackHTaps[k] > 2.0
|
&& ((v->WritebackHTaps[k] % 2)
|
== 1))) {
|
v->WritebackScaleRatioAndTapsSupport = false;
|
}
|
if (2.0 * v->WritebackDestinationWidth[k] * (v->WritebackVTaps[k] - 1) * 57 > v->WritebackLineBufferSize) {
|
v->WritebackScaleRatioAndTapsSupport = false;
|
}
|
}
|
}
|
/*Maximum DISPCLK/DPPCLK Support check*/
|
|
v->WritebackRequiredDISPCLK = 0.0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->WritebackEnable[k] == true) {
|
v->WritebackRequiredDISPCLK = dml_max(v->WritebackRequiredDISPCLK,
|
dml30_CalculateWriteBackDISPCLK(
|
v->WritebackPixelFormat[k],
|
v->PixelClock[k],
|
v->WritebackHRatio[k],
|
v->WritebackVRatio[k],
|
v->WritebackHTaps[k],
|
v->WritebackVTaps[k],
|
v->WritebackSourceWidth[k],
|
v->WritebackDestinationWidth[k],
|
v->HTotal[k],
|
v->WritebackLineBufferSize));
|
}
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->HRatio[k] > 1.0) {
|
v->PSCL_FACTOR[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1.0));
|
} else {
|
v->PSCL_FACTOR[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
|
}
|
if (v->BytePerPixelC[k] == 0.0) {
|
v->PSCL_FACTOR_CHROMA[k] = 0.0;
|
v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k]
|
* dml_max3(v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]), v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k], 1.0);
|
if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0) && v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
|
v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
|
}
|
} else {
|
if (v->HRatioChroma[k] > 1.0) {
|
v->PSCL_FACTOR_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput,
|
v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
|
} else {
|
v->PSCL_FACTOR_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
|
}
|
v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k] * dml_max5(v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
|
v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k],
|
v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
|
v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_FACTOR_CHROMA[k],
|
1.0);
|
if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0 || v->HTAPsChroma[k] > 6.0 || v->VTAPsChroma[k] > 6.0)
|
&& v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
|
v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
|
}
|
}
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
int MaximumSwathWidthSupportLuma = 0;
|
int MaximumSwathWidthSupportChroma = 0;
|
|
if (v->SurfaceTiling[k] == dm_sw_linear) {
|
MaximumSwathWidthSupportLuma = 8192.0;
|
} else if (v->SourceScan[k] == dm_vert && v->BytePerPixelC[k] > 0) {
|
MaximumSwathWidthSupportLuma = 2880.0;
|
} else {
|
MaximumSwathWidthSupportLuma = 5760.0;
|
}
|
|
if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) {
|
MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma / 2.0;
|
} else {
|
MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma;
|
}
|
v->MaximumSwathWidthInLineBufferLuma = v->LineBufferSize * dml_max(v->HRatio[k], 1.0) / v->LBBitPerPixel[k]
|
/ (v->vtaps[k] + dml_max(dml_ceil(v->VRatio[k], 1.0) - 2, 0.0));
|
if (v->BytePerPixelC[k] == 0.0) {
|
v->MaximumSwathWidthInLineBufferChroma = 0;
|
} else {
|
v->MaximumSwathWidthInLineBufferChroma = v->LineBufferSize * dml_max(v->HRatioChroma[k], 1.0) / v->LBBitPerPixel[k]
|
/ (v->VTAPsChroma[k] + dml_max(dml_ceil(v->VRatioChroma[k], 1.0) - 2, 0.0));
|
}
|
v->MaximumSwathWidthLuma[k] = dml_min(MaximumSwathWidthSupportLuma, v->MaximumSwathWidthInLineBufferLuma);
|
v->MaximumSwathWidthChroma[k] = dml_min(MaximumSwathWidthSupportChroma, v->MaximumSwathWidthInLineBufferChroma);
|
}
|
|
CalculateSwathAndDETConfiguration(
|
true,
|
v->NumberOfActivePlanes,
|
v->DETBufferSizeInKByte,
|
v->MaximumSwathWidthLuma,
|
v->MaximumSwathWidthChroma,
|
v->SourceScan,
|
v->SourcePixelFormat,
|
v->SurfaceTiling,
|
v->ViewportWidth,
|
v->ViewportHeight,
|
v->SurfaceWidthY,
|
v->SurfaceWidthC,
|
v->SurfaceHeightY,
|
v->SurfaceHeightC,
|
v->Read256BlockHeightY,
|
v->Read256BlockHeightC,
|
v->Read256BlockWidthY,
|
v->Read256BlockWidthC,
|
v->odm_combine_dummy,
|
v->BlendingAndTiming,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->BytePerPixelInDETY,
|
v->BytePerPixelInDETC,
|
v->HActive,
|
v->HRatio,
|
v->HRatioChroma,
|
v->DPPPerPlane,
|
v->swath_width_luma_ub,
|
v->swath_width_chroma_ub,
|
v->SwathWidthY,
|
v->SwathWidthC,
|
v->SwathHeightY,
|
v->SwathHeightC,
|
v->DETBufferSizeY,
|
v->DETBufferSizeC,
|
v->SingleDPPViewportSizeSupportPerPlane,
|
&v->ViewportSizeSupport[0][0]);
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
for (j = 0; j < 2; j++) {
|
v->MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDispclk[i], v->DISPCLKDPPCLKVCOSpeed);
|
v->MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDppclk[i], v->DISPCLKDPPCLKVCOSpeed);
|
v->RequiredDISPCLK[i][j] = 0.0;
|
v->DISPCLK_DPPCLK_Support[i][j] = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
|
* (1.0 + v->DISPCLKRampingMargin / 100.0);
|
if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
|
&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
|
v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
}
|
v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
|
* (1 + v->DISPCLKRampingMargin / 100.0);
|
if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
|
&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
|
v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
}
|
v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
|
* (1 + v->DISPCLKRampingMargin / 100.0);
|
if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
|
&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
|
v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
}
|
|
if (v->ODMCombinePolicy == dm_odm_combine_policy_none) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
|
} else if (v->ODMCombinePolicy == dm_odm_combine_policy_2to1) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
|
} else if (v->ODMCombinePolicy == dm_odm_combine_policy_4to1
|
|| v->PlaneRequiredDISPCLKWithODMCombine2To1 > v->MaxDispclkRoundedDownToDFSGranularity) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
|
} else if (v->PlaneRequiredDISPCLKWithoutODMCombine > v->MaxDispclkRoundedDownToDFSGranularity) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
|
} else {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
|
}
|
if (v->DSCEnabled[k] && v->HActive[k] > DCN30_MAX_DSC_IMAGE_WIDTH
|
&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
|
if (v->HActive[k] / 2 > DCN30_MAX_DSC_IMAGE_WIDTH) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
|
} else {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
|
}
|
}
|
if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN30_MAX_FMT_420_BUFFER_WIDTH
|
&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
|
if (v->HActive[k] / 2 > DCN30_MAX_FMT_420_BUFFER_WIDTH) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
|
} else {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
|
}
|
}
|
if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
|
v->MPCCombine[i][j][k] = false;
|
v->NoOfDPP[i][j][k] = 4;
|
v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 4;
|
} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
v->MPCCombine[i][j][k] = false;
|
v->NoOfDPP[i][j][k] = 2;
|
v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2;
|
} else if ((v->WhenToDoMPCCombine == dm_mpc_never
|
|| (v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= v->MaxDppclkRoundedDownToDFSGranularity
|
&& v->SingleDPPViewportSizeSupportPerPlane[k] == true))) {
|
v->MPCCombine[i][j][k] = false;
|
v->NoOfDPP[i][j][k] = 1;
|
v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
} else {
|
v->MPCCombine[i][j][k] = true;
|
v->NoOfDPP[i][j][k] = 2;
|
v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
|
}
|
v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
|
if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
|
> v->MaxDppclkRoundedDownToDFSGranularity) || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
|
v->DISPCLK_DPPCLK_Support[i][j] = false;
|
}
|
}
|
v->TotalNumberOfActiveDPP[i][j] = 0;
|
v->TotalNumberOfSingleDPPPlanes[i][j] = 0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
|
if (v->NoOfDPP[i][j][k] == 1)
|
v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] + 1;
|
}
|
if (j == 1 && v->WhenToDoMPCCombine != dm_mpc_never) {
|
while (!(v->TotalNumberOfActiveDPP[i][j] >= v->MaxNumDPP || v->TotalNumberOfSingleDPPPlanes[i][j] == 0)) {
|
double BWOfNonSplitPlaneOfMaximumBandwidth = 0;
|
unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
|
BWOfNonSplitPlaneOfMaximumBandwidth = 0;
|
NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k] > BWOfNonSplitPlaneOfMaximumBandwidth
|
&& v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled && v->MPCCombine[i][j][k] == false) {
|
BWOfNonSplitPlaneOfMaximumBandwidth = v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
|
NumberOfNonSplitPlaneOfMaximumBandwidth = k;
|
}
|
}
|
v->MPCCombine[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = true;
|
v->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
|
v->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = v->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
|
* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
|
v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + 1;
|
v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] + 1;
|
}
|
}
|
if (v->TotalNumberOfActiveDPP[i][j] > v->MaxNumDPP) {
|
v->RequiredDISPCLK[i][j] = 0.0;
|
v->DISPCLK_DPPCLK_Support[i][j] = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
if (v->SingleDPPViewportSizeSupportPerPlane[k] == false && v->WhenToDoMPCCombine != dm_mpc_never) {
|
v->MPCCombine[i][j][k] = true;
|
v->NoOfDPP[i][j][k] = 2;
|
v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
|
} else {
|
v->MPCCombine[i][j][k] = false;
|
v->NoOfDPP[i][j][k] = 1;
|
v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
}
|
if (!(v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1] && v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
|
v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
|
* (1.0 + v->DISPCLKRampingMargin / 100.0);
|
} else {
|
v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
}
|
v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
|
if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
|
> v->MaxDppclkRoundedDownToDFSGranularity) || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
|
v->DISPCLK_DPPCLK_Support[i][j] = false;
|
}
|
}
|
v->TotalNumberOfActiveDPP[i][j] = 0.0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
|
}
|
}
|
v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->WritebackRequiredDISPCLK);
|
if (v->MaxDispclkRoundedDownToDFSGranularity < v->WritebackRequiredDISPCLK) {
|
v->DISPCLK_DPPCLK_Support[i][j] = false;
|
}
|
}
|
}
|
|
/*Total Available Pipes Support Check*/
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
for (j = 0; j < 2; j++) {
|
if (v->TotalNumberOfActiveDPP[i][j] <= v->MaxNumDPP) {
|
v->TotalAvailablePipesSupport[i][j] = true;
|
} else {
|
v->TotalAvailablePipesSupport[i][j] = false;
|
}
|
}
|
}
|
/*Display IO and DSC Support Check*/
|
|
v->NonsupportedDSCInputBPC = false;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (!(v->DSCInputBitPerComponent[k] == 12.0
|
|| v->DSCInputBitPerComponent[k] == 10.0
|
|| v->DSCInputBitPerComponent[k] == 8.0)) {
|
v->NonsupportedDSCInputBPC = true;
|
}
|
}
|
|
/*Number Of DSC Slices*/
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->BlendingAndTiming[k] == k) {
|
if (v->PixelClockBackEnd[k] > 3200) {
|
v->NumberOfDSCSlices[k] = dml_ceil(v->PixelClockBackEnd[k] / 400.0, 4.0);
|
} else if (v->PixelClockBackEnd[k] > 1360) {
|
v->NumberOfDSCSlices[k] = 8;
|
} else if (v->PixelClockBackEnd[k] > 680) {
|
v->NumberOfDSCSlices[k] = 4;
|
} else if (v->PixelClockBackEnd[k] > 340) {
|
v->NumberOfDSCSlices[k] = 2;
|
} else {
|
v->NumberOfDSCSlices[k] = 1;
|
}
|
} else {
|
v->NumberOfDSCSlices[k] = 0;
|
}
|
}
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->RequiresDSC[i][k] = false;
|
v->RequiresFEC[i][k] = false;
|
if (v->BlendingAndTiming[k] == k) {
|
if (v->Output[k] == dm_hdmi) {
|
v->RequiresDSC[i][k] = false;
|
v->RequiresFEC[i][k] = false;
|
v->OutputBppPerState[i][k] = TruncToValidBPP(
|
dml_min(600.0, v->PHYCLKPerState[i]) * 10,
|
3,
|
v->HTotal[k],
|
v->HActive[k],
|
v->PixelClockBackEnd[k],
|
v->ForcedOutputLinkBPP[k],
|
false,
|
v->Output[k],
|
v->OutputFormat[k],
|
v->DSCInputBitPerComponent[k],
|
v->NumberOfDSCSlices[k],
|
v->AudioSampleRate[k],
|
v->AudioSampleLayout[k],
|
v->ODMCombineEnablePerState[i][k]);
|
} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
|
if (v->DSCEnable[k] == true) {
|
v->RequiresDSC[i][k] = true;
|
v->LinkDSCEnable = true;
|
if (v->Output[k] == dm_dp) {
|
v->RequiresFEC[i][k] = true;
|
} else {
|
v->RequiresFEC[i][k] = false;
|
}
|
} else {
|
v->RequiresDSC[i][k] = false;
|
v->LinkDSCEnable = false;
|
v->RequiresFEC[i][k] = false;
|
}
|
|
v->Outbpp = BPP_INVALID;
|
if (v->PHYCLKPerState[i] >= 270.0) {
|
v->Outbpp = TruncToValidBPP(
|
(1.0 - v->Downspreading / 100.0) * 2700,
|
v->OutputLinkDPLanes[k],
|
v->HTotal[k],
|
v->HActive[k],
|
v->PixelClockBackEnd[k],
|
v->ForcedOutputLinkBPP[k],
|
v->LinkDSCEnable,
|
v->Output[k],
|
v->OutputFormat[k],
|
v->DSCInputBitPerComponent[k],
|
v->NumberOfDSCSlices[k],
|
v->AudioSampleRate[k],
|
v->AudioSampleLayout[k],
|
v->ODMCombineEnablePerState[i][k]);
|
v->OutputBppPerState[i][k] = v->Outbpp;
|
// TODO: Need some other way to handle this nonsense
|
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
|
}
|
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
|
v->Outbpp = TruncToValidBPP(
|
(1.0 - v->Downspreading / 100.0) * 5400,
|
v->OutputLinkDPLanes[k],
|
v->HTotal[k],
|
v->HActive[k],
|
v->PixelClockBackEnd[k],
|
v->ForcedOutputLinkBPP[k],
|
v->LinkDSCEnable,
|
v->Output[k],
|
v->OutputFormat[k],
|
v->DSCInputBitPerComponent[k],
|
v->NumberOfDSCSlices[k],
|
v->AudioSampleRate[k],
|
v->AudioSampleLayout[k],
|
v->ODMCombineEnablePerState[i][k]);
|
v->OutputBppPerState[i][k] = v->Outbpp;
|
// TODO: Need some other way to handle this nonsense
|
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
|
}
|
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
|
v->Outbpp = TruncToValidBPP(
|
(1.0 - v->Downspreading / 100.0) * 8100,
|
v->OutputLinkDPLanes[k],
|
v->HTotal[k],
|
v->HActive[k],
|
v->PixelClockBackEnd[k],
|
v->ForcedOutputLinkBPP[k],
|
v->LinkDSCEnable,
|
v->Output[k],
|
v->OutputFormat[k],
|
v->DSCInputBitPerComponent[k],
|
v->NumberOfDSCSlices[k],
|
v->AudioSampleRate[k],
|
v->AudioSampleLayout[k],
|
v->ODMCombineEnablePerState[i][k]);
|
if (v->Outbpp == BPP_INVALID && v->ForcedOutputLinkBPP[k] == 0) {
|
//if (v->Outbpp == BPP_INVALID && v->DSCEnabled[k] == dm_dsc_enable_only_if_necessary && v->ForcedOutputLinkBPP[k] == 0) {
|
v->RequiresDSC[i][k] = true;
|
v->LinkDSCEnable = true;
|
if (v->Output[k] == dm_dp) {
|
v->RequiresFEC[i][k] = true;
|
}
|
v->Outbpp = TruncToValidBPP(
|
(1.0 - v->Downspreading / 100.0) * 8100,
|
v->OutputLinkDPLanes[k],
|
v->HTotal[k],
|
v->HActive[k],
|
v->PixelClockBackEnd[k],
|
v->ForcedOutputLinkBPP[k],
|
v->LinkDSCEnable,
|
v->Output[k],
|
v->OutputFormat[k],
|
v->DSCInputBitPerComponent[k],
|
v->NumberOfDSCSlices[k],
|
v->AudioSampleRate[k],
|
v->AudioSampleLayout[k],
|
v->ODMCombineEnablePerState[i][k]);
|
}
|
v->OutputBppPerState[i][k] = v->Outbpp;
|
// TODO: Need some other way to handle this nonsense
|
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
}
|
}
|
} else {
|
v->OutputBppPerState[i][k] = 0;
|
}
|
}
|
}
|
for (i = 0; i < v->soc.num_states; i++) {
|
v->DIOSupport[i] = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi)
|
&& (v->OutputBppPerState[i][k] == 0
|
|| (v->OutputFormat[k] == dm_420 && v->Interlace[k] == true && v->ProgressiveToInterlaceUnitInOPP == true))) {
|
v->DIOSupport[i] = false;
|
}
|
}
|
}
|
|
for (i = 0; i < v->soc.num_states; ++i) {
|
v->ODMCombine4To1SupportCheckOK[i] = true;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->BlendingAndTiming[k] == k && v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
|
&& (v->ODMCombine4To1Supported == false || v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi)) {
|
v->ODMCombine4To1SupportCheckOK[i] = false;
|
}
|
}
|
}
|
|
/* Skip dscclk validation: as long as dispclk is supported, dscclk is also implicitly supported */
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
v->NotEnoughDSCUnits[i] = false;
|
v->TotalDSCUnitsRequired = 0.0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->RequiresDSC[i][k] == true) {
|
if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
|
v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 4.0;
|
} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 2.0;
|
} else {
|
v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 1.0;
|
}
|
}
|
}
|
if (v->TotalDSCUnitsRequired > v->NumberOfDSC) {
|
v->NotEnoughDSCUnits[i] = true;
|
}
|
}
|
/*DSC Delay per state*/
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->OutputBppPerState[i][k] == BPP_INVALID) {
|
v->BPP = 0.0;
|
} else {
|
v->BPP = v->OutputBppPerState[i][k];
|
}
|
if (v->RequiresDSC[i][k] == true && v->BPP != 0.0) {
|
if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
v->DSCDelayPerState[i][k] = dscceComputeDelay(
|
v->DSCInputBitPerComponent[k],
|
v->BPP,
|
dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
|
v->NumberOfDSCSlices[k],
|
v->OutputFormat[k],
|
v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
|
} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
v->DSCDelayPerState[i][k] = 2.0
|
* dscceComputeDelay(
|
v->DSCInputBitPerComponent[k],
|
v->BPP,
|
dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
|
v->NumberOfDSCSlices[k] / 2,
|
v->OutputFormat[k],
|
v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
|
} else {
|
v->DSCDelayPerState[i][k] = 4.0
|
* (dscceComputeDelay(
|
v->DSCInputBitPerComponent[k],
|
v->BPP,
|
dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
|
v->NumberOfDSCSlices[k] / 4,
|
v->OutputFormat[k],
|
v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
|
}
|
v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
|
} else {
|
v->DSCDelayPerState[i][k] = 0.0;
|
}
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
for (m = 0; m <= v->NumberOfActivePlanes - 1; m++) {
|
if (v->BlendingAndTiming[k] == m && v->RequiresDSC[i][m] == true) {
|
v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][m];
|
}
|
}
|
}
|
}
|
|
//Calculate Swath, DET Configuration, DCFCLKDeepSleep
|
//
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->RequiredDPPCLKThisState[k] = v->RequiredDPPCLK[i][j][k];
|
v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
|
v->ODMCombineEnableThisState[k] = v->ODMCombineEnablePerState[i][k];
|
}
|
|
CalculateSwathAndDETConfiguration(
|
false,
|
v->NumberOfActivePlanes,
|
v->DETBufferSizeInKByte,
|
v->MaximumSwathWidthLuma,
|
v->MaximumSwathWidthChroma,
|
v->SourceScan,
|
v->SourcePixelFormat,
|
v->SurfaceTiling,
|
v->ViewportWidth,
|
v->ViewportHeight,
|
v->SurfaceWidthY,
|
v->SurfaceWidthC,
|
v->SurfaceHeightY,
|
v->SurfaceHeightC,
|
v->Read256BlockHeightY,
|
v->Read256BlockHeightC,
|
v->Read256BlockWidthY,
|
v->Read256BlockWidthC,
|
v->ODMCombineEnableThisState,
|
v->BlendingAndTiming,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->BytePerPixelInDETY,
|
v->BytePerPixelInDETC,
|
v->HActive,
|
v->HRatio,
|
v->HRatioChroma,
|
v->NoOfDPPThisState,
|
v->swath_width_luma_ub_this_state,
|
v->swath_width_chroma_ub_this_state,
|
v->SwathWidthYThisState,
|
v->SwathWidthCThisState,
|
v->SwathHeightYThisState,
|
v->SwathHeightCThisState,
|
v->DETBufferSizeYThisState,
|
v->DETBufferSizeCThisState,
|
v->dummystring,
|
&v->ViewportSizeSupport[i][j]);
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->swath_width_luma_ub_all_states[i][j][k] = v->swath_width_luma_ub_this_state[k];
|
v->swath_width_chroma_ub_all_states[i][j][k] = v->swath_width_chroma_ub_this_state[k];
|
v->SwathWidthYAllStates[i][j][k] = v->SwathWidthYThisState[k];
|
v->SwathWidthCAllStates[i][j][k] = v->SwathWidthCThisState[k];
|
v->SwathHeightYAllStates[i][j][k] = v->SwathHeightYThisState[k];
|
v->SwathHeightCAllStates[i][j][k] = v->SwathHeightCThisState[k];
|
v->DETBufferSizeYAllStates[i][j][k] = v->DETBufferSizeYThisState[k];
|
v->DETBufferSizeCAllStates[i][j][k] = v->DETBufferSizeCThisState[k];
|
}
|
|
}
|
}
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->cursor_bw[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0 / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
|
}
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
for (j = 0; j < 2; j++) {
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
|
v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
|
v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
|
v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
|
v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
|
v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
|
v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
|
v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
|
}
|
|
v->TotalNumberOfDCCActiveDPP[i][j] = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->DCCEnable[k] == true) {
|
v->TotalNumberOfDCCActiveDPP[i][j] = v->TotalNumberOfDCCActiveDPP[i][j] + v->NoOfDPP[i][j][k];
|
}
|
}
|
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
|
|| v->SourcePixelFormat[k] == dm_rgbe_alpha) {
|
|
if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
|
v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
|
v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
|
} else {
|
v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
|
v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
|
}
|
|
v->PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
|
mode_lib,
|
v->DCCEnable[k],
|
v->Read256BlockHeightC[k],
|
v->Read256BlockWidthY[k],
|
v->SourcePixelFormat[k],
|
v->SurfaceTiling[k],
|
v->BytePerPixelC[k],
|
v->SourceScan[k],
|
v->SwathWidthCThisState[k],
|
v->ViewportHeightChroma[k],
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->GPUVMMinPageSize,
|
v->HostVMMinPageSize,
|
v->PTEBufferSizeInRequestsForChroma,
|
v->PitchC[k],
|
0.0,
|
&v->MacroTileWidthC[k],
|
&v->MetaRowBytesC,
|
&v->DPTEBytesPerRowC,
|
&v->PTEBufferSizeNotExceededC[i][j][k],
|
&v->dummyinteger7,
|
&v->dpte_row_height_chroma[k],
|
&v->dummyinteger28,
|
&v->dummyinteger26,
|
&v->dummyinteger23,
|
&v->meta_row_height_chroma[k],
|
&v->dummyinteger8,
|
&v->dummyinteger9,
|
&v->dummyinteger19,
|
&v->dummyinteger20,
|
&v->dummyinteger17,
|
&v->dummyinteger10,
|
&v->dummyinteger11);
|
|
v->PrefetchLinesC[i][j][k] = CalculatePrefetchSourceLines(
|
mode_lib,
|
v->VRatioChroma[k],
|
v->VTAPsChroma[k],
|
v->Interlace[k],
|
v->ProgressiveToInterlaceUnitInOPP,
|
v->SwathHeightCThisState[k],
|
v->ViewportYStartC[k],
|
&v->PrefillC[k],
|
&v->MaxNumSwC[k]);
|
} else {
|
v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
|
v->PTEBufferSizeInRequestsForChroma = 0;
|
v->PDEAndMetaPTEBytesPerFrameC = 0.0;
|
v->MetaRowBytesC = 0.0;
|
v->DPTEBytesPerRowC = 0.0;
|
v->PrefetchLinesC[i][j][k] = 0.0;
|
v->PTEBufferSizeNotExceededC[i][j][k] = true;
|
}
|
v->PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
|
mode_lib,
|
v->DCCEnable[k],
|
v->Read256BlockHeightY[k],
|
v->Read256BlockWidthY[k],
|
v->SourcePixelFormat[k],
|
v->SurfaceTiling[k],
|
v->BytePerPixelY[k],
|
v->SourceScan[k],
|
v->SwathWidthYThisState[k],
|
v->ViewportHeight[k],
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->GPUVMMinPageSize,
|
v->HostVMMinPageSize,
|
v->PTEBufferSizeInRequestsForLuma,
|
v->PitchY[k],
|
v->DCCMetaPitchY[k],
|
&v->MacroTileWidthY[k],
|
&v->MetaRowBytesY,
|
&v->DPTEBytesPerRowY,
|
&v->PTEBufferSizeNotExceededY[i][j][k],
|
v->dummyinteger4,
|
&v->dpte_row_height[k],
|
&v->dummyinteger29,
|
&v->dummyinteger27,
|
&v->dummyinteger24,
|
&v->meta_row_height[k],
|
&v->dummyinteger25,
|
&v->dpte_group_bytes[k],
|
&v->dummyinteger21,
|
&v->dummyinteger22,
|
&v->dummyinteger18,
|
&v->dummyinteger5,
|
&v->dummyinteger6);
|
v->PrefetchLinesY[i][j][k] = CalculatePrefetchSourceLines(
|
mode_lib,
|
v->VRatio[k],
|
v->vtaps[k],
|
v->Interlace[k],
|
v->ProgressiveToInterlaceUnitInOPP,
|
v->SwathHeightYThisState[k],
|
v->ViewportYStartY[k],
|
&v->PrefillY[k],
|
&v->MaxNumSwY[k]);
|
v->PDEAndMetaPTEBytesPerFrame[i][j][k] = v->PDEAndMetaPTEBytesPerFrameY + v->PDEAndMetaPTEBytesPerFrameC;
|
v->MetaRowBytes[i][j][k] = v->MetaRowBytesY + v->MetaRowBytesC;
|
v->DPTEBytesPerRow[i][j][k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC;
|
|
CalculateRowBandwidth(
|
v->GPUVMEnable,
|
v->SourcePixelFormat[k],
|
v->VRatio[k],
|
v->VRatioChroma[k],
|
v->DCCEnable[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->MetaRowBytesY,
|
v->MetaRowBytesC,
|
v->meta_row_height[k],
|
v->meta_row_height_chroma[k],
|
v->DPTEBytesPerRowY,
|
v->DPTEBytesPerRowC,
|
v->dpte_row_height[k],
|
v->dpte_row_height_chroma[k],
|
&v->meta_row_bandwidth[i][j][k],
|
&v->dpte_row_bandwidth[i][j][k]);
|
}
|
v->UrgLatency[i] = CalculateUrgentLatency(
|
v->UrgentLatencyPixelDataOnly,
|
v->UrgentLatencyPixelMixedWithVMData,
|
v->UrgentLatencyVMDataOnly,
|
v->DoUrgentLatencyAdjustment,
|
v->UrgentLatencyAdjustmentFabricClockComponent,
|
v->UrgentLatencyAdjustmentFabricClockReference,
|
v->FabricClockPerState[i]);
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
CalculateUrgentBurstFactor(
|
v->swath_width_luma_ub_this_state[k],
|
v->swath_width_chroma_ub_this_state[k],
|
v->DETBufferSizeInKByte,
|
v->SwathHeightYThisState[k],
|
v->SwathHeightCThisState[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->UrgLatency[i],
|
v->CursorBufferSize,
|
v->CursorWidth[k][0],
|
v->CursorBPP[k][0],
|
v->VRatio[k],
|
v->VRatioChroma[k],
|
v->BytePerPixelInDETY[k],
|
v->BytePerPixelInDETC[k],
|
v->DETBufferSizeYThisState[k],
|
v->DETBufferSizeCThisState[k],
|
&v->UrgentBurstFactorCursor[k],
|
&v->UrgentBurstFactorLuma[k],
|
&v->UrgentBurstFactorChroma[k],
|
&NotUrgentLatencyHiding[k]);
|
}
|
|
v->NotUrgentLatencyHiding[i][j] = false;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (NotUrgentLatencyHiding[k]) {
|
v->NotUrgentLatencyHiding[i][j] = true;
|
}
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->VActivePixelBandwidth[i][j][k] = v->ReadBandwidthLuma[k] * v->UrgentBurstFactorLuma[k]
|
+ v->ReadBandwidthChroma[k] * v->UrgentBurstFactorChroma[k];
|
v->VActiveCursorBandwidth[i][j][k] = v->cursor_bw[k] * v->UrgentBurstFactorCursor[k];
|
}
|
|
v->TotalVActivePixelBandwidth[i][j] = 0;
|
v->TotalVActiveCursorBandwidth[i][j] = 0;
|
v->TotalMetaRowBandwidth[i][j] = 0;
|
v->TotalDPTERowBandwidth[i][j] = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->TotalVActivePixelBandwidth[i][j] = v->TotalVActivePixelBandwidth[i][j] + v->VActivePixelBandwidth[i][j][k];
|
v->TotalVActiveCursorBandwidth[i][j] = v->TotalVActiveCursorBandwidth[i][j] + v->VActiveCursorBandwidth[i][j][k];
|
v->TotalMetaRowBandwidth[i][j] = v->TotalMetaRowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->meta_row_bandwidth[i][j][k];
|
v->TotalDPTERowBandwidth[i][j] = v->TotalDPTERowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->dpte_row_bandwidth[i][j][k];
|
}
|
|
CalculateDCFCLKDeepSleep(
|
mode_lib,
|
v->NumberOfActivePlanes,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->VRatio,
|
v->VRatioChroma,
|
v->SwathWidthYThisState,
|
v->SwathWidthCThisState,
|
v->NoOfDPPThisState,
|
v->HRatio,
|
v->HRatioChroma,
|
v->PixelClock,
|
v->PSCL_FACTOR,
|
v->PSCL_FACTOR_CHROMA,
|
v->RequiredDPPCLKThisState,
|
v->ReadBandwidthLuma,
|
v->ReadBandwidthChroma,
|
v->ReturnBusWidth,
|
&v->ProjectedDCFCLKDeepSleep[i][j]);
|
}
|
}
|
|
//Calculate Return BW
|
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->BlendingAndTiming[k] == k) {
|
if (v->WritebackEnable[k] == true) {
|
v->WritebackDelayTime[k] = v->WritebackLatency
|
+ CalculateWriteBackDelay(
|
v->WritebackPixelFormat[k],
|
v->WritebackHRatio[k],
|
v->WritebackVRatio[k],
|
v->WritebackVTaps[k],
|
v->WritebackDestinationWidth[k],
|
v->WritebackDestinationHeight[k],
|
v->WritebackSourceHeight[k],
|
v->HTotal[k]) / v->RequiredDISPCLK[i][j];
|
} else {
|
v->WritebackDelayTime[k] = 0.0;
|
}
|
for (m = 0; m <= v->NumberOfActivePlanes - 1; m++) {
|
if (v->BlendingAndTiming[m] == k && v->WritebackEnable[m] == true) {
|
v->WritebackDelayTime[k] = dml_max(
|
v->WritebackDelayTime[k],
|
v->WritebackLatency
|
+ CalculateWriteBackDelay(
|
v->WritebackPixelFormat[m],
|
v->WritebackHRatio[m],
|
v->WritebackVRatio[m],
|
v->WritebackVTaps[m],
|
v->WritebackDestinationWidth[m],
|
v->WritebackDestinationHeight[m],
|
v->WritebackSourceHeight[m],
|
v->HTotal[m]) / v->RequiredDISPCLK[i][j]);
|
}
|
}
|
}
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
for (m = 0; m <= v->NumberOfActivePlanes - 1; m++) {
|
if (v->BlendingAndTiming[k] == m) {
|
v->WritebackDelayTime[k] = v->WritebackDelayTime[m];
|
}
|
}
|
}
|
v->MaxMaxVStartup[i][j] = 0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->MaximumVStartup[i][j][k] = v->VTotal[k] - v->VActive[k]
|
- dml_max(1.0, dml_ceil(1.0 * v->WritebackDelayTime[k] / (v->HTotal[k] / v->PixelClock[k]), 1.0));
|
v->MaxMaxVStartup[i][j] = dml_max(v->MaxMaxVStartup[i][j], v->MaximumVStartup[i][j][k]);
|
}
|
}
|
}
|
|
ReorderingBytes = v->NumberOfChannels
|
* dml_max3(
|
v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
|
v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
|
v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
|
v->FinalDRAMClockChangeLatency = (v->DRAMClockChangeLatencyOverride > 0 ? v->DRAMClockChangeLatencyOverride : v->DRAMClockChangeLatency);
|
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
|
}
|
}
|
|
if (v->UseMinimumRequiredDCFCLK == true) {
|
UseMinimumDCFCLK(
|
mode_lib,
|
v->MaxInterDCNTileRepeaters,
|
MaxPrefetchMode,
|
v->FinalDRAMClockChangeLatency,
|
v->SREnterPlusExitTime,
|
v->ReturnBusWidth,
|
v->RoundTripPingLatencyCycles,
|
ReorderingBytes,
|
v->PixelChunkSizeInKByte,
|
v->MetaChunkSize,
|
v->GPUVMEnable,
|
v->GPUVMMaxPageTableLevels,
|
v->HostVMEnable,
|
v->NumberOfActivePlanes,
|
v->HostVMMinPageSize,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->DynamicMetadataVMEnabled,
|
v->ImmediateFlipRequirement,
|
v->ProgressiveToInterlaceUnitInOPP,
|
v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly,
|
v->VTotal,
|
v->VActive,
|
v->DynamicMetadataTransmittedBytes,
|
v->DynamicMetadataLinesBeforeActiveRequired,
|
v->Interlace,
|
v->RequiredDPPCLK,
|
v->RequiredDISPCLK,
|
v->UrgLatency,
|
v->NoOfDPP,
|
v->ProjectedDCFCLKDeepSleep,
|
v->MaximumVStartup,
|
v->TotalVActivePixelBandwidth,
|
v->TotalVActiveCursorBandwidth,
|
v->TotalMetaRowBandwidth,
|
v->TotalDPTERowBandwidth,
|
v->TotalNumberOfActiveDPP,
|
v->TotalNumberOfDCCActiveDPP,
|
v->dpte_group_bytes,
|
v->PrefetchLinesY,
|
v->PrefetchLinesC,
|
v->swath_width_luma_ub_all_states,
|
v->swath_width_chroma_ub_all_states,
|
v->BytePerPixelY,
|
v->BytePerPixelC,
|
v->HTotal,
|
v->PixelClock,
|
v->PDEAndMetaPTEBytesPerFrame,
|
v->DPTEBytesPerRow,
|
v->MetaRowBytes,
|
v->DynamicMetadataEnable,
|
v->VActivePixelBandwidth,
|
v->VActiveCursorBandwidth,
|
v->ReadBandwidthLuma,
|
v->ReadBandwidthChroma,
|
v->DCFCLKPerState,
|
v->DCFCLKState);
|
|
if (v->ClampMinDCFCLK) {
|
/* Clamp calculated values to actual minimum */
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
if (v->DCFCLKState[i][j] < mode_lib->soc.min_dcfclk) {
|
v->DCFCLKState[i][j] = mode_lib->soc.min_dcfclk;
|
}
|
}
|
}
|
}
|
}
|
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
v->IdealSDPPortBandwidthPerState[i][j] = dml_min3(
|
v->ReturnBusWidth * v->DCFCLKState[i][j],
|
v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth,
|
v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn);
|
if (v->HostVMEnable != true) {
|
v->ReturnBWPerState[i][j] = v->IdealSDPPortBandwidthPerState[i][j] * v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly
|
/ 100;
|
} else {
|
v->ReturnBWPerState[i][j] = v->IdealSDPPortBandwidthPerState[i][j]
|
* v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100;
|
}
|
}
|
}
|
|
//Re-ordering Buffer Support Check
|
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
if ((v->ROBBufferSizeInKByte - v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
|
> (v->RoundTripPingLatencyCycles + 32) / v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
|
v->ROBSupport[i][j] = true;
|
} else {
|
v->ROBSupport[i][j] = false;
|
}
|
}
|
}
|
|
//Vertical Active BW support check
|
|
MaxTotalVActiveRDBandwidth = 0;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
|
}
|
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
v->MaxTotalVerticalActiveAvailableBandwidth[i][j] = dml_min(
|
v->IdealSDPPortBandwidthPerState[i][j] * v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100,
|
v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth * v->MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation
|
/ 100);
|
if (MaxTotalVActiveRDBandwidth <= v->MaxTotalVerticalActiveAvailableBandwidth[i][j]) {
|
v->TotalVerticalActiveBandwidthSupport[i][j] = true;
|
} else {
|
v->TotalVerticalActiveBandwidthSupport[i][j] = false;
|
}
|
}
|
}
|
|
//Prefetch Check
|
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
int NextPrefetchModeState = MinPrefetchMode;
|
|
v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep[i][j];
|
|
v->BandwidthWithoutPrefetchSupported[i][j] = true;
|
if (v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j] + v->TotalDPTERowBandwidth[i][j]
|
> v->ReturnBWPerState[i][j] || v->NotUrgentLatencyHiding[i][j]) {
|
v->BandwidthWithoutPrefetchSupported[i][j] = false;
|
}
|
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
|
v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
|
v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
|
v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
|
v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
|
v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
|
v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
|
v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
|
v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
|
v->ODMCombineEnabled[k] = v->ODMCombineEnablePerState[i][k];
|
}
|
|
v->ExtraLatency = CalculateExtraLatency(
|
v->RoundTripPingLatencyCycles,
|
ReorderingBytes,
|
v->DCFCLKState[i][j],
|
v->TotalNumberOfActiveDPP[i][j],
|
v->PixelChunkSizeInKByte,
|
v->TotalNumberOfDCCActiveDPP[i][j],
|
v->MetaChunkSize,
|
v->ReturnBWPerState[i][j],
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->NumberOfActivePlanes,
|
v->NoOfDPPThisState,
|
v->dpte_group_bytes,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
v->HostVMMinPageSize,
|
v->HostVMMaxNonCachedPageTableLevels);
|
|
v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
|
do {
|
v->PrefetchModePerState[i][j] = NextPrefetchModeState;
|
v->MaxVStartup = v->NextMaxVStartup;
|
|
v->TWait = CalculateTWait(v->PrefetchModePerState[i][j], v->FinalDRAMClockChangeLatency, v->UrgLatency[i], v->SREnterPlusExitTime);
|
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
Pipe myPipe = { 0 };
|
|
myPipe.DPPCLK = v->RequiredDPPCLK[i][j][k];
|
myPipe.DISPCLK = v->RequiredDISPCLK[i][j];
|
myPipe.PixelClock = v->PixelClock[k];
|
myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j];
|
myPipe.DPPPerPlane = v->NoOfDPP[i][j][k];
|
myPipe.ScalerEnabled = v->ScalerEnabled[k];
|
myPipe.SourceScan = v->SourceScan[k];
|
myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k];
|
myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k];
|
myPipe.BlockWidth256BytesC = v->Read256BlockWidthC[k];
|
myPipe.BlockHeight256BytesC = v->Read256BlockHeightC[k];
|
myPipe.InterlaceEnable = v->Interlace[k];
|
myPipe.NumberOfCursors = v->NumberOfCursors[k];
|
myPipe.VBlank = v->VTotal[k] - v->VActive[k];
|
myPipe.HTotal = v->HTotal[k];
|
myPipe.DCCEnable = v->DCCEnable[k];
|
myPipe.ODMCombineEnabled = !!v->ODMCombineEnabled[k];
|
|
v->NoTimeForPrefetch[i][j][k] = CalculatePrefetchSchedule(
|
mode_lib,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
&myPipe,
|
v->DSCDelayPerState[i][k],
|
v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
|
v->DPPCLKDelaySCL,
|
v->DPPCLKDelaySCLLBOnly,
|
v->DPPCLKDelayCNVCCursor,
|
v->DISPCLKDelaySubtotal,
|
v->SwathWidthYThisState[k] / v->HRatio[k],
|
v->OutputFormat[k],
|
v->MaxInterDCNTileRepeaters,
|
dml_min(v->MaxVStartup, v->MaximumVStartup[i][j][k]),
|
v->MaximumVStartup[i][j][k],
|
v->GPUVMMaxPageTableLevels,
|
v->GPUVMEnable,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->HostVMMinPageSize,
|
v->DynamicMetadataEnable[k],
|
v->DynamicMetadataVMEnabled,
|
v->DynamicMetadataLinesBeforeActiveRequired[k],
|
v->DynamicMetadataTransmittedBytes[k],
|
v->UrgLatency[i],
|
v->ExtraLatency,
|
v->TimeCalc,
|
v->PDEAndMetaPTEBytesPerFrame[i][j][k],
|
v->MetaRowBytes[i][j][k],
|
v->DPTEBytesPerRow[i][j][k],
|
v->PrefetchLinesY[i][j][k],
|
v->SwathWidthYThisState[k],
|
v->BytePerPixelY[k],
|
v->PrefillY[k],
|
v->MaxNumSwY[k],
|
v->PrefetchLinesC[i][j][k],
|
v->SwathWidthCThisState[k],
|
v->BytePerPixelC[k],
|
v->PrefillC[k],
|
v->MaxNumSwC[k],
|
v->swath_width_luma_ub_this_state[k],
|
v->swath_width_chroma_ub_this_state[k],
|
v->SwathHeightYThisState[k],
|
v->SwathHeightCThisState[k],
|
v->TWait,
|
v->ProgressiveToInterlaceUnitInOPP,
|
&v->DSTXAfterScaler[k],
|
&v->DSTYAfterScaler[k],
|
&v->LineTimesForPrefetch[k],
|
&v->PrefetchBW[k],
|
&v->LinesForMetaPTE[k],
|
&v->LinesForMetaAndDPTERow[k],
|
&v->VRatioPreY[i][j][k],
|
&v->VRatioPreC[i][j][k],
|
&v->RequiredPrefetchPixelDataBWLuma[i][j][k],
|
&v->RequiredPrefetchPixelDataBWChroma[i][j][k],
|
&v->NoTimeForDynamicMetadata[i][j][k],
|
&v->Tno_bw[k],
|
&v->prefetch_vmrow_bw[k],
|
&v->Tdmdl_vm[k],
|
&v->Tdmdl[k],
|
&v->VUpdateOffsetPix[k],
|
&v->VUpdateWidthPix[k],
|
&v->VReadyOffsetPix[k]);
|
}
|
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
CalculateUrgentBurstFactor(
|
v->swath_width_luma_ub_this_state[k],
|
v->swath_width_chroma_ub_this_state[k],
|
v->DETBufferSizeInKByte,
|
v->SwathHeightYThisState[k],
|
v->SwathHeightCThisState[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->UrgentLatency,
|
v->CursorBufferSize,
|
v->CursorWidth[k][0],
|
v->CursorBPP[k][0],
|
v->VRatioPreY[i][j][k],
|
v->VRatioPreC[i][j][k],
|
v->BytePerPixelInDETY[k],
|
v->BytePerPixelInDETC[k],
|
v->DETBufferSizeYThisState[k],
|
v->DETBufferSizeCThisState[k],
|
&v->UrgentBurstFactorCursorPre[k],
|
&v->UrgentBurstFactorLumaPre[k],
|
&v->UrgentBurstFactorChroma[k],
|
&v->NoUrgentLatencyHidingPre[k]);
|
}
|
|
v->MaximumReadBandwidthWithPrefetch = 0.0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0 / (v->HTotal[k] / v->PixelClock[k])
|
* v->VRatioPreY[i][j][k];
|
|
v->MaximumReadBandwidthWithPrefetch = v->MaximumReadBandwidthWithPrefetch
|
+ dml_max4(
|
v->VActivePixelBandwidth[i][j][k],
|
v->VActiveCursorBandwidth[i][j][k]
|
+ v->NoOfDPP[i][j][k] * (v->meta_row_bandwidth[i][j][k] + v->dpte_row_bandwidth[i][j][k]),
|
v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
|
v->NoOfDPP[i][j][k]
|
* (v->RequiredPrefetchPixelDataBWLuma[i][j][k] * v->UrgentBurstFactorLumaPre[k]
|
+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
|
* v->UrgentBurstFactorChromaPre[k])
|
+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
|
}
|
|
v->NotEnoughUrgentLatencyHidingPre = false;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->NoUrgentLatencyHidingPre[k] == true) {
|
v->NotEnoughUrgentLatencyHidingPre = true;
|
}
|
}
|
|
v->PrefetchSupported[i][j] = true;
|
if (v->BandwidthWithoutPrefetchSupported[i][j] == false || v->MaximumReadBandwidthWithPrefetch > v->ReturnBWPerState[i][j]
|
|| v->NotEnoughUrgentLatencyHidingPre == 1) {
|
v->PrefetchSupported[i][j] = false;
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->LineTimesForPrefetch[k] < 2.0 || v->LinesForMetaPTE[k] >= 32.0 || v->LinesForMetaAndDPTERow[k] >= 16.0
|
|| v->NoTimeForPrefetch[i][j][k] == true) {
|
v->PrefetchSupported[i][j] = false;
|
}
|
}
|
|
v->DynamicMetadataSupported[i][j] = true;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->NoTimeForDynamicMetadata[i][j][k] == true) {
|
v->DynamicMetadataSupported[i][j] = false;
|
}
|
}
|
|
v->VRatioInPrefetchSupported[i][j] = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->VRatioPreY[i][j][k] > 4.0 || v->VRatioPreC[i][j][k] > 4.0 || v->NoTimeForPrefetch[i][j][k] == true) {
|
v->VRatioInPrefetchSupported[i][j] = false;
|
}
|
}
|
v->AnyLinesForVMOrRowTooLarge = false;
|
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
if (v->LinesForMetaAndDPTERow[k] >= 16 || v->LinesForMetaPTE[k] >= 32) {
|
v->AnyLinesForVMOrRowTooLarge = true;
|
}
|
}
|
|
if (v->PrefetchSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true) {
|
v->BandwidthAvailableForImmediateFlip = v->ReturnBWPerState[i][j];
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
|
- dml_max(
|
v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k],
|
v->NoOfDPP[i][j][k]
|
* (v->RequiredPrefetchPixelDataBWLuma[i][j][k] * v->UrgentBurstFactorLumaPre[k]
|
+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
|
* v->UrgentBurstFactorChromaPre[k])
|
+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
|
}
|
v->TotImmediateFlipBytes = 0.0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->TotImmediateFlipBytes = v->TotImmediateFlipBytes + v->NoOfDPP[i][j][k] * v->PDEAndMetaPTEBytesPerFrame[i][j][k]
|
+ v->MetaRowBytes[i][j][k] + v->DPTEBytesPerRow[i][j][k];
|
}
|
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
CalculateFlipSchedule(
|
mode_lib,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
v->ExtraLatency,
|
v->UrgLatency[i],
|
v->GPUVMMaxPageTableLevels,
|
v->HostVMEnable,
|
v->HostVMMaxNonCachedPageTableLevels,
|
v->GPUVMEnable,
|
v->HostVMMinPageSize,
|
v->PDEAndMetaPTEBytesPerFrame[i][j][k],
|
v->MetaRowBytes[i][j][k],
|
v->DPTEBytesPerRow[i][j][k],
|
v->BandwidthAvailableForImmediateFlip,
|
v->TotImmediateFlipBytes,
|
v->SourcePixelFormat[k],
|
v->HTotal[k] / v->PixelClock[k],
|
v->VRatio[k],
|
v->VRatioChroma[k],
|
v->Tno_bw[k],
|
v->DCCEnable[k],
|
v->dpte_row_height[k],
|
v->meta_row_height[k],
|
v->dpte_row_height_chroma[k],
|
v->meta_row_height_chroma[k],
|
&v->DestinationLinesToRequestVMInImmediateFlip[k],
|
&v->DestinationLinesToRequestRowInImmediateFlip[k],
|
&v->final_flip_bw[k],
|
&v->ImmediateFlipSupportedForPipe[k]);
|
}
|
v->total_dcn_read_bw_with_flip = 0.0;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
|
+ dml_max3(
|
v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
|
v->NoOfDPP[i][j][k] * v->final_flip_bw[k] + v->VActivePixelBandwidth[i][j][k]
|
+ v->VActiveCursorBandwidth[i][j][k],
|
v->NoOfDPP[i][j][k]
|
* (v->final_flip_bw[k]
|
+ v->RequiredPrefetchPixelDataBWLuma[i][j][k]
|
* v->UrgentBurstFactorLumaPre[k]
|
+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
|
* v->UrgentBurstFactorChromaPre[k])
|
+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
|
}
|
v->ImmediateFlipSupportedForState[i][j] = true;
|
if (v->total_dcn_read_bw_with_flip > v->ReturnBWPerState[i][j]) {
|
v->ImmediateFlipSupportedForState[i][j] = false;
|
}
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->ImmediateFlipSupportedForPipe[k] == false) {
|
v->ImmediateFlipSupportedForState[i][j] = false;
|
}
|
}
|
} else {
|
v->ImmediateFlipSupportedForState[i][j] = false;
|
}
|
if (v->MaxVStartup <= 13 || v->AnyLinesForVMOrRowTooLarge == false) {
|
v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
|
NextPrefetchModeState = NextPrefetchModeState + 1;
|
} else {
|
v->NextMaxVStartup = v->NextMaxVStartup - 1;
|
}
|
} while (!((v->PrefetchSupported[i][j] == true && v->DynamicMetadataSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true
|
&& ((v->HostVMEnable == false && v->ImmediateFlipRequirement != dm_immediate_flip_required)
|
|| v->ImmediateFlipSupportedForState[i][j] == true))
|
|| (v->NextMaxVStartup == v->MaxMaxVStartup[i][j] && NextPrefetchModeState > MaxPrefetchMode)));
|
|
CalculateWatermarksAndDRAMSpeedChangeSupport(
|
mode_lib,
|
v->PrefetchModePerState[i][j],
|
v->NumberOfActivePlanes,
|
v->MaxLineBufferLines,
|
v->LineBufferSize,
|
v->DPPOutputBufferPixels,
|
v->DETBufferSizeInKByte,
|
v->WritebackInterfaceBufferSize,
|
v->DCFCLKState[i][j],
|
v->ReturnBWPerState[i][j],
|
v->GPUVMEnable,
|
v->dpte_group_bytes,
|
v->MetaChunkSize,
|
v->UrgLatency[i],
|
v->ExtraLatency,
|
v->WritebackLatency,
|
v->WritebackChunkSize,
|
v->SOCCLKPerState[i],
|
v->FinalDRAMClockChangeLatency,
|
v->SRExitTime,
|
v->SREnterPlusExitTime,
|
v->ProjectedDCFCLKDeepSleep[i][j],
|
v->NoOfDPPThisState,
|
v->DCCEnable,
|
v->RequiredDPPCLKThisState,
|
v->DETBufferSizeYThisState,
|
v->DETBufferSizeCThisState,
|
v->SwathHeightYThisState,
|
v->SwathHeightCThisState,
|
v->LBBitPerPixel,
|
v->SwathWidthYThisState,
|
v->SwathWidthCThisState,
|
v->HRatio,
|
v->HRatioChroma,
|
v->vtaps,
|
v->VTAPsChroma,
|
v->VRatio,
|
v->VRatioChroma,
|
v->HTotal,
|
v->PixelClock,
|
v->BlendingAndTiming,
|
v->BytePerPixelInDETY,
|
v->BytePerPixelInDETC,
|
v->DSTXAfterScaler,
|
v->DSTYAfterScaler,
|
v->WritebackEnable,
|
v->WritebackPixelFormat,
|
v->WritebackDestinationWidth,
|
v->WritebackDestinationHeight,
|
v->WritebackSourceHeight,
|
&v->DRAMClockChangeSupport[i][j],
|
&v->UrgentWatermark,
|
&v->WritebackUrgentWatermark,
|
&v->DRAMClockChangeWatermark,
|
&v->WritebackDRAMClockChangeWatermark,
|
&v->StutterExitWatermark,
|
&v->StutterEnterPlusExitWatermark,
|
&v->MinActiveDRAMClockChangeLatencySupported);
|
}
|
}
|
|
/*PTE Buffer Size Check*/
|
|
for (i = 0; i < v->soc.num_states; i++) {
|
for (j = 0; j < 2; j++) {
|
v->PTEBufferSizeNotExceeded[i][j] = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->PTEBufferSizeNotExceededY[i][j][k] == false || v->PTEBufferSizeNotExceededC[i][j][k] == false) {
|
v->PTEBufferSizeNotExceeded[i][j] = false;
|
}
|
}
|
}
|
}
|
/*Cursor Support Check*/
|
|
v->CursorSupport = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->CursorWidth[k][0] > 0.0) {
|
if (v->CursorBPP[k][0] == 64 && v->Cursor64BppSupport == false) {
|
v->CursorSupport = false;
|
}
|
}
|
}
|
/*Valid Pitch Check*/
|
|
v->PitchSupport = true;
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->AlignedYPitch[k] = dml_ceil(dml_max(v->PitchY[k], v->SurfaceWidthY[k]), v->MacroTileWidthY[k]);
|
if (v->DCCEnable[k] == true) {
|
v->AlignedDCCMetaPitchY[k] = dml_ceil(dml_max(v->DCCMetaPitchY[k], v->SurfaceWidthY[k]), 64.0 * v->Read256BlockWidthY[k]);
|
} else {
|
v->AlignedDCCMetaPitchY[k] = v->DCCMetaPitchY[k];
|
}
|
if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32 && v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_mono_16
|
&& v->SourcePixelFormat[k] != dm_rgbe && v->SourcePixelFormat[k] != dm_mono_8) {
|
v->AlignedCPitch[k] = dml_ceil(dml_max(v->PitchC[k], v->SurfaceWidthC[k]), v->MacroTileWidthC[k]);
|
if (v->DCCEnable[k] == true) {
|
v->AlignedDCCMetaPitchC[k] = dml_ceil(dml_max(v->DCCMetaPitchC[k], v->SurfaceWidthC[k]), 64.0 * v->Read256BlockWidthC[k]);
|
} else {
|
v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
|
}
|
} else {
|
v->AlignedCPitch[k] = v->PitchC[k];
|
v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
|
}
|
if (v->AlignedYPitch[k] > v->PitchY[k] || v->AlignedCPitch[k] > v->PitchC[k] || v->AlignedDCCMetaPitchY[k] > v->DCCMetaPitchY[k]
|
|| v->AlignedDCCMetaPitchC[k] > v->DCCMetaPitchC[k]) {
|
v->PitchSupport = false;
|
}
|
}
|
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
if (v->ViewportWidth[k] > v->SurfaceWidthY[k] || v->ViewportHeight[k] > v->SurfaceHeightY[k])
|
ViewportExceedsSurface = true;
|
|
if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32 && v->SourcePixelFormat[k] != dm_444_16
|
&& v->SourcePixelFormat[k] != dm_444_8 && v->SourcePixelFormat[k] != dm_rgbe) {
|
if (v->ViewportWidthChroma[k] > v->SurfaceWidthC[k] || v->ViewportHeightChroma[k] > v->SurfaceHeightC[k]) {
|
ViewportExceedsSurface = true;
|
}
|
}
|
}
|
/*Mode Support, Voltage State and SOC Configuration*/
|
|
for (i = v->soc.num_states - 1; i >= 0; i--) {
|
for (j = 0; j < 2; j++) {
|
if (v->ScaleRatioAndTapsSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 && v->ViewportSizeSupport[i][j] == 1
|
&& v->DIOSupport[i] == 1 && v->ODMCombine4To1SupportCheckOK[i] == 1
|
&& v->NotEnoughDSCUnits[i] == 0
|
&& v->DTBCLKRequiredMoreThanSupported[i] == 0
|
&& v->ROBSupport[i][j] == 1 && v->DISPCLK_DPPCLK_Support[i][j] == 1 && v->TotalAvailablePipesSupport[i][j] == 1
|
&& EnoughWritebackUnits == 1 && WritebackModeSupport == 1
|
&& v->WritebackLatencySupport == 1 && v->WritebackScaleRatioAndTapsSupport == 1 && v->CursorSupport == 1 && v->PitchSupport == 1
|
&& ViewportExceedsSurface == 0 && v->PrefetchSupported[i][j] == 1 && v->DynamicMetadataSupported[i][j] == 1
|
&& v->TotalVerticalActiveBandwidthSupport[i][j] == 1 && v->VRatioInPrefetchSupported[i][j] == 1
|
&& v->PTEBufferSizeNotExceeded[i][j] == 1 && v->NonsupportedDSCInputBPC == 0
|
&& ((v->HostVMEnable == 0 && v->ImmediateFlipRequirement != dm_immediate_flip_required)
|
|| v->ImmediateFlipSupportedForState[i][j] == true)) {
|
v->ModeSupport[i][j] = true;
|
} else {
|
v->ModeSupport[i][j] = false;
|
}
|
}
|
}
|
{
|
unsigned int MaximumMPCCombine = 0;
|
for (i = v->soc.num_states; i >= 0; i--) {
|
if (i == v->soc.num_states || v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true) {
|
v->VoltageLevel = i;
|
v->ModeIsSupported = v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true;
|
if (v->ModeSupport[i][1] == true) {
|
MaximumMPCCombine = 1;
|
} else {
|
MaximumMPCCombine = 0;
|
}
|
}
|
}
|
v->ImmediateFlipSupport = v->ImmediateFlipSupportedForState[v->VoltageLevel][MaximumMPCCombine];
|
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
v->MPCCombineEnable[k] = v->MPCCombine[v->VoltageLevel][MaximumMPCCombine][k];
|
v->DPPPerPlane[k] = v->NoOfDPP[v->VoltageLevel][MaximumMPCCombine][k];
|
}
|
v->DCFCLK = v->DCFCLKState[v->VoltageLevel][MaximumMPCCombine];
|
v->DRAMSpeed = v->DRAMSpeedPerState[v->VoltageLevel];
|
v->FabricClock = v->FabricClockPerState[v->VoltageLevel];
|
v->SOCCLK = v->SOCCLKPerState[v->VoltageLevel];
|
v->ReturnBW = v->ReturnBWPerState[v->VoltageLevel][MaximumMPCCombine];
|
v->maxMpcComb = MaximumMPCCombine;
|
}
|
}
|
|
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 WritebackInterfaceBufferSize,
|
double DCFCLK,
|
double ReturnBW,
|
bool GPUVMEnable,
|
unsigned int dpte_group_bytes[],
|
unsigned int MetaChunkSize,
|
double UrgentLatency,
|
double ExtraLatency,
|
double WritebackLatency,
|
double WritebackChunkSize,
|
double SOCCLK,
|
double DRAMClockChangeLatency,
|
double SRExitTime,
|
double SREnterPlusExitTime,
|
double DCFCLKDeepSleep,
|
unsigned int DPPPerPlane[],
|
bool DCCEnable[],
|
double DPPCLK[],
|
double DETBufferSizeY[],
|
double DETBufferSizeC[],
|
unsigned int SwathHeightY[],
|
unsigned int SwathHeightC[],
|
unsigned int LBBitPerPixel[],
|
double SwathWidthY[],
|
double SwathWidthC[],
|
double HRatio[],
|
double HRatioChroma[],
|
unsigned int vtaps[],
|
unsigned int VTAPsChroma[],
|
double VRatio[],
|
double VRatioChroma[],
|
unsigned int HTotal[],
|
double PixelClock[],
|
unsigned int BlendingAndTiming[],
|
double BytePerPixelDETY[],
|
double BytePerPixelDETC[],
|
double DSTXAfterScaler[],
|
double DSTYAfterScaler[],
|
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 = 0;
|
double EffectiveLBLatencyHidingC = 0;
|
double LinesInDETY[DC__NUM_DPP__MAX] = { 0 };
|
double LinesInDETC = 0;
|
unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX] = { 0 };
|
unsigned int LinesInDETCRoundedDownToSwath = 0;
|
double FullDETBufferingTimeY[DC__NUM_DPP__MAX] = { 0 };
|
double FullDETBufferingTimeC = 0;
|
double ActiveDRAMClockChangeLatencyMarginY = 0;
|
double ActiveDRAMClockChangeLatencyMarginC = 0;
|
double WritebackDRAMClockChangeLatencyMargin = 0;
|
double PlaneWithMinActiveDRAMClockChangeMargin = 0;
|
double SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 0;
|
double FullDETBufferingTimeYStutterCriticalPlane = 0;
|
double TimeToFinishSwathTransferStutterCriticalPlane = 0;
|
double WritebackDRAMClockChangeLatencyHiding = 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];
|
}
|
}
|
|
*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] / (SwathWidthC[k] / dml_max(HRatioChroma[k], 1.0)), 1)) - (VTAPsChroma[k] - 1);
|
|
EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY / VRatio[k] * (HTotal[k] / PixelClock[k]);
|
|
EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC / VRatioChroma[k] * (HTotal[k] / PixelClock[k]);
|
|
LinesInDETY[k] = (double) DETBufferSizeY[k] / 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 = mode_lib->vba.DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k];
|
LinesInDETCRoundedDownToSwath = dml_floor(LinesInDETC, SwathHeightC[k]);
|
FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath * (HTotal[k] / PixelClock[k]) / VRatioChroma[k];
|
} else {
|
LinesInDETC = 0;
|
FullDETBufferingTimeC = 999999;
|
}
|
|
ActiveDRAMClockChangeLatencyMarginY = EffectiveLBLatencyHidingY + FullDETBufferingTimeY[k] - *UrgentWatermark - (HTotal[k] / PixelClock[k]) * (DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) - *DRAMClockChangeWatermark;
|
|
if (NumberOfActivePlanes > 1) {
|
ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY - (1 - 1.0 / NumberOfActivePlanes) * SwathHeightY[k] * HTotal[k] / PixelClock[k] / VRatio[k];
|
}
|
|
if (BytePerPixelDETC[k] > 0) {
|
ActiveDRAMClockChangeLatencyMarginC = EffectiveLBLatencyHidingC + FullDETBufferingTimeC - *UrgentWatermark - (HTotal[k] / PixelClock[k]) * (DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) - *DRAMClockChangeWatermark;
|
|
if (NumberOfActivePlanes > 1) {
|
ActiveDRAMClockChangeLatencyMarginC = ActiveDRAMClockChangeLatencyMarginC - (1 - 1.0 / NumberOfActivePlanes) * SwathHeightC[k] * HTotal[k] / PixelClock[k] / VRatioChroma[k];
|
}
|
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, ActiveDRAMClockChangeLatencyMarginC);
|
} else {
|
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = ActiveDRAMClockChangeLatencyMarginY;
|
}
|
|
if (WritebackEnable[k] == true) {
|
|
WritebackDRAMClockChangeLatencyHiding = WritebackInterfaceBufferSize * 1024 / (WritebackDestinationWidth[k] * WritebackDestinationHeight[k] / (WritebackSourceHeight[k] * HTotal[k] / PixelClock[k]) * 4);
|
if (WritebackPixelFormat[k] == dm_444_64) {
|
WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding / 2;
|
}
|
if (mode_lib->vba.WritebackConfiguration == dm_whole_buffer_for_single_stream_interleave) {
|
WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding * 2;
|
}
|
WritebackDRAMClockChangeLatencyMargin = WritebackDRAMClockChangeLatencyHiding - mode_lib->vba.WritebackDRAMClockChangeWatermark;
|
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k], WritebackDRAMClockChangeLatencyMargin);
|
}
|
}
|
|
mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
|
PlaneWithMinActiveDRAMClockChangeMargin = 0;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] < mode_lib->vba.MinActiveDRAMClockChangeMargin) {
|
mode_lib->vba.MinActiveDRAMClockChangeMargin = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
|
if (BlendingAndTiming[k] == k) {
|
PlaneWithMinActiveDRAMClockChangeMargin = k;
|
} else {
|
for (j = 0; j < NumberOfActivePlanes; ++j) {
|
if (BlendingAndTiming[k] == j) {
|
PlaneWithMinActiveDRAMClockChangeMargin = j;
|
}
|
}
|
}
|
}
|
}
|
|
*MinActiveDRAMClockChangeLatencySupported = mode_lib->vba.MinActiveDRAMClockChangeMargin + DRAMClockChangeLatency;
|
|
SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (BlendingAndTiming[k] == k)) && !(BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin) && mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] < SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
|
SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
|
}
|
}
|
|
mode_lib->vba.TotalNumberOfActiveOTG = 0;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (BlendingAndTiming[k] == k) {
|
mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG + 1;
|
}
|
}
|
|
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) {
|
*DRAMClockChangeSupport = dm_dram_clock_change_vactive;
|
} else if (((mode_lib->vba.SynchronizedVBlank == true || mode_lib->vba.TotalNumberOfActiveOTG == 1 || SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0)) {
|
*DRAMClockChangeSupport = dm_dram_clock_change_vblank;
|
} else {
|
*DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
|
}
|
|
FullDETBufferingTimeYStutterCriticalPlane = FullDETBufferingTimeY[0];
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (FullDETBufferingTimeY[k] <= FullDETBufferingTimeYStutterCriticalPlane) {
|
FullDETBufferingTimeYStutterCriticalPlane = FullDETBufferingTimeY[k];
|
TimeToFinishSwathTransferStutterCriticalPlane = (SwathHeightY[k] - (LinesInDETY[k] - LinesInDETYRoundedDownToSwath[k])) * (HTotal[k] / PixelClock[k]) / VRatio[k];
|
}
|
}
|
|
*StutterExitWatermark = SRExitTime + ExtraLatency + 10 / DCFCLKDeepSleep;
|
*StutterEnterPlusExitWatermark = dml_max(SREnterPlusExitTime + ExtraLatency + 10 / DCFCLKDeepSleep, TimeToFinishSwathTransferStutterCriticalPlane);
|
|
}
|
|
static void CalculateDCFCLKDeepSleep(
|
struct display_mode_lib *mode_lib,
|
unsigned int NumberOfActivePlanes,
|
int BytePerPixelY[],
|
int BytePerPixelC[],
|
double VRatio[],
|
double VRatioChroma[],
|
double SwathWidthY[],
|
double SwathWidthC[],
|
unsigned int DPPPerPlane[],
|
double HRatio[],
|
double HRatioChroma[],
|
double PixelClock[],
|
double PSCL_THROUGHPUT[],
|
double PSCL_THROUGHPUT_CHROMA[],
|
double DPPCLK[],
|
double ReadBandwidthLuma[],
|
double ReadBandwidthChroma[],
|
int ReturnBusWidth,
|
double *DCFCLKDeepSleep)
|
{
|
double DisplayPipeLineDeliveryTimeLuma = 0;
|
double DisplayPipeLineDeliveryTimeChroma = 0;
|
unsigned int k;
|
double ReadBandwidth = 0.0;
|
|
//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 (BytePerPixelC[k] == 0) {
|
DisplayPipeLineDeliveryTimeChroma = 0;
|
} else {
|
if (VRatioChroma[k] <= 1) {
|
DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
|
} else {
|
DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
|
}
|
}
|
|
if (BytePerPixelC[k] > 0) {
|
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(1.1 * SwathWidthY[k] * BytePerPixelY[k] / 32.0 / DisplayPipeLineDeliveryTimeLuma, 1.1 * SwathWidthC[k] * BytePerPixelC[k] / 32.0 / DisplayPipeLineDeliveryTimeChroma);
|
} else {
|
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = 1.1 * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma;
|
}
|
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(mode_lib->vba.DCFCLKDeepSleepPerPlane[k], PixelClock[k] / 16);
|
|
}
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
|
}
|
|
*DCFCLKDeepSleep = dml_max(8.0, ReadBandwidth / ReturnBusWidth);
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
*DCFCLKDeepSleep = dml_max(*DCFCLKDeepSleep, mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
|
}
|
}
|
|
static void CalculateUrgentBurstFactor(
|
long swath_width_luma_ub,
|
long swath_width_chroma_ub,
|
unsigned int DETBufferSizeInKByte,
|
unsigned int SwathHeightY,
|
unsigned int SwathHeightC,
|
double LineTime,
|
double UrgentLatency,
|
double CursorBufferSize,
|
unsigned int CursorWidth,
|
unsigned int CursorBPP,
|
double VRatio,
|
double VRatioC,
|
double BytePerPixelInDETY,
|
double BytePerPixelInDETC,
|
double DETBufferSizeY,
|
double DETBufferSizeC,
|
double *UrgentBurstFactorCursor,
|
double *UrgentBurstFactorLuma,
|
double *UrgentBurstFactorChroma,
|
bool *NotEnoughUrgentLatencyHiding)
|
{
|
double LinesInDETLuma = 0;
|
double LinesInDETChroma = 0;
|
unsigned int LinesInCursorBuffer = 0;
|
double CursorBufferSizeInTime = 0;
|
double DETBufferSizeInTimeLuma = 0;
|
double DETBufferSizeInTimeChroma = 0;
|
|
*NotEnoughUrgentLatencyHiding = 0;
|
|
if (CursorWidth > 0) {
|
LinesInCursorBuffer = 1 << (unsigned int) dml_floor(dml_log2(CursorBufferSize * 1024.0 / (CursorWidth * CursorBPP / 8.0)), 1.0);
|
if (VRatio > 0) {
|
CursorBufferSizeInTime = LinesInCursorBuffer * LineTime / VRatio;
|
if (CursorBufferSizeInTime - UrgentLatency <= 0) {
|
*NotEnoughUrgentLatencyHiding = 1;
|
*UrgentBurstFactorCursor = 0;
|
} else {
|
*UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency);
|
}
|
} else {
|
*UrgentBurstFactorCursor = 1;
|
}
|
}
|
|
LinesInDETLuma = DETBufferSizeY / BytePerPixelInDETY / swath_width_luma_ub;
|
if (VRatio > 0) {
|
DETBufferSizeInTimeLuma = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
|
if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
|
*NotEnoughUrgentLatencyHiding = 1;
|
*UrgentBurstFactorLuma = 0;
|
} else {
|
*UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency);
|
}
|
} else {
|
*UrgentBurstFactorLuma = 1;
|
}
|
|
if (BytePerPixelInDETC > 0) {
|
LinesInDETChroma = DETBufferSizeC / BytePerPixelInDETC / swath_width_chroma_ub;
|
if (VRatio > 0) {
|
DETBufferSizeInTimeChroma = dml_floor(LinesInDETChroma, SwathHeightC) * LineTime / VRatio;
|
if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
|
*NotEnoughUrgentLatencyHiding = 1;
|
*UrgentBurstFactorChroma = 0;
|
} else {
|
*UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency);
|
}
|
} else {
|
*UrgentBurstFactorChroma = 1;
|
}
|
}
|
}
|
|
static void CalculatePixelDeliveryTimes(
|
unsigned int NumberOfActivePlanes,
|
double VRatio[],
|
double VRatioChroma[],
|
double VRatioPrefetchY[],
|
double VRatioPrefetchC[],
|
unsigned int swath_width_luma_ub[],
|
unsigned int swath_width_chroma_ub[],
|
unsigned int DPPPerPlane[],
|
double HRatio[],
|
double HRatioChroma[],
|
double PixelClock[],
|
double PSCL_THROUGHPUT[],
|
double PSCL_THROUGHPUT_CHROMA[],
|
double DPPCLK[],
|
int BytePerPixelC[],
|
enum scan_direction_class SourceScan[],
|
unsigned int NumberOfCursors[],
|
unsigned int CursorWidth[][2],
|
unsigned int CursorBPP[][2],
|
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 CursorRequestDeliveryTime[],
|
double CursorRequestDeliveryTimePrefetch[])
|
{
|
double req_per_swath_ub = 0;
|
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 (BytePerPixelC[k] == 0) {
|
DisplayPipeLineDeliveryTimeChroma[k] = 0;
|
} else {
|
if (VRatioChroma[k] <= 1) {
|
DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / 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 (BytePerPixelC[k] == 0) {
|
DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
|
} else {
|
if (VRatioPrefetchC[k] <= 1) {
|
DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / 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_vert) {
|
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 (BytePerPixelC[k] == 0) {
|
DisplayPipeRequestDeliveryTimeChroma[k] = 0;
|
DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0;
|
} else {
|
if (SourceScan[k] != dm_vert) {
|
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;
|
}
|
}
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
int cursor_req_per_width = 0;
|
cursor_req_per_width = dml_ceil(CursorWidth[k][0] * CursorBPP[k][0] / 256 / 8, 1);
|
if (NumberOfCursors[k] > 0) {
|
if (VRatio[k] <= 1) {
|
CursorRequestDeliveryTime[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
|
} else {
|
CursorRequestDeliveryTime[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
|
}
|
if (VRatioPrefetchY[k] <= 1) {
|
CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
|
} else {
|
CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
|
}
|
} else {
|
CursorRequestDeliveryTime[k] = 0;
|
CursorRequestDeliveryTimePrefetch[k] = 0;
|
}
|
}
|
}
|
|
static void CalculateMetaAndPTETimes(
|
int NumberOfActivePlanes,
|
bool GPUVMEnable,
|
int MetaChunkSize,
|
int MinMetaChunkSizeBytes,
|
int HTotal[],
|
double VRatio[],
|
double VRatioChroma[],
|
double DestinationLinesToRequestRowInVBlank[],
|
double DestinationLinesToRequestRowInImmediateFlip[],
|
bool DCCEnable[],
|
double PixelClock[],
|
int BytePerPixelY[],
|
int BytePerPixelC[],
|
enum scan_direction_class SourceScan[],
|
int dpte_row_height[],
|
int dpte_row_height_chroma[],
|
int meta_row_width[],
|
int meta_row_width_chroma[],
|
int meta_row_height[],
|
int meta_row_height_chroma[],
|
int meta_req_width[],
|
int meta_req_width_chroma[],
|
int meta_req_height[],
|
int meta_req_height_chroma[],
|
int dpte_group_bytes[],
|
int PTERequestSizeY[],
|
int PTERequestSizeC[],
|
int PixelPTEReqWidthY[],
|
int PixelPTEReqHeightY[],
|
int PixelPTEReqWidthC[],
|
int PixelPTEReqHeightC[],
|
int dpte_row_width_luma_ub[],
|
int dpte_row_width_chroma_ub[],
|
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 DST_Y_PER_META_ROW_NOM_C[],
|
double TimePerMetaChunkNominal[],
|
double TimePerChromaMetaChunkNominal[],
|
double TimePerMetaChunkVBlank[],
|
double TimePerChromaMetaChunkVBlank[],
|
double TimePerMetaChunkFlip[],
|
double TimePerChromaMetaChunkFlip[],
|
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[])
|
{
|
unsigned int meta_chunk_width = 0;
|
unsigned int min_meta_chunk_width = 0;
|
unsigned int meta_chunk_per_row_int = 0;
|
unsigned int meta_row_remainder = 0;
|
unsigned int meta_chunk_threshold = 0;
|
unsigned int meta_chunks_per_row_ub = 0;
|
unsigned int meta_chunk_width_chroma = 0;
|
unsigned int min_meta_chunk_width_chroma = 0;
|
unsigned int meta_chunk_per_row_int_chroma = 0;
|
unsigned int meta_row_remainder_chroma = 0;
|
unsigned int meta_chunk_threshold_chroma = 0;
|
unsigned int meta_chunks_per_row_ub_chroma = 0;
|
unsigned int dpte_group_width_luma = 0;
|
unsigned int dpte_groups_per_row_luma_ub = 0;
|
unsigned int dpte_group_width_chroma = 0;
|
unsigned int dpte_groups_per_row_chroma_ub = 0;
|
unsigned int k;
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
DST_Y_PER_PTE_ROW_NOM_L[k] = dpte_row_height[k] / VRatio[k];
|
if (BytePerPixelC[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] / VRatioChroma[k];
|
}
|
DST_Y_PER_META_ROW_NOM_L[k] = meta_row_height[k] / VRatio[k];
|
if (BytePerPixelC[k] == 0) {
|
DST_Y_PER_META_ROW_NOM_C[k] = 0;
|
} else {
|
DST_Y_PER_META_ROW_NOM_C[k] = meta_row_height_chroma[k] / VRatioChroma[k];
|
}
|
}
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (DCCEnable[k] == true) {
|
meta_chunk_width = MetaChunkSize * 1024 * 256 / BytePerPixelY[k] / meta_row_height[k];
|
min_meta_chunk_width = MinMetaChunkSizeBytes * 256 / BytePerPixelY[k] / 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_vert) {
|
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;
|
if (BytePerPixelC[k] == 0) {
|
TimePerChromaMetaChunkNominal[k] = 0;
|
TimePerChromaMetaChunkVBlank[k] = 0;
|
TimePerChromaMetaChunkFlip[k] = 0;
|
} else {
|
meta_chunk_width_chroma = MetaChunkSize * 1024 * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
|
min_meta_chunk_width_chroma = MinMetaChunkSizeBytes * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
|
meta_chunk_per_row_int_chroma = (double) meta_row_width_chroma[k] / meta_chunk_width_chroma;
|
meta_row_remainder_chroma = meta_row_width_chroma[k] % meta_chunk_width_chroma;
|
if (SourceScan[k] != dm_vert) {
|
meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_width_chroma[k];
|
} else {
|
meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_height_chroma[k];
|
}
|
if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) {
|
meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1;
|
} else {
|
meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2;
|
}
|
TimePerChromaMetaChunkNominal[k] = meta_row_height_chroma[k] / VRatioChroma[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
|
TimePerChromaMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
|
TimePerChromaMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
|
}
|
} else {
|
TimePerMetaChunkNominal[k] = 0;
|
TimePerMetaChunkVBlank[k] = 0;
|
TimePerMetaChunkFlip[k] = 0;
|
TimePerChromaMetaChunkNominal[k] = 0;
|
TimePerChromaMetaChunkVBlank[k] = 0;
|
TimePerChromaMetaChunkFlip[k] = 0;
|
}
|
}
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (GPUVMEnable == true) {
|
if (SourceScan[k] != dm_vert) {
|
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(1.0 * 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 (BytePerPixelC[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_vert) {
|
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(1.0 * 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;
|
}
|
}
|
}
|
|
static void CalculateVMGroupAndRequestTimes(
|
unsigned int NumberOfActivePlanes,
|
bool GPUVMEnable,
|
unsigned int GPUVMMaxPageTableLevels,
|
unsigned int HTotal[],
|
int BytePerPixelC[],
|
double DestinationLinesToRequestVMInVBlank[],
|
double DestinationLinesToRequestVMInImmediateFlip[],
|
bool DCCEnable[],
|
double PixelClock[],
|
int dpte_row_width_luma_ub[],
|
int dpte_row_width_chroma_ub[],
|
int vm_group_bytes[],
|
unsigned int dpde0_bytes_per_frame_ub_l[],
|
unsigned int dpde0_bytes_per_frame_ub_c[],
|
int meta_pte_bytes_per_frame_ub_l[],
|
int meta_pte_bytes_per_frame_ub_c[],
|
double TimePerVMGroupVBlank[],
|
double TimePerVMGroupFlip[],
|
double TimePerVMRequestVBlank[],
|
double TimePerVMRequestFlip[])
|
{
|
int num_group_per_lower_vm_stage = 0;
|
int num_req_per_lower_vm_stage = 0;
|
unsigned int k;
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (GPUVMEnable == true && (DCCEnable[k] == true || GPUVMMaxPageTableLevels > 1)) {
|
if (DCCEnable[k] == false) {
|
if (BytePerPixelC[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 (BytePerPixelC[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 (BytePerPixelC[k] > 0) {
|
num_group_per_lower_vm_stage = 2 + 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 = 1 + 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 (BytePerPixelC[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 (BytePerPixelC[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 (BytePerPixelC[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 void CalculateStutterEfficiency(
|
int NumberOfActivePlanes,
|
long ROBBufferSizeInKByte,
|
double TotalDataReadBandwidth,
|
double DCFCLK,
|
double ReturnBW,
|
double SRExitTime,
|
bool SynchronizedVBlank,
|
int DPPPerPlane[],
|
double DETBufferSizeY[],
|
int BytePerPixelY[],
|
double BytePerPixelDETY[],
|
double SwathWidthY[],
|
int SwathHeightY[],
|
int SwathHeightC[],
|
double DCCRateLuma[],
|
double DCCRateChroma[],
|
int HTotal[],
|
int VTotal[],
|
double PixelClock[],
|
double VRatio[],
|
enum scan_direction_class SourceScan[],
|
int BlockHeight256BytesY[],
|
int BlockWidth256BytesY[],
|
int BlockHeight256BytesC[],
|
int BlockWidth256BytesC[],
|
int DCCYMaxUncompressedBlock[],
|
int DCCCMaxUncompressedBlock[],
|
int VActive[],
|
bool DCCEnable[],
|
bool WritebackEnable[],
|
double ReadBandwidthPlaneLuma[],
|
double ReadBandwidthPlaneChroma[],
|
double meta_row_bw[],
|
double dpte_row_bw[],
|
double *StutterEfficiencyNotIncludingVBlank,
|
double *StutterEfficiency,
|
double *StutterPeriodOut)
|
{
|
double FullDETBufferingTimeY[DC__NUM_DPP__MAX] = { 0 };
|
double FrameTimeForMinFullDETBufferingTime = 0;
|
double StutterPeriod = 0;
|
double AverageReadBandwidth = 0;
|
double TotalRowReadBandwidth = 0;
|
double AverageDCCCompressionRate = 0;
|
double PartOfBurstThatFitsInROB = 0;
|
double StutterBurstTime = 0;
|
int TotalActiveWriteback = 0;
|
double VBlankTime = 0;
|
double SmallestVBlank = 0;
|
int BytePerPixelYCriticalPlane = 0;
|
double SwathWidthYCriticalPlane = 0;
|
double LinesInDETY[DC__NUM_DPP__MAX] = { 0 };
|
double LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX] = { 0 };
|
double LinesToFinishSwathTransferStutterCriticalPlane = 0;
|
double MaximumEffectiveCompressionLuma = 0;
|
double MaximumEffectiveCompressionChroma = 0;
|
unsigned int k;
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
LinesInDETY[k] = DETBufferSizeY[k] / BytePerPixelDETY[k] / SwathWidthY[k];
|
LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
|
FullDETBufferingTimeY[k] = LinesInDETYRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k]) / VRatio[k];
|
}
|
|
StutterPeriod = FullDETBufferingTimeY[0];
|
FrameTimeForMinFullDETBufferingTime = VTotal[0] * HTotal[0] / PixelClock[0];
|
BytePerPixelYCriticalPlane = BytePerPixelY[0];
|
SwathWidthYCriticalPlane = SwathWidthY[0];
|
LinesToFinishSwathTransferStutterCriticalPlane = SwathHeightY[0]
|
- (LinesInDETY[0] - LinesInDETYRoundedDownToSwath[0]);
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (FullDETBufferingTimeY[k] < StutterPeriod) {
|
StutterPeriod = FullDETBufferingTimeY[k];
|
FrameTimeForMinFullDETBufferingTime = VTotal[k] * HTotal[k] / PixelClock[k];
|
BytePerPixelYCriticalPlane = BytePerPixelY[k];
|
SwathWidthYCriticalPlane = SwathWidthY[k];
|
LinesToFinishSwathTransferStutterCriticalPlane = SwathHeightY[k]
|
- (LinesInDETY[k] - LinesInDETYRoundedDownToSwath[k]);
|
}
|
}
|
|
AverageReadBandwidth = 0;
|
TotalRowReadBandwidth = 0;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (DCCEnable[k] == true) {
|
if ((SourceScan[k] == dm_vert && BlockWidth256BytesY[k] > SwathHeightY[k])
|
|| (SourceScan[k] != dm_vert
|
&& BlockHeight256BytesY[k] > SwathHeightY[k])
|
|| DCCYMaxUncompressedBlock[k] < 256) {
|
MaximumEffectiveCompressionLuma = 2;
|
} else {
|
MaximumEffectiveCompressionLuma = 4;
|
}
|
AverageReadBandwidth = AverageReadBandwidth + ReadBandwidthPlaneLuma[k] / dml_min(DCCRateLuma[k], MaximumEffectiveCompressionLuma);
|
|
if (ReadBandwidthPlaneChroma[k] > 0) {
|
if ((SourceScan[k] == dm_vert && BlockWidth256BytesC[k] > SwathHeightC[k])
|
|| (SourceScan[k] != dm_vert && BlockHeight256BytesC[k] > SwathHeightC[k])
|
|| DCCCMaxUncompressedBlock[k] < 256) {
|
MaximumEffectiveCompressionChroma = 2;
|
} else {
|
MaximumEffectiveCompressionChroma = 4;
|
}
|
AverageReadBandwidth = AverageReadBandwidth + ReadBandwidthPlaneChroma[k] / dml_min(DCCRateChroma[k], MaximumEffectiveCompressionChroma);
|
}
|
} else {
|
AverageReadBandwidth = AverageReadBandwidth + ReadBandwidthPlaneLuma[k] + ReadBandwidthPlaneChroma[k];
|
}
|
TotalRowReadBandwidth = TotalRowReadBandwidth + DPPPerPlane[k] * (meta_row_bw[k] + dpte_row_bw[k]);
|
}
|
|
AverageDCCCompressionRate = TotalDataReadBandwidth / AverageReadBandwidth;
|
PartOfBurstThatFitsInROB = dml_min(StutterPeriod * TotalDataReadBandwidth, ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate);
|
StutterBurstTime = PartOfBurstThatFitsInROB / AverageDCCCompressionRate / ReturnBW + (StutterPeriod * TotalDataReadBandwidth
|
- PartOfBurstThatFitsInROB) / (DCFCLK * 64) + StutterPeriod * TotalRowReadBandwidth / ReturnBW;
|
StutterBurstTime = dml_max(StutterBurstTime, LinesToFinishSwathTransferStutterCriticalPlane * BytePerPixelYCriticalPlane * SwathWidthYCriticalPlane / ReturnBW);
|
|
TotalActiveWriteback = 0;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (WritebackEnable[k] == true) {
|
TotalActiveWriteback = TotalActiveWriteback + 1;
|
}
|
}
|
|
if (TotalActiveWriteback == 0) {
|
*StutterEfficiencyNotIncludingVBlank = (1
|
- (SRExitTime + StutterBurstTime) / StutterPeriod) * 100;
|
} else {
|
*StutterEfficiencyNotIncludingVBlank = 0;
|
}
|
|
if (SynchronizedVBlank == true || NumberOfActivePlanes == 1) {
|
SmallestVBlank = (VTotal[0] - VActive[0]) * HTotal[0] / PixelClock[0];
|
} else {
|
SmallestVBlank = 0;
|
}
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if (SynchronizedVBlank == true || NumberOfActivePlanes == 1) {
|
VBlankTime = (VTotal[k] - VActive[k]) * HTotal[k] / PixelClock[k];
|
} else {
|
VBlankTime = 0;
|
}
|
SmallestVBlank = dml_min(SmallestVBlank, VBlankTime);
|
}
|
|
*StutterEfficiency = (*StutterEfficiencyNotIncludingVBlank / 100.0 * (FrameTimeForMinFullDETBufferingTime - SmallestVBlank) + SmallestVBlank) / FrameTimeForMinFullDETBufferingTime * 100;
|
|
if (StutterPeriodOut)
|
*StutterPeriodOut = StutterPeriod;
|
}
|
|
static void CalculateSwathAndDETConfiguration(
|
bool ForceSingleDPP,
|
int NumberOfActivePlanes,
|
long DETBufferSizeInKByte,
|
double MaximumSwathWidthLuma[],
|
double MaximumSwathWidthChroma[],
|
enum scan_direction_class SourceScan[],
|
enum source_format_class SourcePixelFormat[],
|
enum dm_swizzle_mode SurfaceTiling[],
|
int ViewportWidth[],
|
int ViewportHeight[],
|
int SurfaceWidthY[],
|
int SurfaceWidthC[],
|
int SurfaceHeightY[],
|
int SurfaceHeightC[],
|
int Read256BytesBlockHeightY[],
|
int Read256BytesBlockHeightC[],
|
int Read256BytesBlockWidthY[],
|
int Read256BytesBlockWidthC[],
|
enum odm_combine_mode ODMCombineEnabled[],
|
int BlendingAndTiming[],
|
int BytePerPixY[],
|
int BytePerPixC[],
|
double BytePerPixDETY[],
|
double BytePerPixDETC[],
|
int HActive[],
|
double HRatio[],
|
double HRatioChroma[],
|
int DPPPerPlane[],
|
int swath_width_luma_ub[],
|
int swath_width_chroma_ub[],
|
double SwathWidth[],
|
double SwathWidthChroma[],
|
int SwathHeightY[],
|
int SwathHeightC[],
|
double DETBufferSizeY[],
|
double DETBufferSizeC[],
|
bool ViewportSizeSupportPerPlane[],
|
bool *ViewportSizeSupport)
|
{
|
int MaximumSwathHeightY[DC__NUM_DPP__MAX] = { 0 };
|
int MaximumSwathHeightC[DC__NUM_DPP__MAX] = { 0 };
|
int MinimumSwathHeightY = 0;
|
int MinimumSwathHeightC = 0;
|
long RoundedUpMaxSwathSizeBytesY = 0;
|
long RoundedUpMaxSwathSizeBytesC = 0;
|
long RoundedUpMinSwathSizeBytesY = 0;
|
long RoundedUpMinSwathSizeBytesC = 0;
|
long RoundedUpSwathSizeBytesY = 0;
|
long RoundedUpSwathSizeBytesC = 0;
|
double SwathWidthSingleDPP[DC__NUM_DPP__MAX] = { 0 };
|
double SwathWidthSingleDPPChroma[DC__NUM_DPP__MAX] = { 0 };
|
int k;
|
|
CalculateSwathWidth(
|
ForceSingleDPP,
|
NumberOfActivePlanes,
|
SourcePixelFormat,
|
SourceScan,
|
ViewportWidth,
|
ViewportHeight,
|
SurfaceWidthY,
|
SurfaceWidthC,
|
SurfaceHeightY,
|
SurfaceHeightC,
|
ODMCombineEnabled,
|
BytePerPixY,
|
BytePerPixC,
|
Read256BytesBlockHeightY,
|
Read256BytesBlockHeightC,
|
Read256BytesBlockWidthY,
|
Read256BytesBlockWidthC,
|
BlendingAndTiming,
|
HActive,
|
HRatio,
|
DPPPerPlane,
|
SwathWidthSingleDPP,
|
SwathWidthSingleDPPChroma,
|
SwathWidth,
|
SwathWidthChroma,
|
MaximumSwathHeightY,
|
MaximumSwathHeightC,
|
swath_width_luma_ub,
|
swath_width_chroma_ub);
|
|
*ViewportSizeSupport = true;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
if ((SourcePixelFormat[k] == dm_444_64 || SourcePixelFormat[k] == dm_444_32
|
|| SourcePixelFormat[k] == dm_444_16
|
|| SourcePixelFormat[k] == dm_mono_16
|
|| SourcePixelFormat[k] == dm_mono_8
|
|| SourcePixelFormat[k] == dm_rgbe)) {
|
if (SurfaceTiling[k] == dm_sw_linear
|
|| (SourcePixelFormat[k] == dm_444_64
|
&& (SurfaceTiling[k] == dm_sw_64kb_s || SurfaceTiling[k] == dm_sw_64kb_s_t || SurfaceTiling[k] == dm_sw_64kb_s_x)
|
&& SourceScan[k] != dm_vert)) {
|
MinimumSwathHeightY = MaximumSwathHeightY[k];
|
} else if (SourcePixelFormat[k] == dm_444_8 && SourceScan[k] == dm_vert) {
|
MinimumSwathHeightY = MaximumSwathHeightY[k];
|
} else {
|
MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
|
}
|
MinimumSwathHeightC = MaximumSwathHeightC[k];
|
} else {
|
if (SurfaceTiling[k] == dm_sw_linear) {
|
MinimumSwathHeightY = MaximumSwathHeightY[k];
|
MinimumSwathHeightC = MaximumSwathHeightC[k];
|
} else if (SourcePixelFormat[k] == dm_rgbe_alpha
|
&& SourceScan[k] == dm_vert) {
|
MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
|
MinimumSwathHeightC = MaximumSwathHeightC[k];
|
} else if (SourcePixelFormat[k] == dm_rgbe_alpha) {
|
MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
|
MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
|
} else if (SourcePixelFormat[k] == dm_420_8 && SourceScan[k] == dm_vert) {
|
MinimumSwathHeightY = MaximumSwathHeightY[k];
|
MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
|
} else {
|
MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
|
MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
|
}
|
}
|
|
RoundedUpMaxSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k]
|
* MaximumSwathHeightY[k];
|
RoundedUpMinSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k]
|
* MinimumSwathHeightY;
|
if (SourcePixelFormat[k] == dm_420_10) {
|
RoundedUpMaxSwathSizeBytesY = dml_ceil((double) RoundedUpMaxSwathSizeBytesY, 256);
|
RoundedUpMinSwathSizeBytesY = dml_ceil((double) RoundedUpMinSwathSizeBytesY, 256);
|
}
|
RoundedUpMaxSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k]
|
* MaximumSwathHeightC[k];
|
RoundedUpMinSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k]
|
* MinimumSwathHeightC;
|
if (SourcePixelFormat[k] == dm_420_10) {
|
RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, 256);
|
RoundedUpMinSwathSizeBytesC = dml_ceil(RoundedUpMinSwathSizeBytesC, 256);
|
}
|
|
if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
|
<= DETBufferSizeInKByte * 1024 / 2) {
|
SwathHeightY[k] = MaximumSwathHeightY[k];
|
SwathHeightC[k] = MaximumSwathHeightC[k];
|
RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
|
RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
|
} else if (RoundedUpMaxSwathSizeBytesY >= 1.5 * RoundedUpMaxSwathSizeBytesC
|
&& RoundedUpMinSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
|
<= DETBufferSizeInKByte * 1024 / 2) {
|
SwathHeightY[k] = MinimumSwathHeightY;
|
SwathHeightC[k] = MaximumSwathHeightC[k];
|
RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
|
RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
|
} else if (RoundedUpMaxSwathSizeBytesY < 1.5 * RoundedUpMaxSwathSizeBytesC
|
&& RoundedUpMaxSwathSizeBytesY + RoundedUpMinSwathSizeBytesC
|
<= DETBufferSizeInKByte * 1024 / 2) {
|
SwathHeightY[k] = MaximumSwathHeightY[k];
|
SwathHeightC[k] = MinimumSwathHeightC;
|
RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
|
RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
|
} else {
|
SwathHeightY[k] = MinimumSwathHeightY;
|
SwathHeightC[k] = MinimumSwathHeightC;
|
RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
|
RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
|
}
|
|
if (SwathHeightC[k] == 0) {
|
DETBufferSizeY[k] = DETBufferSizeInKByte * 1024;
|
DETBufferSizeC[k] = 0;
|
} else if (RoundedUpSwathSizeBytesY <= 1.5 * RoundedUpSwathSizeBytesC) {
|
DETBufferSizeY[k] = DETBufferSizeInKByte * 1024 / 2;
|
DETBufferSizeC[k] = DETBufferSizeInKByte * 1024 / 2;
|
} else {
|
DETBufferSizeY[k] = DETBufferSizeInKByte * 1024 * 2 / 3;
|
DETBufferSizeC[k] = DETBufferSizeInKByte * 1024 / 3;
|
}
|
|
if (RoundedUpMinSwathSizeBytesY + RoundedUpMinSwathSizeBytesC
|
> DETBufferSizeInKByte * 1024 / 2
|
|| SwathWidth[k] > MaximumSwathWidthLuma[k]
|
|| (SwathHeightC[k] > 0
|
&& SwathWidthChroma[k] > MaximumSwathWidthChroma[k])) {
|
*ViewportSizeSupport = false;
|
ViewportSizeSupportPerPlane[k] = false;
|
} else {
|
ViewportSizeSupportPerPlane[k] = true;
|
}
|
}
|
}
|
|
static void CalculateSwathWidth(
|
bool ForceSingleDPP,
|
int NumberOfActivePlanes,
|
enum source_format_class SourcePixelFormat[],
|
enum scan_direction_class SourceScan[],
|
unsigned int ViewportWidth[],
|
unsigned int ViewportHeight[],
|
unsigned int SurfaceWidthY[],
|
unsigned int SurfaceWidthC[],
|
unsigned int SurfaceHeightY[],
|
unsigned int SurfaceHeightC[],
|
enum odm_combine_mode ODMCombineEnabled[],
|
int BytePerPixY[],
|
int BytePerPixC[],
|
int Read256BytesBlockHeightY[],
|
int Read256BytesBlockHeightC[],
|
int Read256BytesBlockWidthY[],
|
int Read256BytesBlockWidthC[],
|
int BlendingAndTiming[],
|
unsigned int HActive[],
|
double HRatio[],
|
int DPPPerPlane[],
|
double SwathWidthSingleDPPY[],
|
double SwathWidthSingleDPPC[],
|
double SwathWidthY[],
|
double SwathWidthC[],
|
int MaximumSwathHeightY[],
|
int MaximumSwathHeightC[],
|
unsigned int swath_width_luma_ub[],
|
unsigned int swath_width_chroma_ub[])
|
{
|
unsigned int k, j;
|
long surface_width_ub_l;
|
long surface_height_ub_l;
|
long surface_width_ub_c;
|
long surface_height_ub_c;
|
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
enum odm_combine_mode MainPlaneODMCombine = 0;
|
surface_width_ub_l = dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
|
surface_height_ub_l = dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
|
surface_width_ub_c = dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
|
surface_height_ub_c = dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
|
|
if (SourceScan[k] != dm_vert) {
|
SwathWidthSingleDPPY[k] = ViewportWidth[k];
|
} else {
|
SwathWidthSingleDPPY[k] = ViewportHeight[k];
|
}
|
|
MainPlaneODMCombine = ODMCombineEnabled[k];
|
for (j = 0; j < NumberOfActivePlanes; ++j) {
|
if (BlendingAndTiming[k] == j) {
|
MainPlaneODMCombine = ODMCombineEnabled[j];
|
}
|
}
|
|
if (MainPlaneODMCombine == dm_odm_combine_mode_4to1) {
|
SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 4.0 * HRatio[k]));
|
} else if (MainPlaneODMCombine == dm_odm_combine_mode_2to1) {
|
SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 2.0 * HRatio[k]));
|
} else if (DPPPerPlane[k] == 2) {
|
SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2;
|
} else {
|
SwathWidthY[k] = SwathWidthSingleDPPY[k];
|
}
|
|
if (SourcePixelFormat[k] == dm_420_8 || SourcePixelFormat[k] == dm_420_10 || SourcePixelFormat[k] == dm_420_12) {
|
SwathWidthC[k] = SwathWidthY[k] / 2;
|
SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2;
|
} else {
|
SwathWidthC[k] = SwathWidthY[k];
|
SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k];
|
}
|
|
if (ForceSingleDPP == true) {
|
SwathWidthY[k] = SwathWidthSingleDPPY[k];
|
SwathWidthC[k] = SwathWidthSingleDPPC[k];
|
}
|
|
surface_width_ub_l = dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
|
surface_height_ub_l = dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
|
surface_width_ub_c = dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
|
surface_height_ub_c = dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
|
|
if (SourceScan[k] != dm_vert) {
|
MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k];
|
MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k];
|
swath_width_luma_ub[k] = dml_min(surface_width_ub_l, (long) dml_ceil(SwathWidthY[k] - 1,
|
Read256BytesBlockWidthY[k]) + Read256BytesBlockWidthY[k]);
|
if (BytePerPixC[k] > 0) {
|
swath_width_chroma_ub[k] = dml_min(surface_width_ub_c, (long) dml_ceil(SwathWidthC[k] - 1,
|
Read256BytesBlockWidthC[k]) + Read256BytesBlockWidthC[k]);
|
} else {
|
swath_width_chroma_ub[k] = 0;
|
}
|
} else {
|
MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k];
|
MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k];
|
swath_width_luma_ub[k] = dml_min(surface_height_ub_l, (long) dml_ceil(SwathWidthY[k] - 1,
|
Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]);
|
if (BytePerPixC[k] > 0) {
|
swath_width_chroma_ub[k] = dml_min(surface_height_ub_c, (long) dml_ceil(SwathWidthC[k] - 1,
|
Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]);
|
} else {
|
swath_width_chroma_ub[k] = 0;
|
}
|
}
|
}
|
}
|
|
static double CalculateExtraLatency(
|
long RoundTripPingLatencyCycles,
|
long ReorderingBytes,
|
double DCFCLK,
|
int TotalNumberOfActiveDPP,
|
int PixelChunkSizeInKByte,
|
int TotalNumberOfDCCActiveDPP,
|
int MetaChunkSize,
|
double ReturnBW,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
int NumberOfActivePlanes,
|
int NumberOfDPP[],
|
int dpte_group_bytes[],
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
double HostVMMinPageSize,
|
int HostVMMaxNonCachedPageTableLevels)
|
{
|
double ExtraLatencyBytes = 0;
|
ExtraLatencyBytes = CalculateExtraLatencyBytes(
|
ReorderingBytes,
|
TotalNumberOfActiveDPP,
|
PixelChunkSizeInKByte,
|
TotalNumberOfDCCActiveDPP,
|
MetaChunkSize,
|
GPUVMEnable,
|
HostVMEnable,
|
NumberOfActivePlanes,
|
NumberOfDPP,
|
dpte_group_bytes,
|
PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
HostVMMinPageSize,
|
HostVMMaxNonCachedPageTableLevels);
|
|
return (RoundTripPingLatencyCycles + 32) / DCFCLK + ExtraLatencyBytes / ReturnBW;
|
}
|
|
static double CalculateExtraLatencyBytes(
|
long ReorderingBytes,
|
int TotalNumberOfActiveDPP,
|
int PixelChunkSizeInKByte,
|
int TotalNumberOfDCCActiveDPP,
|
int MetaChunkSize,
|
bool GPUVMEnable,
|
bool HostVMEnable,
|
int NumberOfActivePlanes,
|
int NumberOfDPP[],
|
int dpte_group_bytes[],
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
double HostVMMinPageSize,
|
int HostVMMaxNonCachedPageTableLevels)
|
{
|
double ret = 0;
|
double HostVMInefficiencyFactor = 0;
|
int HostVMDynamicLevels = 0;
|
unsigned int k;
|
|
if (GPUVMEnable == true && HostVMEnable == true) {
|
HostVMInefficiencyFactor = PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
|
if (HostVMMinPageSize < 2048) {
|
HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
|
} else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) {
|
HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
|
} else {
|
HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
|
}
|
} else {
|
HostVMInefficiencyFactor = 1;
|
HostVMDynamicLevels = 0;
|
}
|
|
ret = ReorderingBytes + (TotalNumberOfActiveDPP * PixelChunkSizeInKByte + TotalNumberOfDCCActiveDPP * MetaChunkSize) * 1024.0;
|
|
if (GPUVMEnable == true) {
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
ret = ret + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor;
|
}
|
}
|
return ret;
|
}
|
|
|
static double CalculateUrgentLatency(
|
double UrgentLatencyPixelDataOnly,
|
double UrgentLatencyPixelMixedWithVMData,
|
double UrgentLatencyVMDataOnly,
|
bool DoUrgentLatencyAdjustment,
|
double UrgentLatencyAdjustmentFabricClockComponent,
|
double UrgentLatencyAdjustmentFabricClockReference,
|
double FabricClock)
|
{
|
double ret;
|
|
ret = dml_max3(UrgentLatencyPixelDataOnly, UrgentLatencyPixelMixedWithVMData, UrgentLatencyVMDataOnly);
|
if (DoUrgentLatencyAdjustment == true) {
|
ret = ret + UrgentLatencyAdjustmentFabricClockComponent * (UrgentLatencyAdjustmentFabricClockReference / FabricClock - 1);
|
}
|
return ret;
|
}
|
|
static noinline_for_stack void UseMinimumDCFCLK(
|
struct display_mode_lib *mode_lib,
|
int MaxInterDCNTileRepeaters,
|
int MaxPrefetchMode,
|
double FinalDRAMClockChangeLatency,
|
double SREnterPlusExitTime,
|
int ReturnBusWidth,
|
int RoundTripPingLatencyCycles,
|
int ReorderingBytes,
|
int PixelChunkSizeInKByte,
|
int MetaChunkSize,
|
bool GPUVMEnable,
|
int GPUVMMaxPageTableLevels,
|
bool HostVMEnable,
|
int NumberOfActivePlanes,
|
double HostVMMinPageSize,
|
int HostVMMaxNonCachedPageTableLevels,
|
bool DynamicMetadataVMEnabled,
|
enum immediate_flip_requirement ImmediateFlipRequirement,
|
bool ProgressiveToInterlaceUnitInOPP,
|
double MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly,
|
int VTotal[],
|
int VActive[],
|
int DynamicMetadataTransmittedBytes[],
|
int DynamicMetadataLinesBeforeActiveRequired[],
|
bool Interlace[],
|
double RequiredDPPCLK[][2][DC__NUM_DPP__MAX],
|
double RequiredDISPCLK[][2],
|
double UrgLatency[],
|
unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX],
|
double ProjectedDCFCLKDeepSleep[][2],
|
double MaximumVStartup[][2][DC__NUM_DPP__MAX],
|
double TotalVActivePixelBandwidth[][2],
|
double TotalVActiveCursorBandwidth[][2],
|
double TotalMetaRowBandwidth[][2],
|
double TotalDPTERowBandwidth[][2],
|
unsigned int TotalNumberOfActiveDPP[][2],
|
unsigned int TotalNumberOfDCCActiveDPP[][2],
|
int dpte_group_bytes[],
|
double PrefetchLinesY[][2][DC__NUM_DPP__MAX],
|
double PrefetchLinesC[][2][DC__NUM_DPP__MAX],
|
int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX],
|
int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX],
|
int BytePerPixelY[],
|
int BytePerPixelC[],
|
int HTotal[],
|
double PixelClock[],
|
double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX],
|
double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX],
|
double MetaRowBytes[][2][DC__NUM_DPP__MAX],
|
bool DynamicMetadataEnable[],
|
double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX],
|
double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX],
|
double ReadBandwidthLuma[],
|
double ReadBandwidthChroma[],
|
double DCFCLKPerState[],
|
double DCFCLKState[][2])
|
{
|
double NormalEfficiency = 0;
|
double PTEEfficiency = 0;
|
double TotalMaxPrefetchFlipDPTERowBandwidth[DC__VOLTAGE_STATES][2] = { { 0 } };
|
unsigned int i, j, k;
|
|
NormalEfficiency = (HostVMEnable == true ? PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData
|
: PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly) / 100.0;
|
PTEEfficiency = (HostVMEnable == true ? PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly
|
/ PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData : 1.0);
|
for (i = 0; i < mode_lib->soc.num_states; ++i) {
|
for (j = 0; j <= 1; ++j) {
|
double PixelDCFCLKCyclesRequiredInPrefetch[DC__NUM_DPP__MAX] = { 0 };
|
double PrefetchPixelLinesTime[DC__NUM_DPP__MAX] = { 0 };
|
double DCFCLKRequiredForPeakBandwidthPerPlane[DC__NUM_DPP__MAX] = { 0 };
|
double DynamicMetadataVMExtraLatency[DC__NUM_DPP__MAX] = { 0 };
|
double MinimumTWait = 0;
|
double NonDPTEBandwidth = 0;
|
double DPTEBandwidth = 0;
|
double DCFCLKRequiredForAverageBandwidth = 0;
|
double ExtraLatencyBytes = 0;
|
double ExtraLatencyCycles = 0;
|
double DCFCLKRequiredForPeakBandwidth = 0;
|
int NoOfDPPState[DC__NUM_DPP__MAX] = { 0 };
|
double MinimumTvmPlus2Tr0 = 0;
|
|
TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = 0;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = TotalMaxPrefetchFlipDPTERowBandwidth[i][j]
|
+ NoOfDPP[i][j][k] * DPTEBytesPerRow[i][j][k] / (15.75 * HTotal[k] / PixelClock[k]);
|
}
|
|
for (k = 0; k <= NumberOfActivePlanes - 1; ++k) {
|
NoOfDPPState[k] = NoOfDPP[i][j][k];
|
}
|
|
MinimumTWait = CalculateTWait(MaxPrefetchMode, FinalDRAMClockChangeLatency, UrgLatency[i], SREnterPlusExitTime);
|
NonDPTEBandwidth = TotalVActivePixelBandwidth[i][j] + TotalVActiveCursorBandwidth[i][j] + TotalMetaRowBandwidth[i][j];
|
DPTEBandwidth = (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) ?
|
TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : TotalDPTERowBandwidth[i][j];
|
DCFCLKRequiredForAverageBandwidth = dml_max3(ProjectedDCFCLKDeepSleep[i][j],
|
(NonDPTEBandwidth + TotalDPTERowBandwidth[i][j]) / ReturnBusWidth / (MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100),
|
(NonDPTEBandwidth + DPTEBandwidth / PTEEfficiency) / NormalEfficiency / ReturnBusWidth);
|
|
ExtraLatencyBytes = CalculateExtraLatencyBytes(ReorderingBytes, TotalNumberOfActiveDPP[i][j], PixelChunkSizeInKByte, TotalNumberOfDCCActiveDPP[i][j],
|
MetaChunkSize, GPUVMEnable, HostVMEnable, NumberOfActivePlanes, NoOfDPPState, dpte_group_bytes,
|
PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
HostVMMinPageSize, HostVMMaxNonCachedPageTableLevels);
|
ExtraLatencyCycles = RoundTripPingLatencyCycles + 32 + ExtraLatencyBytes / NormalEfficiency / ReturnBusWidth;
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
double DCFCLKCyclesRequiredInPrefetch = { 0 };
|
double ExpectedPrefetchBWAcceleration = { 0 };
|
double PrefetchTime = { 0 };
|
|
PixelDCFCLKCyclesRequiredInPrefetch[k] = (PrefetchLinesY[i][j][k] * swath_width_luma_ub_all_states[i][j][k] * BytePerPixelY[k]
|
+ PrefetchLinesC[i][j][k] * swath_width_chroma_ub_all_states[i][j][k] * BytePerPixelC[k]) / NormalEfficiency / ReturnBusWidth;
|
DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k] + PDEAndMetaPTEBytesPerFrame[i][j][k] / PTEEfficiency
|
/ NormalEfficiency / ReturnBusWidth * (GPUVMMaxPageTableLevels > 2 ? 1 : 0) + 2 * DPTEBytesPerRow[i][j][k] / PTEEfficiency
|
/ NormalEfficiency / ReturnBusWidth + 2 * MetaRowBytes[i][j][k] / NormalEfficiency / ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k];
|
PrefetchPixelLinesTime[k] = dml_max(PrefetchLinesY[i][j][k], PrefetchLinesC[i][j][k]) * HTotal[k] / PixelClock[k];
|
ExpectedPrefetchBWAcceleration = (VActivePixelBandwidth[i][j][k] + VActiveCursorBandwidth[i][j][k]) / (ReadBandwidthLuma[k] + ReadBandwidthChroma[k]);
|
DynamicMetadataVMExtraLatency[k] = (GPUVMEnable == true && DynamicMetadataEnable[k] == true && DynamicMetadataVMEnabled == true) ?
|
UrgLatency[i] * GPUVMMaxPageTableLevels * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0;
|
PrefetchTime = (MaximumVStartup[i][j][k] - 1) * HTotal[k] / PixelClock[k] - MinimumTWait - UrgLatency[i] * ((GPUVMMaxPageTableLevels <= 2 ? GPUVMMaxPageTableLevels
|
: GPUVMMaxPageTableLevels - 2) * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) - DynamicMetadataVMExtraLatency[k];
|
|
if (PrefetchTime > 0) {
|
double ExpectedVRatioPrefetch = { 0 };
|
ExpectedVRatioPrefetch = PrefetchPixelLinesTime[k] / (PrefetchTime * PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch);
|
DCFCLKRequiredForPeakBandwidthPerPlane[k] = NoOfDPPState[k] * PixelDCFCLKCyclesRequiredInPrefetch[k] / PrefetchPixelLinesTime[k]
|
* dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4) * ExpectedPrefetchBWAcceleration;
|
if (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) {
|
DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKRequiredForPeakBandwidthPerPlane[k]
|
+ NoOfDPPState[k] * DPTEBandwidth / PTEEfficiency / NormalEfficiency / ReturnBusWidth;
|
}
|
} else {
|
DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i];
|
}
|
if (DynamicMetadataEnable[k] == true) {
|
double TsetupPipe = { 0 };
|
double TdmbfPipe = { 0 };
|
double TdmsksPipe = { 0 };
|
double TdmecPipe = { 0 };
|
double AllowedTimeForUrgentExtraLatency = { 0 };
|
|
CalculateDynamicMetadataParameters(
|
MaxInterDCNTileRepeaters,
|
RequiredDPPCLK[i][j][k],
|
RequiredDISPCLK[i][j],
|
ProjectedDCFCLKDeepSleep[i][j],
|
PixelClock[k],
|
HTotal[k],
|
VTotal[k] - VActive[k],
|
DynamicMetadataTransmittedBytes[k],
|
DynamicMetadataLinesBeforeActiveRequired[k],
|
Interlace[k],
|
ProgressiveToInterlaceUnitInOPP,
|
&TsetupPipe,
|
&TdmbfPipe,
|
&TdmecPipe,
|
&TdmsksPipe);
|
AllowedTimeForUrgentExtraLatency = MaximumVStartup[i][j][k] * HTotal[k] / PixelClock[k] - MinimumTWait - TsetupPipe
|
- TdmbfPipe - TdmecPipe - TdmsksPipe - DynamicMetadataVMExtraLatency[k];
|
if (AllowedTimeForUrgentExtraLatency > 0) {
|
DCFCLKRequiredForPeakBandwidthPerPlane[k] = dml_max(DCFCLKRequiredForPeakBandwidthPerPlane[k],
|
ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency);
|
} else {
|
DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i];
|
}
|
}
|
}
|
DCFCLKRequiredForPeakBandwidth = 0;
|
for (k = 0; k <= NumberOfActivePlanes - 1; ++k) {
|
DCFCLKRequiredForPeakBandwidth = DCFCLKRequiredForPeakBandwidth + DCFCLKRequiredForPeakBandwidthPerPlane[k];
|
}
|
MinimumTvmPlus2Tr0 = UrgLatency[i] * (GPUVMEnable == true ? (HostVMEnable == true ?
|
(GPUVMMaxPageTableLevels + 2) * (HostVMMaxNonCachedPageTableLevels + 1) - 1 : GPUVMMaxPageTableLevels + 1) : 0);
|
for (k = 0; k < NumberOfActivePlanes; ++k) {
|
double MaximumTvmPlus2Tr0PlusTsw = { 0 };
|
MaximumTvmPlus2Tr0PlusTsw = (MaximumVStartup[i][j][k] - 2) * HTotal[k] / PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k];
|
if (MaximumTvmPlus2Tr0PlusTsw <= MinimumTvmPlus2Tr0 + PrefetchPixelLinesTime[k] / 4) {
|
DCFCLKRequiredForPeakBandwidth = DCFCLKPerState[i];
|
} else {
|
DCFCLKRequiredForPeakBandwidth = dml_max3(DCFCLKRequiredForPeakBandwidth, 2 * ExtraLatencyCycles
|
/ (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0 - PrefetchPixelLinesTime[k] / 4),
|
(2 * ExtraLatencyCycles + PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0));
|
}
|
}
|
DCFCLKState[i][j] = dml_min(DCFCLKPerState[i], 1.05 * (1 + mode_lib->vba.PercentMarginOverMinimumRequiredDCFCLK / 100)
|
* dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth));
|
}
|
}
|
}
|
|
#endif /* CONFIG_DRM_AMD_DC_DCN3_0 */
|