#include "../display_mode_lib.h"
#include "display_mode_vba_20v2.h"
#include "../dml_inline_defs.h"
#define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff
#define DCN20_MAX_DSC_IMAGE_WIDTH 5184
#define DCN20_MAX_420_IMAGE_WIDTH 4096
static double adjust_ReturnBW(
struct display_mode_lib *mode_lib,
double ReturnBW,
bool DCCEnabledAnyPlane,
double ReturnBandwidthToDCN);
static unsigned int dscceComputeDelay(
unsigned int bpc,
double bpp,
unsigned int sliceWidth,
unsigned int numSlices,
enum output_format_class pixelFormat);
static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
static bool CalculateDelayAfterScaler(
struct display_mode_lib *mode_lib,
double ReturnBW,
double ReadBandwidthPlaneLuma,
double ReadBandwidthPlaneChroma,
double TotalDataReadBandwidth,
double DisplayPipeLineDeliveryTimeLuma,
double DisplayPipeLineDeliveryTimeChroma,
double DPPCLK,
double DISPCLK,
double PixelClock,
unsigned int DSCDelay,
unsigned int DPPPerPlane,
bool ScalerEnabled,
unsigned int NumberOfCursors,
double DPPCLKDelaySubtotal,
double DPPCLKDelaySCL,
double DPPCLKDelaySCLLBOnly,
double DPPCLKDelayCNVCFormater,
double DPPCLKDelayCNVCCursor,
double DISPCLKDelaySubtotal,
unsigned int ScalerRecoutWidth,
enum output_format_class OutputFormat,
unsigned int HTotal,
unsigned int SwathWidthSingleDPPY,
double BytePerPixelDETY,
double BytePerPixelDETC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
bool Interlace,
bool ProgressiveToInterlaceUnitInOPP,
double *DSTXAfterScaler,
double *DSTYAfterScaler
);
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double DPPCLK,
double DISPCLK,
double PixelClock,
double DCFCLKDeepSleep,
unsigned int DPPPerPlane,
unsigned int NumberOfCursors,
unsigned int VBlank,
unsigned int HTotal,
unsigned int MaxInterDCNTileRepeaters,
unsigned int VStartup,
unsigned int PageTableLevels,
bool GPUVMEnable,
bool DynamicMetadataEnable,
unsigned int DynamicMetadataLinesBeforeActiveRequired,
unsigned int DynamicMetadataTransmittedBytes,
bool DCCEnable,
double UrgentLatencyPixelDataOnly,
double UrgentExtraLatency,
double TCalc,
unsigned int PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
double PrefetchSourceLinesY,
unsigned int SwathWidthY,
double BytePerPixelDETY,
double VInitPreFillY,
unsigned int MaxNumSwathY,
double PrefetchSourceLinesC,
double BytePerPixelDETC,
double VInitPreFillC,
unsigned int MaxNumSwathC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
double TWait,
bool XFCEnabled,
double XFCRemoteSurfaceFlipDelay,
bool InterlaceEnable,
bool ProgressiveToInterlaceUnitInOPP,
double DSTXAfterScaler,
double DSTYAfterScaler,
double *DestinationLinesForPrefetch,
double *PrefetchBandwidth,
double *DestinationLinesToRequestVMInVBlank,
double *DestinationLinesToRequestRowInVBlank,
double *VRatioPrefetchY,
double *VRatioPrefetchC,
double *RequiredPrefetchPixDataBW,
double *Tno_bw,
unsigned int *VUpdateOffsetPix,
double *VUpdateWidthPix,
double *VReadyOffsetPix);
static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
static double CalculatePrefetchSourceLines(
struct display_mode_lib *mode_lib,
double VRatio,
double vtaps,
bool Interlace,
bool ProgressiveToInterlaceUnitInOPP,
unsigned int SwathHeight,
unsigned int ViewportYStart,
double *VInitPreFill,
unsigned int *MaxNumSwath);
static unsigned int CalculateVMAndRowBytes(
struct display_mode_lib *mode_lib,
bool DCCEnable,
unsigned int BlockHeight256Bytes,
unsigned int BlockWidth256Bytes,
enum source_format_class SourcePixelFormat,
unsigned int SurfaceTiling,
unsigned int BytePerPixel,
enum scan_direction_class ScanDirection,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int SwathWidthY,
bool GPUVMEnable,
unsigned int VMMPageSize,
unsigned int PTEBufferSizeInRequestsLuma,
unsigned int PDEProcessingBufIn64KBReqs,
unsigned int Pitch,
unsigned int DCCMetaPitch,
unsigned int *MacroTileWidth,
unsigned int *MetaRowByte,
unsigned int *PixelPTEBytesPerRow,
bool *PTEBufferSizeNotExceeded,
unsigned int *dpte_row_height,
unsigned int *meta_row_height);
static double CalculateTWait(
unsigned int PrefetchMode,
double DRAMClockChangeLatency,
double UrgentLatencyPixelDataOnly,
double SREnterPlusExitTime);
static double CalculateRemoteSurfaceFlipDelay(
struct display_mode_lib *mode_lib,
double VRatio,
double SwathWidth,
double Bpp,
double LineTime,
double XFCTSlvVupdateOffset,
double XFCTSlvVupdateWidth,
double XFCTSlvVreadyOffset,
double XFCXBUFLatencyTolerance,
double XFCFillBWOverhead,
double XFCSlvChunkSize,
double XFCBusTransportTime,
double TCalc,
double TWait,
double *SrcActiveDrainRate,
double *TInitXFill,
double *TslvChk);
static void CalculateActiveRowBandwidth(
bool GPUVMEnable,
enum source_format_class SourcePixelFormat,
double VRatio,
bool DCCEnable,
double LineTime,
unsigned int MetaRowByteLuma,
unsigned int MetaRowByteChroma,
unsigned int meta_row_height_luma,
unsigned int meta_row_height_chroma,
unsigned int PixelPTEBytesPerRowLuma,
unsigned int PixelPTEBytesPerRowChroma,
unsigned int dpte_row_height_luma,
unsigned int dpte_row_height_chroma,
double *meta_row_bw,
double *dpte_row_bw,
double *qual_row_bw);
static void CalculateFlipSchedule(
struct display_mode_lib *mode_lib,
double UrgentExtraLatency,
double UrgentLatencyPixelDataOnly,
unsigned int GPUVMMaxPageTableLevels,
bool GPUVMEnable,
double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum source_format_class SourcePixelFormat,
unsigned int ImmediateFlipBytes,
double LineTime,
double VRatio,
double Tno_bw,
double PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
bool DCCEnable,
unsigned int dpte_row_height,
unsigned int meta_row_height,
double qual_row_bw,
double *DestinationLinesToRequestVMInImmediateFlip,
double *DestinationLinesToRequestRowInImmediateFlip,
double *final_flip_bw,
bool *ImmediateFlipSupportedForPipe);
static double CalculateWriteBackDelay(
enum source_format_class WritebackPixelFormat,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackLumaHTaps,
unsigned int WritebackLumaVTaps,
unsigned int WritebackChromaHTaps,
unsigned int WritebackChromaVTaps,
unsigned int WritebackDestinationWidth);
static void dml20v2_DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
struct display_mode_lib *mode_lib);
void dml20v2_recalculate(struct display_mode_lib *mode_lib)
{
ModeSupportAndSystemConfiguration(mode_lib);
mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels * mode_lib->vba.DRAMChannelWidth,
mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000.0;
PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
dml20v2_DisplayPipeConfiguration(mode_lib);
dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
}
static double adjust_ReturnBW(
struct display_mode_lib *mode_lib,
double ReturnBW,
bool DCCEnabledAnyPlane,
double ReturnBandwidthToDCN)
{
double CriticalCompression;
if (DCCEnabledAnyPlane
&& ReturnBandwidthToDCN
> mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
ReturnBW =
dml_min(
ReturnBW,
ReturnBandwidthToDCN * 4
* (1.0
- mode_lib->vba.UrgentLatencyPixelDataOnly
/ ((mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024
/ ReturnBandwidthToDCN
- mode_lib->vba.DCFCLK
* mode_lib->vba.ReturnBusWidth
/ 4)
+ mode_lib->vba.UrgentLatencyPixelDataOnly));
CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
* mode_lib->vba.UrgentLatencyPixelDataOnly
/ (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatencyPixelDataOnly
+ (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024);
if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
ReturnBW =
dml_min(
ReturnBW,
4.0 * ReturnBandwidthToDCN
* (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024
* mode_lib->vba.ReturnBusWidth
* mode_lib->vba.DCFCLK
* mode_lib->vba.UrgentLatencyPixelDataOnly
/ dml_pow(
(ReturnBandwidthToDCN
* mode_lib->vba.UrgentLatencyPixelDataOnly
+ (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024),
2));
return ReturnBW;
}
static unsigned int dscceComputeDelay(
unsigned int bpc,
double bpp,
unsigned int sliceWidth,
unsigned int numSlices,
enum output_format_class pixelFormat)
{
unsigned int rcModelSize = 8192;
unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
Delay, pixels;
if (pixelFormat == dm_n422 || pixelFormat == dm_420)
pixelsPerClock = 2;
else
pixelsPerClock = 1;
initalXmitDelay = (unsigned int)dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
if (bpc == 8)
D = 81;
else if (bpc == 10)
D = 89;
else
D = 113;
w = sliceWidth / pixelsPerClock;
if (pixelFormat == dm_s422)
s = 1;
else
s = 0;
ix = initalXmitDelay + 45;
wx = (w + 2) / 3;
p = 3 * wx - w;
l0 = ix / w;
a = ix + p * l0;
ax = (a + 2) / 3 + D + 6 + 1;
l = (ax + wx - 1) / wx;
if ((ix % w) == 0 && p != 0)
lstall = 1;
else
lstall = 0;
Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
pixels = Delay * 3 * pixelsPerClock;
return pixels;
}
static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
{
unsigned int Delay = 0;
if (pixelFormat == dm_420) {
Delay = Delay + 2;
Delay = Delay + 0;
Delay = Delay + 3;
Delay = Delay + 2;
Delay = Delay + 12;
Delay = Delay + 13;
Delay = Delay + 2;
Delay = Delay + 7;
Delay = Delay + 3;
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 1;
} else if (pixelFormat == dm_n422) {
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 5;
Delay = Delay + 25;
Delay = Delay + 2;
Delay = Delay + 10;
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 1;
} else {
Delay = Delay + 2;
Delay = Delay + 0;
Delay = Delay + 3;
Delay = Delay + 12;
Delay = Delay + 2;
Delay = Delay + 7;
Delay = Delay + 1;
Delay = Delay + 2;
Delay = Delay + 1;
}
return Delay;
}
static bool CalculateDelayAfterScaler(
struct display_mode_lib *mode_lib,
double ReturnBW,
double ReadBandwidthPlaneLuma,
double ReadBandwidthPlaneChroma,
double TotalDataReadBandwidth,
double DisplayPipeLineDeliveryTimeLuma,
double DisplayPipeLineDeliveryTimeChroma,
double DPPCLK,
double DISPCLK,
double PixelClock,
unsigned int DSCDelay,
unsigned int DPPPerPlane,
bool ScalerEnabled,
unsigned int NumberOfCursors,
double DPPCLKDelaySubtotal,
double DPPCLKDelaySCL,
double DPPCLKDelaySCLLBOnly,
double DPPCLKDelayCNVCFormater,
double DPPCLKDelayCNVCCursor,
double DISPCLKDelaySubtotal,
unsigned int ScalerRecoutWidth,
enum output_format_class OutputFormat,
unsigned int HTotal,
unsigned int SwathWidthSingleDPPY,
double BytePerPixelDETY,
double BytePerPixelDETC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
bool Interlace,
bool ProgressiveToInterlaceUnitInOPP,
double *DSTXAfterScaler,
double *DSTYAfterScaler
)
{
(void)ReturnBW;
unsigned int DPPCycles, DISPCLKCycles;
double DataFabricLineDeliveryTimeLuma;
double DataFabricLineDeliveryTimeChroma;
double DSTTotalPixelsAfterScaler;
DataFabricLineDeliveryTimeLuma = SwathWidthSingleDPPY * SwathHeightY * dml_ceil(BytePerPixelDETY, 1) / (mode_lib->vba.ReturnBW * ReadBandwidthPlaneLuma / TotalDataReadBandwidth);
mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, DataFabricLineDeliveryTimeLuma - DisplayPipeLineDeliveryTimeLuma);
if (BytePerPixelDETC != 0) {
DataFabricLineDeliveryTimeChroma = SwathWidthSingleDPPY / 2 * SwathHeightC * dml_ceil(BytePerPixelDETC, 2) / (mode_lib->vba.ReturnBW * ReadBandwidthPlaneChroma / TotalDataReadBandwidth);
mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, DataFabricLineDeliveryTimeChroma - DisplayPipeLineDeliveryTimeChroma);
}
if (ScalerEnabled)
DPPCycles = (unsigned int)(DPPCLKDelaySubtotal + DPPCLKDelaySCL);
else
DPPCycles = (unsigned int)(DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly);
DPPCycles = (unsigned int)(DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor);
DISPCLKCycles = (unsigned int)DISPCLKDelaySubtotal;
if (DPPCLK == 0.0 || DISPCLK == 0.0)
return true;
*DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
+ DSCDelay;
if (DPPPerPlane > 1)
*DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
if (OutputFormat == dm_420 || (Interlace && ProgressiveToInterlaceUnitInOPP))
*DSTYAfterScaler = 1;
else
*DSTYAfterScaler = 0;
DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
return true;
}
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double DPPCLK,
double DISPCLK,
double PixelClock,
double DCFCLKDeepSleep,
unsigned int DPPPerPlane,
unsigned int NumberOfCursors,
unsigned int VBlank,
unsigned int HTotal,
unsigned int MaxInterDCNTileRepeaters,
unsigned int VStartup,
unsigned int PageTableLevels,
bool GPUVMEnable,
bool DynamicMetadataEnable,
unsigned int DynamicMetadataLinesBeforeActiveRequired,
unsigned int DynamicMetadataTransmittedBytes,
bool DCCEnable,
double UrgentLatencyPixelDataOnly,
double UrgentExtraLatency,
double TCalc,
unsigned int PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
double PrefetchSourceLinesY,
unsigned int SwathWidthY,
double BytePerPixelDETY,
double VInitPreFillY,
unsigned int MaxNumSwathY,
double PrefetchSourceLinesC,
double BytePerPixelDETC,
double VInitPreFillC,
unsigned int MaxNumSwathC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
double TWait,
bool XFCEnabled,
double XFCRemoteSurfaceFlipDelay,
bool InterlaceEnable,
bool ProgressiveToInterlaceUnitInOPP,
double DSTXAfterScaler,
double DSTYAfterScaler,
double *DestinationLinesForPrefetch,
double *PrefetchBandwidth,
double *DestinationLinesToRequestVMInVBlank,
double *DestinationLinesToRequestRowInVBlank,
double *VRatioPrefetchY,
double *VRatioPrefetchC,
double *RequiredPrefetchPixDataBW,
double *Tno_bw,
unsigned int *VUpdateOffsetPix,
double *VUpdateWidthPix,
double *VReadyOffsetPix)
{
(void)mode_lib;
bool MyError = false;
double TotalRepeaterDelayTime;
double Tdm, LineTime, Tsetup;
double dst_y_prefetch_equ;
double Tsw_oto;
double prefetch_bw_oto;
double Tvm_oto;
double Tr0_oto;
double Tpre_oto;
double dst_y_prefetch_oto;
double TimeForFetchingMetaPTE = 0;
double TimeForFetchingRowInVBlank = 0;
double LinesToRequestPrefetchPixelData = 0;
*VUpdateOffsetPix = (unsigned int)dml_ceil(HTotal / 4.0, 1);
TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
*VUpdateWidthPix = (14.0 / DCFCLKDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
* PixelClock;
*VReadyOffsetPix = dml_max(
150.0 / DPPCLK,
TotalRepeaterDelayTime + 20.0 / DCFCLKDeepSleep + 10.0 / DPPCLK)
* PixelClock;
Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
LineTime = (double) HTotal / PixelClock;
if (DynamicMetadataEnable) {
double Tdmbf, Tdmec, Tdmsks;
Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
Tdmec = LineTime;
if (DynamicMetadataLinesBeforeActiveRequired == 0)
Tdmsks = VBlank * LineTime / 2.0;
else
Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
Tdmsks = Tdmsks / 2;
if (VStartup * LineTime
< Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
MyError = true;
}
} else
Tdm = 0;
if (GPUVMEnable) {
if (PageTableLevels == 4)
*Tno_bw = UrgentExtraLatency + UrgentLatencyPixelDataOnly;
else if (PageTableLevels == 3)
*Tno_bw = UrgentExtraLatency;
else
*Tno_bw = 0;
} else if (DCCEnable)
*Tno_bw = LineTime;
else
*Tno_bw = LineTime / 4;
dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
- (Tsetup + Tdm) / LineTime
- (DSTYAfterScaler + DSTXAfterScaler / HTotal);
Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+ PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
/ Tsw_oto;
if (GPUVMEnable == true) {
Tvm_oto =
dml_max(
*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
dml_max(
UrgentExtraLatency
+ UrgentLatencyPixelDataOnly
* (PageTableLevels
- 1),
LineTime / 4.0));
} else
Tvm_oto = LineTime / 4.0;
if ((GPUVMEnable == true || DCCEnable == true)) {
Tr0_oto = dml_max(
(MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
dml_max(UrgentLatencyPixelDataOnly, dml_max(LineTime - Tvm_oto, LineTime / 4)));
} else
Tr0_oto = LineTime - Tvm_oto;
Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
dst_y_prefetch_oto = Tpre_oto / LineTime;
if (dst_y_prefetch_oto < dst_y_prefetch_equ)
*DestinationLinesForPrefetch = dst_y_prefetch_oto;
else
*DestinationLinesForPrefetch = dst_y_prefetch_equ;
*DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
/ 4;
dml_print("DML: VStartup: %d\n", VStartup);
dml_print("DML: TCalc: %f\n", TCalc);
dml_print("DML: TWait: %f\n", TWait);
dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
dml_print("DML: LineTime: %f\n", LineTime);
dml_print("DML: Tsetup: %f\n", Tsetup);
dml_print("DML: Tdm: %f\n", Tdm);
dml_print("DML: DSTYAfterScaler: %f\n", DSTYAfterScaler);
dml_print("DML: DSTXAfterScaler: %f\n", DSTXAfterScaler);
dml_print("DML: HTotal: %d\n", HTotal);
*PrefetchBandwidth = 0;
*DestinationLinesToRequestVMInVBlank = 0;
*DestinationLinesToRequestRowInVBlank = 0;
*VRatioPrefetchY = 0;
*VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBW = 0;
if (*DestinationLinesForPrefetch > 1) {
*PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
+ 2 * PixelPTEBytesPerRow
+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+ PrefetchSourceLinesC * SwathWidthY / 2
* dml_ceil(BytePerPixelDETC, 2))
/ (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
if (GPUVMEnable) {
TimeForFetchingMetaPTE =
dml_max(
*Tno_bw
+ (double) PDEAndMetaPTEBytesFrame
/ *PrefetchBandwidth,
dml_max(
UrgentExtraLatency
+ UrgentLatencyPixelDataOnly
* (PageTableLevels
- 1),
LineTime / 4));
} else {
if (NumberOfCursors > 0 || XFCEnabled)
TimeForFetchingMetaPTE = LineTime / 4;
else
TimeForFetchingMetaPTE = 0.0;
}
if ((GPUVMEnable == true || DCCEnable == true)) {
TimeForFetchingRowInVBlank =
dml_max(
(MetaRowByte + PixelPTEBytesPerRow)
/ *PrefetchBandwidth,
dml_max(
UrgentLatencyPixelDataOnly,
dml_max(
LineTime
- TimeForFetchingMetaPTE,
LineTime
/ 4.0)));
} else {
if (NumberOfCursors > 0 || XFCEnabled)
TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
else
TimeForFetchingRowInVBlank = 0.0;
}
*DestinationLinesToRequestVMInVBlank = dml_floor(
4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
1) / 4.0;
*DestinationLinesToRequestRowInVBlank = dml_floor(
4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
1) / 4.0;
LinesToRequestPrefetchPixelData =
*DestinationLinesForPrefetch
- ((NumberOfCursors > 0 || GPUVMEnable
|| DCCEnable) ?
(*DestinationLinesToRequestVMInVBlank
+ *DestinationLinesToRequestRowInVBlank) :
0.0);
if (LinesToRequestPrefetchPixelData > 0) {
*VRatioPrefetchY = (double) PrefetchSourceLinesY
/ LinesToRequestPrefetchPixelData;
*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
*VRatioPrefetchY =
dml_max(
(double) PrefetchSourceLinesY
/ LinesToRequestPrefetchPixelData,
(double) MaxNumSwathY
* SwathHeightY
/ (LinesToRequestPrefetchPixelData
- (VInitPreFillY
- 3.0)
/ 2.0));
*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
} else {
MyError = true;
*VRatioPrefetchY = 0;
}
}
*VRatioPrefetchC = (double) PrefetchSourceLinesC
/ LinesToRequestPrefetchPixelData;
*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
if ((SwathHeightC > 4)) {
if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
*VRatioPrefetchC =
dml_max(
*VRatioPrefetchC,
(double) MaxNumSwathC
* SwathHeightC
/ (LinesToRequestPrefetchPixelData
- (VInitPreFillC
- 3.0)
/ 2.0));
*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
} else {
MyError = true;
*VRatioPrefetchC = 0;
}
}
*RequiredPrefetchPixDataBW =
DPPPerPlane
* ((double) PrefetchSourceLinesY
/ LinesToRequestPrefetchPixelData
* dml_ceil(
BytePerPixelDETY,
1)
+ (double) PrefetchSourceLinesC
/ LinesToRequestPrefetchPixelData
* dml_ceil(
BytePerPixelDETC,
2)
/ 2)
* SwathWidthY / LineTime;
} else {
MyError = true;
*VRatioPrefetchY = 0;
*VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBW = 0;
}
} else {
MyError = true;
}
if (MyError) {
*PrefetchBandwidth = 0;
*DestinationLinesToRequestVMInVBlank = 0;
*DestinationLinesToRequestRowInVBlank = 0;
*DestinationLinesForPrefetch = 0;
*VRatioPrefetchY = 0;
*VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBW = 0;
}
return MyError;
}
static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
{
return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
}
static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
{
return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
}
static double CalculatePrefetchSourceLines(
struct display_mode_lib *mode_lib,
double VRatio,
double vtaps,
bool Interlace,
bool ProgressiveToInterlaceUnitInOPP,
unsigned int SwathHeight,
unsigned int ViewportYStart,
double *VInitPreFill,
unsigned int *MaxNumSwath)
{
unsigned int MaxPartialSwath;
if (ProgressiveToInterlaceUnitInOPP)
*VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
else
*VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
if (!mode_lib->vba.IgnoreViewportPositioning) {
*MaxNumSwath = (unsigned int)(dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0);
if (*VInitPreFill > 1.0)
MaxPartialSwath = (unsigned int)((unsigned int)(*VInitPreFill - 2) % SwathHeight);
else
MaxPartialSwath = (unsigned int)((unsigned int)(*VInitPreFill + SwathHeight - 2) % SwathHeight);
MaxPartialSwath = (unsigned int)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 = (unsigned int)dml_ceil(*VInitPreFill / SwathHeight, 1);
if (*VInitPreFill > 1.0)
MaxPartialSwath = (unsigned int)((unsigned int)(*VInitPreFill - 1) % SwathHeight);
else
MaxPartialSwath = (unsigned int)((unsigned int)(*VInitPreFill + SwathHeight - 1) % SwathHeight);
}
return *MaxNumSwath * SwathHeight + MaxPartialSwath;
}
static unsigned int CalculateVMAndRowBytes(
struct display_mode_lib *mode_lib,
bool DCCEnable,
unsigned int BlockHeight256Bytes,
unsigned int BlockWidth256Bytes,
enum source_format_class SourcePixelFormat,
unsigned int SurfaceTiling,
unsigned int BytePerPixel,
enum scan_direction_class ScanDirection,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int SwathWidth,
bool GPUVMEnable,
unsigned int VMMPageSize,
unsigned int PTEBufferSizeInRequestsLuma,
unsigned int PDEProcessingBufIn64KBReqs,
unsigned int Pitch,
unsigned int DCCMetaPitch,
unsigned int *MacroTileWidth,
unsigned int *MetaRowByte,
unsigned int *PixelPTEBytesPerRow,
bool *PTEBufferSizeNotExceeded,
unsigned int *dpte_row_height,
unsigned int *meta_row_height)
{
(void)ViewportWidth;
unsigned int MetaRequestHeight;
unsigned int MetaRequestWidth;
unsigned int MetaSurfWidth;
unsigned int MetaSurfHeight;
unsigned int MPDEBytesFrame;
unsigned int MetaPTEBytesFrame;
unsigned int DCCMetaSurfaceBytes;
unsigned int MacroTileSizeBytes;
unsigned int MacroTileHeight;
unsigned int DPDE0BytesFrame;
unsigned int ExtraDPDEBytesFrame;
unsigned int PDEAndMetaPTEBytesFrame;
if (DCCEnable == true) {
MetaRequestHeight = 8 * BlockHeight256Bytes;
MetaRequestWidth = 8 * BlockWidth256Bytes;
if (ScanDirection == dm_horz) {
*meta_row_height = (unsigned int)MetaRequestHeight;
MetaSurfWidth = (unsigned int)(dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
+ MetaRequestWidth);
*MetaRowByte = (unsigned int)(MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0);
} else {
*meta_row_height = (unsigned int)MetaRequestWidth;
MetaSurfHeight = (unsigned int)(dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
+ MetaRequestHeight);
*MetaRowByte = (unsigned int)(MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0);
}
if (ScanDirection == dm_horz) {
DCCMetaSurfaceBytes = (unsigned int)(DCCMetaPitch
* (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
+ 64 * BlockHeight256Bytes) * BytePerPixel
/ 256);
} else {
DCCMetaSurfaceBytes = (unsigned int)(DCCMetaPitch
* (dml_ceil(
(double) ViewportHeight - 1,
64 * BlockHeight256Bytes)
+ 64 * BlockHeight256Bytes) * BytePerPixel
/ 256);
}
if (GPUVMEnable == true) {
MetaPTEBytesFrame = (unsigned int)((dml_ceil(
(double) (DCCMetaSurfaceBytes - VMMPageSize)
/ (8 * VMMPageSize),
1) + 1) * 64);
MPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 1);
} else {
MetaPTEBytesFrame = 0;
MPDEBytesFrame = 0;
}
} else {
MetaPTEBytesFrame = 0;
MPDEBytesFrame = 0;
*MetaRowByte = 0;
}
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) {
MacroTileSizeBytes = 256;
MacroTileHeight = BlockHeight256Bytes;
} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
|| SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
MacroTileSizeBytes = 4096;
MacroTileHeight = 4 * BlockHeight256Bytes;
} else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
|| SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
|| SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
|| SurfaceTiling == dm_sw_64kb_r_x) {
MacroTileSizeBytes = 65536;
MacroTileHeight = 16 * BlockHeight256Bytes;
} else {
MacroTileSizeBytes = 262144;
MacroTileHeight = 32 * BlockHeight256Bytes;
}
*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
if (GPUVMEnable == true && mode_lib->vba.GPUVMMaxPageTableLevels > 1) {
if (ScanDirection == dm_horz) {
DPDE0BytesFrame =
(unsigned int)(64
* (dml_ceil(
((Pitch
* (dml_ceil(
ViewportHeight
- 1,
MacroTileHeight)
+ MacroTileHeight)
* BytePerPixel)
- MacroTileSizeBytes)
/ (8
* 2097152),
1) + 1));
} else {
DPDE0BytesFrame =
(unsigned int)(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 (GPUVMEnable == true) {
unsigned int PTERequestSize;
unsigned int PixelPTEReqHeight;
unsigned int PixelPTEReqWidth;
double FractionOfPTEReturnDrop;
unsigned int EffectivePDEProcessingBufIn64KBReqs;
if (SurfaceTiling == dm_sw_linear) {
PixelPTEReqHeight = 1;
PixelPTEReqWidth = (unsigned int)8.0 * VMMPageSize / BytePerPixel;
PTERequestSize = 64;
FractionOfPTEReturnDrop = 0;
} else if (MacroTileSizeBytes == 4096) {
PixelPTEReqHeight = MacroTileHeight;
PixelPTEReqWidth = 8 * *MacroTileWidth;
PTERequestSize = 64;
if (ScanDirection == dm_horz)
FractionOfPTEReturnDrop = 0;
else
FractionOfPTEReturnDrop = 7.0 / 8;
} else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
PixelPTEReqHeight = 16 * BlockHeight256Bytes;
PixelPTEReqWidth = 16 * BlockWidth256Bytes;
PTERequestSize = 128;
FractionOfPTEReturnDrop = 0;
} else {
PixelPTEReqHeight = MacroTileHeight;
PixelPTEReqWidth = 8 * *MacroTileWidth;
PTERequestSize = 64;
FractionOfPTEReturnDrop = 0;
}
if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
else
EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
if (SurfaceTiling == dm_sw_linear) {
*dpte_row_height = (unsigned int)(
dml_min(
128,
1
<< (unsigned int) dml_floor(
dml_log2(
dml_min(
(double) PTEBufferSizeInRequestsLuma
* PixelPTEReqWidth,
EffectivePDEProcessingBufIn64KBReqs
* 65536.0
/ BytePerPixel)
/ Pitch),
1)));
*PixelPTEBytesPerRow = PTERequestSize
* (unsigned int)(dml_ceil(
(double) (Pitch * *dpte_row_height - 1)
/ PixelPTEReqWidth,
1) + 1);
} else if (ScanDirection == dm_horz) {
*dpte_row_height = PixelPTEReqHeight;
*PixelPTEBytesPerRow = PTERequestSize
* (unsigned int)(dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
+ 1);
} else {
*dpte_row_height = (unsigned int)dml_min(PixelPTEReqWidth, *MacroTileWidth);
*PixelPTEBytesPerRow = PTERequestSize
* (unsigned int)(dml_ceil(
((double) SwathWidth - 1)
/ PixelPTEReqHeight,
1) + 1);
}
if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
<= 64 * PTEBufferSizeInRequestsLuma) {
*PTEBufferSizeNotExceeded = true;
} else {
*PTEBufferSizeNotExceeded = false;
}
} else {
*PixelPTEBytesPerRow = 0;
*PTEBufferSizeNotExceeded = true;
}
return PDEAndMetaPTEBytesFrame;
}
static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
struct display_mode_lib *mode_lib)
{
unsigned int j, k;
mode_lib->vba.WritebackDISPCLK = 0.0;
mode_lib->vba.DISPCLKWithRamping = 0;
mode_lib->vba.DISPCLKWithoutRamping = 0;
mode_lib->vba.GlobalDPPCLK = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.WritebackEnable[k]) {
mode_lib->vba.WritebackDISPCLK =
dml_max(
mode_lib->vba.WritebackDISPCLK,
CalculateWriteBackDISPCLK(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.PixelClock[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.WritebackChromaLineBufferWidth));
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.HRatio[k] > 1) {
mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ dml_ceil(
mode_lib->vba.htaps[k]
/ 6.0,
1));
} else {
mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
mode_lib->vba.DPPCLKUsingSingleDPPLuma =
mode_lib->vba.PixelClock[k]
* dml_max(
mode_lib->vba.vtaps[k] / 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]),
dml_max(
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
1.0));
if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
&& mode_lib->vba.DPPCLKUsingSingleDPPLuma
< 2 * mode_lib->vba.PixelClock[k]) {
mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
}
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
mode_lib->vba.DPPCLKUsingSingleDPP[k] =
mode_lib->vba.DPPCLKUsingSingleDPPLuma;
} else {
if (mode_lib->vba.HRatio[k] > 1) {
mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ 2
/ dml_ceil(
mode_lib->vba.HTAPsChroma[k]
/ 6.0,
1.0));
} else {
mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
mode_lib->vba.DPPCLKUsingSingleDPPChroma =
mode_lib->vba.PixelClock[k]
* dml_max(
mode_lib->vba.VTAPsChroma[k]
/ 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]
/ 2),
dml_max(
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ 4
/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
1.0));
if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
&& mode_lib->vba.DPPCLKUsingSingleDPPChroma
< 2 * mode_lib->vba.PixelClock[k]) {
mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
* mode_lib->vba.PixelClock[k];
}
mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
mode_lib->vba.DPPCLKUsingSingleDPPLuma,
mode_lib->vba.DPPCLKUsingSingleDPPChroma);
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.BlendingAndTiming[k] != k)
continue;
if (mode_lib->vba.ODMCombineEnabled[k]) {
mode_lib->vba.DISPCLKWithRamping =
dml_max(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.PixelClock[k] / 2
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100)
* (1
+ mode_lib->vba.DISPCLKRampingMargin
/ 100));
mode_lib->vba.DISPCLKWithoutRamping =
dml_max(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.PixelClock[k] / 2
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100));
} else if (!mode_lib->vba.ODMCombineEnabled[k]) {
mode_lib->vba.DISPCLKWithRamping =
dml_max(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.PixelClock[k]
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100)
* (1
+ mode_lib->vba.DISPCLKRampingMargin
/ 100));
mode_lib->vba.DISPCLKWithoutRamping =
dml_max(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.PixelClock[k]
* (1
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100));
}
}
mode_lib->vba.DISPCLKWithRamping = dml_max(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.WritebackDISPCLK);
mode_lib->vba.DISPCLKWithoutRamping = dml_max(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.WritebackDISPCLK);
ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
mode_lib->vba.DISPCLKWithRamping,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
mode_lib->vba.DISPCLKWithoutRamping,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
mode_lib->vba.soc.clock_limits[mode_lib->vba.soc.num_states].dispclk_mhz,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
mode_lib->vba.DISPCLK_calculated =
mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
} else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
} else {
mode_lib->vba.DISPCLK_calculated =
mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
}
DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.DPPPerPlane[k] == 0) {
mode_lib->vba.DPPCLK_calculated[k] = 0;
} else {
mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
/ mode_lib->vba.DPPPerPlane[k]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
}
mode_lib->vba.GlobalDPPCLK = dml_max(
mode_lib->vba.GlobalDPPCLK,
mode_lib->vba.DPPCLK_calculated[k]);
}
mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
mode_lib->vba.GlobalDPPCLK,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
* dml_ceil(
mode_lib->vba.DPPCLK_calculated[k] * 255
/ mode_lib->vba.GlobalDPPCLK,
1);
DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
}
mode_lib->vba.DCCEnabledAnyPlane = false;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
if (mode_lib->vba.DCCEnable[k])
mode_lib->vba.DCCEnabledAnyPlane = true;
mode_lib->vba.ReturnBandwidthToDCN = dml_min(
mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
mode_lib->vba.FabricAndDRAMBandwidth * 1000)
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
mode_lib->vba.ReturnBW = adjust_ReturnBW(
mode_lib,
mode_lib->vba.ReturnBW,
mode_lib->vba.DCCEnabledAnyPlane,
mode_lib->vba.ReturnBandwidthToDCN);
mode_lib->vba.ReturnBandwidthToDCN = dml_min(
mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
mode_lib->vba.FabricAndDRAMBandwidth * 1000);
mode_lib->vba.ReturnBW = adjust_ReturnBW(
mode_lib,
mode_lib->vba.ReturnBW,
mode_lib->vba.DCCEnabledAnyPlane,
mode_lib->vba.ReturnBandwidthToDCN);
DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK);
DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN);
DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
bool MainPlaneDoesODMCombine = false;
if (mode_lib->vba.SourceScan[k] == dm_horz)
mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
else
mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
MainPlaneDoesODMCombine = true;
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
MainPlaneDoesODMCombine = true;
if (MainPlaneDoesODMCombine == true)
mode_lib->vba.SwathWidthY[k] = dml_min(
(double) mode_lib->vba.SwathWidthSingleDPPY[k],
dml_round(
mode_lib->vba.HActive[k] / 2.0
* mode_lib->vba.HRatio[k]));
else {
if (mode_lib->vba.DPPPerPlane[k] == 0) {
mode_lib->vba.SwathWidthY[k] = 0;
} else {
mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
/ mode_lib->vba.DPPPerPlane[k];
}
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
mode_lib->vba.BytePerPixelDETY[k] = 8;
mode_lib->vba.BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
mode_lib->vba.BytePerPixelDETY[k] = 4;
mode_lib->vba.BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
mode_lib->vba.BytePerPixelDETY[k] = 2;
mode_lib->vba.BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
mode_lib->vba.BytePerPixelDETY[k] = 1;
mode_lib->vba.BytePerPixelDETC[k] = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
mode_lib->vba.BytePerPixelDETY[k] = 1;
mode_lib->vba.BytePerPixelDETC[k] = 2;
} else {
mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
}
}
mode_lib->vba.TotalDataReadBandwidth = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* mode_lib->vba.VRatio[k];
mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
/ 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* mode_lib->vba.VRatio[k] / 2;
DTRACE(
" read_bw[%i] = %fBps",
k,
mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ mode_lib->vba.ReadBandwidthPlaneChroma[k]);
mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ mode_lib->vba.ReadBandwidthPlaneChroma[k];
}
mode_lib->vba.TotalDCCActiveDPP = 0;
mode_lib->vba.TotalActiveDPP = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
+ mode_lib->vba.DPPPerPlane[k];
if (mode_lib->vba.DCCEnable[k])
mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
+ mode_lib->vba.DPPPerPlane[k];
}
mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
(mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
+ mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly
* mode_lib->vba.NumberOfChannels
/ mode_lib->vba.ReturnBW;
mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.VRatio[k] <= 1.0)
mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
(double) mode_lib->vba.SwathWidthY[k]
* mode_lib->vba.DPPPerPlane[k]
/ mode_lib->vba.HRatio[k]
/ mode_lib->vba.PixelClock[k];
else
mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
(double) mode_lib->vba.SwathWidthY[k]
/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
/ mode_lib->vba.DPPCLK[k];
if (mode_lib->vba.BytePerPixelDETC[k] == 0)
mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0;
else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0)
mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
mode_lib->vba.SwathWidthY[k] / 2.0
* mode_lib->vba.DPPPerPlane[k]
/ (mode_lib->vba.HRatio[k] / 2.0)
/ mode_lib->vba.PixelClock[k];
else
mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
mode_lib->vba.SwathWidthY[k] / 2.0
/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
/ mode_lib->vba.DPPCLK[k];
}
mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
+ (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
+ mode_lib->vba.TotalDCCActiveDPP
* mode_lib->vba.MetaChunkSize) * 1024.0
/ mode_lib->vba.ReturnBW;
if (mode_lib->vba.GPUVMEnable)
mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
* mode_lib->vba.PTEGroupSize / mode_lib->vba.ReturnBW;
mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatencyPixelDataOnly
+ mode_lib->vba.LastPixelOfLineExtraWatermark
+ mode_lib->vba.UrgentExtraLatency;
DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
mode_lib->vba.TotalActiveWriteback = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.WritebackEnable[k])
mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + mode_lib->vba.ActiveWritebacksPerPlane[k];
}
if (mode_lib->vba.TotalActiveWriteback <= 1)
mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
else
mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
/ mode_lib->vba.SOCCLK;
DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
+ mode_lib->vba.UrgentWatermark;
DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
DTRACE(" calculating wb pstate watermark");
DTRACE(" total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
if (mode_lib->vba.TotalActiveWriteback <= 1)
mode_lib->vba.WritebackDRAMClockChangeWatermark =
mode_lib->vba.DRAMClockChangeLatency
+ mode_lib->vba.WritebackLatency;
else
mode_lib->vba.WritebackDRAMClockChangeWatermark =
mode_lib->vba.DRAMClockChangeLatency
+ mode_lib->vba.WritebackLatency
+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
/ mode_lib->vba.SOCCLK;
DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
/ mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
mode_lib->vba.LinesInDETY[k],
mode_lib->vba.SwathHeightY[k]);
mode_lib->vba.FullDETBufferingTimeY[k] =
mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k];
if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
mode_lib->vba.LinesInDETC[k] = (unsigned int)(mode_lib->vba.DETBufferSizeC[k]
/ mode_lib->vba.BytePerPixelDETC[k]
/ (mode_lib->vba.SwathWidthY[k] / 2));
mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = (unsigned int)dml_floor(
mode_lib->vba.LinesInDETC[k],
mode_lib->vba.SwathHeightC[k]);
mode_lib->vba.FullDETBufferingTimeC[k] =
mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ (mode_lib->vba.VRatio[k] / 2);
} else {
mode_lib->vba.LinesInDETC[k] = 0;
mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
}
}
mode_lib->vba.MinFullDETBufferingTime = 999999.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.FullDETBufferingTimeY[k]
< mode_lib->vba.MinFullDETBufferingTime) {
mode_lib->vba.MinFullDETBufferingTime =
mode_lib->vba.FullDETBufferingTimeY[k];
mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
}
if (mode_lib->vba.FullDETBufferingTimeC[k]
< mode_lib->vba.MinFullDETBufferingTime) {
mode_lib->vba.MinFullDETBufferingTime =
mode_lib->vba.FullDETBufferingTimeC[k];
mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
}
}
mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.DCCEnable[k]) {
mode_lib->vba.AverageReadBandwidthGBytePerSecond =
mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
/ mode_lib->vba.DCCRate[k]
/ 1000
+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
/ mode_lib->vba.DCCRate[k]
/ 1000;
} else {
mode_lib->vba.AverageReadBandwidthGBytePerSecond =
mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
/ 1000
+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
/ 1000;
}
if (mode_lib->vba.DCCEnable[k]) {
mode_lib->vba.AverageReadBandwidthGBytePerSecond =
mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
/ 1000 / 256
+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
/ 1000 / 256;
}
if (mode_lib->vba.GPUVMEnable) {
mode_lib->vba.AverageReadBandwidthGBytePerSecond =
mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
/ 1000 / 512
+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
/ 1000 / 512;
}
}
mode_lib->vba.PartOfBurstThatFitsInROB =
dml_min(
mode_lib->vba.MinFullDETBufferingTime
* mode_lib->vba.TotalDataReadBandwidth,
mode_lib->vba.ROBBufferSizeInKByte * 1024
* mode_lib->vba.TotalDataReadBandwidth
/ (mode_lib->vba.AverageReadBandwidthGBytePerSecond
* 1000));
mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
* (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
/ mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
+ (mode_lib->vba.MinFullDETBufferingTime
* mode_lib->vba.TotalDataReadBandwidth
- mode_lib->vba.PartOfBurstThatFitsInROB)
/ (mode_lib->vba.DCFCLK * 64);
if (mode_lib->vba.TotalActiveWriteback == 0) {
mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
- (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
/ mode_lib->vba.MinFullDETBufferingTime) * 100;
} else {
mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
}
mode_lib->vba.SmallestVBlank = 999999;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
- mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
} else {
mode_lib->vba.VBlankTime = 0;
}
mode_lib->vba.SmallestVBlank = dml_min(
mode_lib->vba.SmallestVBlank,
mode_lib->vba.VBlankTime);
}
mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
* (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
- mode_lib->vba.SmallestVBlank)
+ mode_lib->vba.SmallestVBlank)
/ mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
mode_lib->vba.DCFCLKDeepSleep = 8.0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] =
dml_max(
1.1 * mode_lib->vba.SwathWidthY[k]
* dml_ceil(
mode_lib->vba.BytePerPixelDETY[k],
1) / 32
/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
* dml_ceil(
mode_lib->vba.BytePerPixelDETC[k],
2) / 32
/ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
} else
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = 1.1 * mode_lib->vba.SwathWidthY[k]
* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(
mode_lib->vba.DCFCLKDeepSleepPerPlane[k],
mode_lib->vba.PixelClock[k] / 16.0);
mode_lib->vba.DCFCLKDeepSleep = dml_max(
mode_lib->vba.DCFCLKDeepSleep,
mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
DTRACE(
" dcfclk_deepsleep_per_plane[%i] = %fMHz",
k,
mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
}
DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFCLKDeepSleep);
mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
+ mode_lib->vba.LastPixelOfLineExtraWatermark
+ mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFCLKDeepSleep;
mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
+ mode_lib->vba.LastPixelOfLineExtraWatermark
+ mode_lib->vba.UrgentExtraLatency;
DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark);
DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.EffectiveDETPlusLBLinesLuma =
dml_floor(
mode_lib->vba.LinesInDETY[k]
+ dml_min(
mode_lib->vba.LinesInDETY[k]
* mode_lib->vba.DPPCLK[k]
* mode_lib->vba.BytePerPixelDETY[k]
* mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
/ (mode_lib->vba.ReturnBW
/ mode_lib->vba.DPPPerPlane[k]),
(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
mode_lib->vba.SwathHeightY[k]);
mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k]
- mode_lib->vba.EffectiveDETPlusLBLinesLuma
* mode_lib->vba.SwathWidthY[k]
* mode_lib->vba.BytePerPixelDETY[k]
/ (mode_lib->vba.ReturnBW
/ mode_lib->vba.DPPPerPlane[k]);
if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
mode_lib->vba.EffectiveDETPlusLBLinesChroma =
dml_floor(
mode_lib->vba.LinesInDETC[k]
+ dml_min(
mode_lib->vba.LinesInDETC[k]
* mode_lib->vba.DPPCLK[k]
* mode_lib->vba.BytePerPixelDETC[k]
* mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
/ (mode_lib->vba.ReturnBW
/ mode_lib->vba.DPPPerPlane[k]),
(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
mode_lib->vba.SwathHeightC[k]);
mode_lib->vba.UrgentLatencySupportUsChroma =
mode_lib->vba.EffectiveDETPlusLBLinesChroma
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ (mode_lib->vba.VRatio[k] / 2)
- mode_lib->vba.EffectiveDETPlusLBLinesChroma
* (mode_lib->vba.SwathWidthY[k]
/ 2)
* mode_lib->vba.BytePerPixelDETC[k]
/ (mode_lib->vba.ReturnBW
/ mode_lib->vba.DPPPerPlane[k]);
mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
mode_lib->vba.UrgentLatencySupportUsLuma,
mode_lib->vba.UrgentLatencySupportUsChroma);
} else {
mode_lib->vba.UrgentLatencySupportUs[k] =
mode_lib->vba.UrgentLatencySupportUsLuma;
}
}
mode_lib->vba.MinUrgentLatencySupportUs = 999999;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
mode_lib->vba.MinUrgentLatencySupportUs,
mode_lib->vba.UrgentLatencySupportUs[k]);
}
mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
- mode_lib->vba.UrgentWatermark;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
mode_lib->vba.DSCCLK_calculated[k] = 0.0;
} else {
if (mode_lib->vba.OutputFormat[k] == dm_420
|| mode_lib->vba.OutputFormat[k] == dm_n422)
mode_lib->vba.DSCFormatFactor = 2;
else
mode_lib->vba.DSCFormatFactor = 1;
if (mode_lib->vba.ODMCombineEnabled[k])
mode_lib->vba.DSCCLK_calculated[k] =
mode_lib->vba.PixelClockBackEnd[k] / 6
/ mode_lib->vba.DSCFormatFactor
/ (1
- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100);
else
mode_lib->vba.DSCCLK_calculated[k] =
mode_lib->vba.PixelClockBackEnd[k] / 3
/ mode_lib->vba.DSCFormatFactor
/ (1
- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100);
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
double bpp = mode_lib->vba.OutputBpp[k];
unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
if (!mode_lib->vba.ODMCombineEnabled[k]) {
mode_lib->vba.DSCDelay[k] =
dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
bpp,
(unsigned int)dml_ceil(
(double) mode_lib->vba.HActive[k]
/ mode_lib->vba.NumberOfDSCSlices[k],
1),
slices,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]);
} else {
mode_lib->vba.DSCDelay[k] =
2
* (dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
bpp,
(unsigned int)dml_ceil(
(double) mode_lib->vba.HActive[k]
/ mode_lib->vba.NumberOfDSCSlices[k],
1),
(unsigned int)(slices / 2.0),
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]));
}
mode_lib->vba.DSCDelay[k] = (unsigned int)(mode_lib->vba.DSCDelay[k]
* mode_lib->vba.PixelClock[k]
/ mode_lib->vba.PixelClockBackEnd[k]);
} else {
mode_lib->vba.DSCDelay[k] = 0;
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.DSCEnabled[j])
mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
unsigned int PDEAndMetaPTEBytesFrameY;
unsigned int PixelPTEBytesPerRowY;
unsigned int MetaRowByteY;
unsigned int MetaRowByteC;
unsigned int PDEAndMetaPTEBytesFrameC;
unsigned int PixelPTEBytesPerRowC;
Calculate256BBlockSizes(
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
(unsigned int)dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
(unsigned int)dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
&mode_lib->vba.BlockHeight256BytesY[k],
&mode_lib->vba.BlockHeight256BytesC[k],
&mode_lib->vba.BlockWidth256BytesY[k],
&mode_lib->vba.BlockWidth256BytesC[k]);
PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
mode_lib->vba.BlockHeight256BytesY[k],
mode_lib->vba.BlockWidth256BytesY[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
(unsigned int)dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k],
mode_lib->vba.ViewportHeight[k],
(unsigned int)mode_lib->vba.SwathWidthY[k],
mode_lib->vba.GPUVMEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequestsLuma,
mode_lib->vba.PDEProcessingBufIn64KBReqs,
mode_lib->vba.PitchY[k],
mode_lib->vba.DCCMetaPitchY[k],
&mode_lib->vba.MacroTileWidthY[k],
&MetaRowByteY,
&PixelPTEBytesPerRowY,
&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel][0],
&mode_lib->vba.dpte_row_height[k],
&mode_lib->vba.meta_row_height[k]);
mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k],
mode_lib->vba.vtaps[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.ViewportYStartY[k],
&mode_lib->vba.VInitPreFillY[k],
&mode_lib->vba.MaxNumSwathY[k]);
if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
PDEAndMetaPTEBytesFrameC =
CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
mode_lib->vba.BlockHeight256BytesC[k],
mode_lib->vba.BlockWidth256BytesC[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
(unsigned int)dml_ceil(
mode_lib->vba.BytePerPixelDETC[k],
2),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k] / 2,
mode_lib->vba.ViewportHeight[k] / 2,
(unsigned int)mode_lib->vba.SwathWidthY[k] / 2,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequestsLuma,
mode_lib->vba.PDEProcessingBufIn64KBReqs,
mode_lib->vba.PitchC[k],
0,
&mode_lib->vba.MacroTileWidthC[k],
&MetaRowByteC,
&PixelPTEBytesPerRowC,
&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel][0],
&mode_lib->vba.dpte_row_height_chroma[k],
&mode_lib->vba.meta_row_height_chroma[k]);
mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k] / 2,
mode_lib->vba.VTAPsChroma[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.SwathHeightC[k],
mode_lib->vba.ViewportYStartC[k],
&mode_lib->vba.VInitPreFillC[k],
&mode_lib->vba.MaxNumSwathC[k]);
} else {
PixelPTEBytesPerRowC = 0;
PDEAndMetaPTEBytesFrameC = 0;
MetaRowByteC = 0;
mode_lib->vba.MaxNumSwathC[k] = 0;
mode_lib->vba.PrefetchSourceLinesC[k] = 0;
}
mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
+ PDEAndMetaPTEBytesFrameC;
mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
CalculateActiveRowBandwidth(
mode_lib->vba.GPUVMEnable,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.VRatio[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
MetaRowByteY,
MetaRowByteC,
mode_lib->vba.meta_row_height[k],
mode_lib->vba.meta_row_height_chroma[k],
PixelPTEBytesPerRowY,
PixelPTEBytesPerRowC,
mode_lib->vba.dpte_row_height[k],
mode_lib->vba.dpte_row_height_chroma[k],
&mode_lib->vba.meta_row_bw[k],
&mode_lib->vba.dpte_row_bw[k],
&mode_lib->vba.qual_row_bw[k]);
}
mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFCLKDeepSleep;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
mode_lib->vba.WritebackLatency
+ CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
(unsigned int)mode_lib->vba.WritebackDestinationWidth[k])
/ mode_lib->vba.DISPCLK;
} else
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
if (mode_lib->vba.BlendingAndTiming[j] == k
&& mode_lib->vba.WritebackEnable[j] == true) {
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
dml_max(
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
mode_lib->vba.WritebackLatency
+ CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[j],
mode_lib->vba.WritebackHRatio[j],
mode_lib->vba.WritebackVRatio[j],
mode_lib->vba.WritebackLumaHTaps[j],
mode_lib->vba.WritebackLumaVTaps[j],
mode_lib->vba.WritebackChromaHTaps[j],
mode_lib->vba.WritebackChromaVTaps[j],
(unsigned int)mode_lib->vba.WritebackDestinationWidth[j])
/ mode_lib->vba.DISPCLK);
}
}
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (mode_lib->vba.BlendingAndTiming[k] == j)
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
mode_lib->vba.VStartupLines = 13;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.MaxVStartupLines[k] = (unsigned int)(
mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
- dml_max(
1.0,
dml_ceil(
mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1)));
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
mode_lib->vba.MaximumMaxVStartupLines = (unsigned int)dml_max(
mode_lib->vba.MaximumMaxVStartupLines,
mode_lib->vba.MaxVStartupLines[k]);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.cursor_bw[k] = 0.0;
for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
* mode_lib->vba.CursorBPP[k][j] / 8.0
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* mode_lib->vba.VRatio[k];
}
do {
double MaxTotalRDBandwidth = 0;
bool DestinationLineTimesForPrefetchLessThan2 = false;
bool VRatioPrefetchMoreThan4 = false;
bool prefetch_vm_bw_valid = true;
bool prefetch_row_bw_valid = true;
double TWait = CalculateTWait(
mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.SREnterPlusExitTime);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.XFCEnabled[k] == true) {
mode_lib->vba.XFCRemoteSurfaceFlipDelay =
CalculateRemoteSurfaceFlipDelay(
mode_lib,
mode_lib->vba.VRatio[k],
mode_lib->vba.SwathWidthY[k],
dml_ceil(
mode_lib->vba.BytePerPixelDETY[k],
1),
mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k],
mode_lib->vba.XFCTSlvVupdateOffset,
mode_lib->vba.XFCTSlvVupdateWidth,
mode_lib->vba.XFCTSlvVreadyOffset,
mode_lib->vba.XFCXBUFLatencyTolerance,
mode_lib->vba.XFCFillBWOverhead,
mode_lib->vba.XFCSlvChunkSize,
mode_lib->vba.XFCBusTransportTime,
mode_lib->vba.TCalc,
TWait,
&mode_lib->vba.SrcActiveDrainRate,
&mode_lib->vba.TInitXFill,
&mode_lib->vba.TslvChk);
} else {
mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
}
CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.ReadBandwidthPlaneLuma[k], mode_lib->vba.ReadBandwidthPlaneChroma[k], mode_lib->vba.TotalDataReadBandwidth,
mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k],
mode_lib->vba.DPPCLK[k], mode_lib->vba.DISPCLK, mode_lib->vba.PixelClock[k], mode_lib->vba.DSCDelay[k], mode_lib->vba.DPPPerPlane[k], mode_lib->vba.ScalerEnabled[k], mode_lib->vba.NumberOfCursors[k],
mode_lib->vba.DPPCLKDelaySubtotal, mode_lib->vba.DPPCLKDelaySCL, mode_lib->vba.DPPCLKDelaySCLLBOnly, mode_lib->vba.DPPCLKDelayCNVCFormater, mode_lib->vba.DPPCLKDelayCNVCCursor, mode_lib->vba.DISPCLKDelaySubtotal,
(unsigned int)(mode_lib->vba.SwathWidthY[k] / mode_lib->vba.HRatio[k]), mode_lib->vba.OutputFormat[k], mode_lib->vba.HTotal[k],
(unsigned int)mode_lib->vba.SwathWidthSingleDPPY[k], mode_lib->vba.BytePerPixelDETY[k], mode_lib->vba.BytePerPixelDETC[k], mode_lib->vba.SwathHeightY[k], mode_lib->vba.SwathHeightC[k], mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP, &mode_lib->vba.DSTXAfterScaler[k], &mode_lib->vba.DSTYAfterScaler[k]);
mode_lib->vba.ErrorResult[k] =
CalculatePrefetchSchedule(
mode_lib,
mode_lib->vba.DPPCLK[k],
mode_lib->vba.DISPCLK,
mode_lib->vba.PixelClock[k],
mode_lib->vba.DCFCLKDeepSleep,
mode_lib->vba.DPPPerPlane[k],
mode_lib->vba.NumberOfCursors[k],
mode_lib->vba.VTotal[k]
- mode_lib->vba.VActive[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.MaxInterDCNTileRepeaters,
(unsigned int)dml_min(
mode_lib->vba.VStartupLines,
mode_lib->vba.MaxVStartupLines[k]),
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.DynamicMetadataEnable[k],
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
mode_lib->vba.DynamicMetadataTransmittedBytes[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.UrgentExtraLatency,
mode_lib->vba.TCalc,
(unsigned int)mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
(unsigned int)mode_lib->vba.MetaRowByte[k],
(unsigned int)mode_lib->vba.PixelPTEBytesPerRow[k],
mode_lib->vba.PrefetchSourceLinesY[k],
(unsigned int)mode_lib->vba.SwathWidthY[k],
mode_lib->vba.BytePerPixelDETY[k],
mode_lib->vba.VInitPreFillY[k],
mode_lib->vba.MaxNumSwathY[k],
mode_lib->vba.PrefetchSourceLinesC[k],
mode_lib->vba.BytePerPixelDETC[k],
mode_lib->vba.VInitPreFillC[k],
mode_lib->vba.MaxNumSwathC[k],
mode_lib->vba.SwathHeightY[k],
mode_lib->vba.SwathHeightC[k],
TWait,
mode_lib->vba.XFCEnabled[k],
mode_lib->vba.XFCRemoteSurfaceFlipDelay,
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.DSTXAfterScaler[k],
mode_lib->vba.DSTYAfterScaler[k],
&mode_lib->vba.DestinationLinesForPrefetch[k],
&mode_lib->vba.PrefetchBandwidth[k],
&mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
&mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
&mode_lib->vba.VRatioPrefetchY[k],
&mode_lib->vba.VRatioPrefetchC[k],
&mode_lib->vba.RequiredPrefetchPixDataBWLuma[k],
&mode_lib->vba.Tno_bw[k],
&mode_lib->vba.VUpdateOffsetPix[k],
&mode_lib->vba.VUpdateWidthPix[k],
&mode_lib->vba.VReadyOffsetPix[k]);
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.VStartup[k] = (unsigned int)dml_min(
mode_lib->vba.VStartupLines,
mode_lib->vba.MaxVStartupLines[k]);
if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
!= 0) {
mode_lib->vba.VStartup[k] =
mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
}
} else {
mode_lib->vba.VStartup[k] = (unsigned int)
dml_min(
mode_lib->vba.VStartupLines,
mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
mode_lib->vba.prefetch_vm_bw[k] = 0;
else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
mode_lib->vba.prefetch_vm_bw[k] =
(double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
/ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
} else {
mode_lib->vba.prefetch_vm_bw[k] = 0;
prefetch_vm_bw_valid = false;
}
if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
== 0)
mode_lib->vba.prefetch_row_bw[k] = 0;
else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
mode_lib->vba.prefetch_row_bw[k] =
(double) (mode_lib->vba.MetaRowByte[k]
+ mode_lib->vba.PixelPTEBytesPerRow[k])
/ (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
} else {
mode_lib->vba.prefetch_row_bw[k] = 0;
prefetch_row_bw_valid = false;
}
MaxTotalRDBandwidth =
MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
+ dml_max(
mode_lib->vba.prefetch_vm_bw[k],
dml_max(
mode_lib->vba.prefetch_row_bw[k],
dml_max(
mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
mode_lib->vba.RequiredPrefetchPixDataBWLuma[k])
+ mode_lib->vba.meta_row_bw[k]
+ mode_lib->vba.dpte_row_bw[k]));
if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
DestinationLineTimesForPrefetchLessThan2 = true;
if (mode_lib->vba.VRatioPrefetchY[k] > 4
|| mode_lib->vba.VRatioPrefetchC[k] > 4)
VRatioPrefetchMoreThan4 = true;
}
if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
&& prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
&& !DestinationLineTimesForPrefetchLessThan2)
mode_lib->vba.PrefetchModeSupported = true;
else {
mode_lib->vba.PrefetchModeSupported = false;
dml_print(
"DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
}
if (mode_lib->vba.PrefetchModeSupported == true) {
double final_flip_bw[DC__NUM_DPP__MAX];
unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
double total_dcn_read_bw_with_flip = 0;
mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.BandwidthAvailableForImmediateFlip =
mode_lib->vba.BandwidthAvailableForImmediateFlip
- mode_lib->vba.cursor_bw[k]
- dml_max(
mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ mode_lib->vba.qual_row_bw[k],
mode_lib->vba.PrefetchBandwidth[k]);
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
ImmediateFlipBytes[k] = 0;
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
ImmediateFlipBytes[k] = (unsigned int)(
mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+ mode_lib->vba.MetaRowByte[k]
+ mode_lib->vba.PixelPTEBytesPerRow[k]);
}
}
mode_lib->vba.TotImmediateFlipBytes = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
mode_lib->vba.TotImmediateFlipBytes =
mode_lib->vba.TotImmediateFlipBytes
+ ImmediateFlipBytes[k];
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
CalculateFlipSchedule(
mode_lib,
mode_lib->vba.UrgentExtraLatency,
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.BandwidthAvailableForImmediateFlip,
mode_lib->vba.TotImmediateFlipBytes,
mode_lib->vba.SourcePixelFormat[k],
ImmediateFlipBytes[k],
mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k],
mode_lib->vba.VRatio[k],
mode_lib->vba.Tno_bw[k],
mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
(unsigned int)mode_lib->vba.MetaRowByte[k],
(unsigned int)mode_lib->vba.PixelPTEBytesPerRow[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.dpte_row_height[k],
mode_lib->vba.meta_row_height[k],
mode_lib->vba.qual_row_bw[k],
&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
&final_flip_bw[k],
&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
total_dcn_read_bw_with_flip =
total_dcn_read_bw_with_flip
+ mode_lib->vba.cursor_bw[k]
+ dml_max(
mode_lib->vba.prefetch_vm_bw[k],
dml_max(
mode_lib->vba.prefetch_row_bw[k],
final_flip_bw[k]
+ dml_max(
mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
mode_lib->vba.RequiredPrefetchPixDataBWLuma[k])));
}
mode_lib->vba.ImmediateFlipSupported = true;
if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
mode_lib->vba.ImmediateFlipSupported = false;
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
mode_lib->vba.ImmediateFlipSupported = false;
}
}
} else {
mode_lib->vba.ImmediateFlipSupported = false;
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.ErrorResult[k]) {
mode_lib->vba.PrefetchModeSupported = false;
dml_print(
"DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
}
}
mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
} while (!((mode_lib->vba.PrefetchModeSupported
&& (!mode_lib->vba.ImmediateFlipSupport
|| mode_lib->vba.ImmediateFlipSupported))
|| mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
/ mode_lib->vba.HRatio[k]
/ mode_lib->vba.PixelClock[k];
} else {
mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
mode_lib->vba.SwathWidthY[k]
/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
/ mode_lib->vba.DPPCLK[k];
}
if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
} else {
if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
mode_lib->vba.SwathWidthY[k]
* mode_lib->vba.DPPPerPlane[k]
/ mode_lib->vba.HRatio[k]
/ mode_lib->vba.PixelClock[k];
} else {
mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
mode_lib->vba.SwathWidthY[k]
/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
/ mode_lib->vba.DPPCLK[k];
}
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
mode_lib->vba.MinTTUVBlank[k] = dml_max(
mode_lib->vba.DRAMClockChangeWatermark,
dml_max(
mode_lib->vba.StutterEnterPlusExitWatermark,
mode_lib->vba.UrgentWatermark));
} else if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 1) {
mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
mode_lib->vba.MinTTUVBlank[k] = dml_max(
mode_lib->vba.StutterEnterPlusExitWatermark,
mode_lib->vba.UrgentWatermark);
} else {
mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
}
if (!mode_lib->vba.DynamicMetadataEnable[k])
mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
+ mode_lib->vba.MinTTUVBlank[k];
}
mode_lib->vba.ActiveDPPs = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
double EffectiveLBLatencyHidingY;
double EffectiveLBLatencyHidingC;
double DPPOutputBufferLinesY;
double DPPOutputBufferLinesC;
double DPPOPPBufferingY;
double MaxDETBufferingTimeY;
double ActiveDRAMClockChangeLatencyMarginY;
mode_lib->vba.LBLatencyHidingSourceLinesY = (unsigned int)(
dml_min(
mode_lib->vba.MaxLineBufferLines,
(unsigned int) dml_floor(
(double) mode_lib->vba.LineBufferSize
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.SwathWidthY[k]
/ dml_max(
mode_lib->vba.HRatio[k],
1.0)),
1)) -(mode_lib->vba.vtaps[k] - 1));
mode_lib->vba.LBLatencyHidingSourceLinesC = (unsigned int)(
dml_min(
mode_lib->vba.MaxLineBufferLines,
(unsigned int) dml_floor(
(double) mode_lib->vba.LineBufferSize
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.SwathWidthY[k]
/ 2.0
/ dml_max(
mode_lib->vba.HRatio[k]
/ 2,
1.0)),
1))
-(mode_lib->vba.VTAPsChroma[k] - 1));
EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
/ mode_lib->vba.VRatio[k]
* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
/ (mode_lib->vba.VRatio[k] / 2)
* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
/ mode_lib->vba.SwathWidthY[k];
} else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
DPPOutputBufferLinesY = 0.5;
} else {
DPPOutputBufferLinesY = 1;
}
if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
/ (mode_lib->vba.SwathWidthY[k] / 2);
} else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
DPPOutputBufferLinesC = 0.5;
} else {
DPPOutputBufferLinesC = 1;
}
DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
+ (mode_lib->vba.LinesInDETY[k]
- mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
/ mode_lib->vba.SwathHeightY[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
+ MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
if (mode_lib->vba.ActiveDPPs > 1) {
ActiveDRAMClockChangeLatencyMarginY =
ActiveDRAMClockChangeLatencyMarginY
- (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
* mode_lib->vba.SwathHeightY[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
}
if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
* (DPPOutputBufferLinesC
+ mode_lib->vba.OPPOutputBufferLines);
double MaxDETBufferingTimeC =
mode_lib->vba.FullDETBufferingTimeC[k]
+ (mode_lib->vba.LinesInDETC[k]
- mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
/ mode_lib->vba.SwathHeightC[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
+ EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
- mode_lib->vba.DRAMClockChangeWatermark;
if (mode_lib->vba.ActiveDPPs > 1) {
ActiveDRAMClockChangeLatencyMarginC =
ActiveDRAMClockChangeLatencyMarginC
- (1
- 1
/ (mode_lib->vba.ActiveDPPs
- 1))
* mode_lib->vba.SwathHeightC[k]
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
}
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
ActiveDRAMClockChangeLatencyMarginY,
ActiveDRAMClockChangeLatencyMarginC);
} else {
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
ActiveDRAMClockChangeLatencyMarginY;
}
if (mode_lib->vba.WritebackEnable[k]) {
double WritebackDRAMClockChangeLatencyMargin;
if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
WritebackDRAMClockChangeLatencyMargin =
(double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ (mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
* 4)
- mode_lib->vba.WritebackDRAMClockChangeWatermark;
} else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
WritebackDRAMClockChangeLatencyMargin =
dml_min(
(double) mode_lib->vba.WritebackInterfaceLumaBufferSize
* 8.0 / 10,
2.0
* mode_lib->vba.WritebackInterfaceChromaBufferSize
* 8 / 10)
/ (mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]))
- mode_lib->vba.WritebackDRAMClockChangeWatermark;
} else {
WritebackDRAMClockChangeLatencyMargin =
dml_min(
(double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
2.0
* mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ (mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]))
- mode_lib->vba.WritebackDRAMClockChangeWatermark;
}
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
WritebackDRAMClockChangeLatencyMargin);
}
}
{
float SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
int PlaneWithMinActiveDRAMClockChangeMargin = -1;
mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
< mode_lib->vba.MinActiveDRAMClockChangeMargin) {
mode_lib->vba.MinActiveDRAMClockChangeMargin =
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
if (mode_lib->vba.BlendingAndTiming[k] == k) {
PlaneWithMinActiveDRAMClockChangeMargin = k;
} else {
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
if (mode_lib->vba.BlendingAndTiming[k] == j) {
PlaneWithMinActiveDRAMClockChangeMargin = j;
}
}
}
}
}
mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
mode_lib->vba.MinActiveDRAMClockChangeMargin
+ mode_lib->vba.DRAMClockChangeLatency;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (mode_lib->vba.BlendingAndTiming[k] == k))
&& !(mode_lib->vba.BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin)
&& mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
< SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank =
(float)mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
}
}
if (mode_lib->vba.DRAMClockChangeSupportsVActive &&
mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) {
mode_lib->vba.DRAMClockChangeWatermark += 25;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
if (mode_lib->vba.DRAMClockChangeWatermark >
dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark))
mode_lib->vba.MinTTUVBlank[k] += 25;
}
}
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
} else if (mode_lib->vba.DummyPStateCheck &&
mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
} else {
if ((mode_lib->vba.SynchronizedVBlank
|| mode_lib->vba.NumberOfActivePlanes == 1
|| (SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0 &&
mode_lib->vba.AllowDramClockChangeOneDisplayVactive))
&& mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vblank;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
mode_lib->vba.DRAMClockChangeSupport[0][0] =
dm_dram_clock_change_unsupported;
}
}
} else {
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_unsupported;
}
}
}
for (k = 0; k <= mode_lib->vba.soc.num_states; k++)
for (j = 0; j < 2; j++)
mode_lib->vba.DRAMClockChangeSupport[k][j] = mode_lib->vba.DRAMClockChangeSupport[0][0];
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.XFCEnabled[k] == true) {
double TWait;
mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
TWait = CalculateTWait(
mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.SREnterPlusExitTime);
mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
mode_lib,
mode_lib->vba.VRatio[k],
mode_lib->vba.SwathWidthY[k],
dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.XFCTSlvVupdateOffset,
mode_lib->vba.XFCTSlvVupdateWidth,
mode_lib->vba.XFCTSlvVreadyOffset,
mode_lib->vba.XFCXBUFLatencyTolerance,
mode_lib->vba.XFCFillBWOverhead,
mode_lib->vba.XFCSlvChunkSize,
mode_lib->vba.XFCBusTransportTime,
mode_lib->vba.TCalc,
TWait,
&mode_lib->vba.SrcActiveDrainRate,
&mode_lib->vba.TInitXFill,
&mode_lib->vba.TslvChk);
mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
dml_floor(
mode_lib->vba.XFCRemoteSurfaceFlipDelay
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1);
mode_lib->vba.XFCTransferDelay[k] =
dml_ceil(
mode_lib->vba.XFCBusTransportTime
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1);
mode_lib->vba.XFCPrechargeDelay[k] =
dml_ceil(
(mode_lib->vba.XFCBusTransportTime
+ mode_lib->vba.TInitXFill
+ mode_lib->vba.TslvChk)
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1);
mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
* mode_lib->vba.SrcActiveDrainRate;
mode_lib->vba.FinalFillMargin =
(mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]
* mode_lib->vba.SrcActiveDrainRate
+ mode_lib->vba.XFCFillConstant;
mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
* mode_lib->vba.SrcActiveDrainRate
+ mode_lib->vba.FinalFillMargin;
mode_lib->vba.RemainingFillLevel = dml_max(
0.0,
mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
/ (mode_lib->vba.SrcActiveDrainRate
* mode_lib->vba.XFCFillBWOverhead / 100);
mode_lib->vba.XFCPrefetchMargin[k] =
mode_lib->vba.XFCRemoteSurfaceFlipDelay
+ mode_lib->vba.TFinalxFill
+ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k];
} else {
mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
mode_lib->vba.XFCPrechargeDelay[k] = 0;
mode_lib->vba.XFCTransferDelay[k] = 0;
mode_lib->vba.XFCPrefetchMargin[k] = 0;
}
}
{
unsigned int VStartupMargin = 0;
bool FirstMainPlane = true;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
unsigned int Margin = (unsigned int)((mode_lib->vba.MaxVStartupLines[k] - mode_lib->vba.VStartup[k])
* mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
if (FirstMainPlane) {
VStartupMargin = Margin;
FirstMainPlane = false;
} else
VStartupMargin = (unsigned int)dml_min(VStartupMargin, Margin);
}
if (mode_lib->vba.UseMaximumVStartup) {
if (mode_lib->vba.VTotal_Max[k] == mode_lib->vba.VTotal[k]) {
mode_lib->vba.VStartup[k] = mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]];
}
}
}
}
}
static void dml20v2_DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
{
double BytePerPixDETY;
double BytePerPixDETC;
double Read256BytesBlockHeightY;
double Read256BytesBlockHeightC;
double Read256BytesBlockWidthY;
double Read256BytesBlockWidthC;
double MaximumSwathHeightY;
double MaximumSwathHeightC;
double MinimumSwathHeightY;
double MinimumSwathHeightC;
double SwathWidth;
double SwathWidthGranularityY;
double SwathWidthGranularityC;
double RoundedUpMaxSwathSizeBytesY;
double RoundedUpMaxSwathSizeBytesC;
unsigned int j, k;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
bool MainPlaneDoesODMCombine = false;
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
BytePerPixDETY = 8;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
BytePerPixDETY = 4;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
BytePerPixDETY = 2;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
BytePerPixDETY = 1;
BytePerPixDETC = 0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
BytePerPixDETY = 1;
BytePerPixDETC = 2;
} else {
BytePerPixDETY = 4.0 / 3.0;
BytePerPixDETC = 8.0 / 3.0;
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
Read256BytesBlockHeightY = 1;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
Read256BytesBlockHeightY = 4;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
Read256BytesBlockHeightY = 8;
} else {
Read256BytesBlockHeightY = 16;
}
Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
/ Read256BytesBlockHeightY;
Read256BytesBlockHeightC = 0;
Read256BytesBlockWidthC = 0;
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
Read256BytesBlockHeightY = 1;
Read256BytesBlockHeightC = 1;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
Read256BytesBlockHeightY = 16;
Read256BytesBlockHeightC = 8;
} else {
Read256BytesBlockHeightY = 8;
Read256BytesBlockHeightC = 8;
}
Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
/ Read256BytesBlockHeightY;
Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
/ Read256BytesBlockHeightC;
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
MaximumSwathHeightY = Read256BytesBlockHeightY;
MaximumSwathHeightC = Read256BytesBlockHeightC;
} else {
MaximumSwathHeightY = Read256BytesBlockWidthY;
MaximumSwathHeightC = Read256BytesBlockWidthC;
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_t
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s_x)
&& mode_lib->vba.SourceScan[k] == dm_horz)) {
MinimumSwathHeightY = MaximumSwathHeightY;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
&& mode_lib->vba.SourceScan[k] != dm_horz) {
MinimumSwathHeightY = MaximumSwathHeightY;
} else {
MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
}
MinimumSwathHeightC = MaximumSwathHeightC;
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
MinimumSwathHeightY = MaximumSwathHeightY;
MinimumSwathHeightC = MaximumSwathHeightC;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
&& mode_lib->vba.SourceScan[k] == dm_horz) {
MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
MinimumSwathHeightC = MaximumSwathHeightC;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
&& mode_lib->vba.SourceScan[k] == dm_horz) {
MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
MinimumSwathHeightY = MaximumSwathHeightY;
} else {
MinimumSwathHeightY = MaximumSwathHeightY;
MinimumSwathHeightC = MaximumSwathHeightC;
}
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
SwathWidth = mode_lib->vba.ViewportWidth[k];
} else {
SwathWidth = mode_lib->vba.ViewportHeight[k];
}
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
MainPlaneDoesODMCombine = true;
}
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
MainPlaneDoesODMCombine = true;
}
}
if (MainPlaneDoesODMCombine == true) {
SwathWidth = dml_min(
SwathWidth,
mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
} else {
if (mode_lib->vba.DPPPerPlane[k] == 0)
SwathWidth = 0;
else
SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
}
SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
RoundedUpMaxSwathSizeBytesY = (dml_ceil(
(double) (SwathWidth - 1),
SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
* MaximumSwathHeightY;
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
+ 256;
}
if (MaximumSwathHeightC > 0) {
SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
/ MaximumSwathHeightC;
RoundedUpMaxSwathSizeBytesC = (dml_ceil(
(double) (SwathWidth / 2.0 - 1),
SwathWidthGranularityC) + SwathWidthGranularityC)
* BytePerPixDETC * MaximumSwathHeightC;
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
RoundedUpMaxSwathSizeBytesC = dml_ceil(
RoundedUpMaxSwathSizeBytesC,
256) + 256;
}
} else
RoundedUpMaxSwathSizeBytesC = 0.0;
if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
<= mode_lib->vba.DETBufferSizeInKByte[0] * 1024.0 / 2.0) {
mode_lib->vba.SwathHeightY[k] = (unsigned int)MaximumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = (unsigned int)MaximumSwathHeightC;
} else {
mode_lib->vba.SwathHeightY[k] = (unsigned int)MinimumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = (unsigned int)MinimumSwathHeightC;
}
if (mode_lib->vba.SwathHeightC[k] == 0) {
mode_lib->vba.DETBufferSizeY[k] = (unsigned int)(mode_lib->vba.DETBufferSizeInKByte[0] * 1024);
mode_lib->vba.DETBufferSizeC[k] = 0;
} else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
mode_lib->vba.DETBufferSizeY[k] = (unsigned int)(mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 / 2);
mode_lib->vba.DETBufferSizeC[k] = (unsigned int)(mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 / 2);
} else {
mode_lib->vba.DETBufferSizeY[k] = (unsigned int)(mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 * 2 / 3);
mode_lib->vba.DETBufferSizeC[k] = (unsigned int)(mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 / 3);
}
}
}
static double CalculateTWait(
unsigned int PrefetchMode,
double DRAMClockChangeLatency,
double UrgentLatencyPixelDataOnly,
double SREnterPlusExitTime)
{
if (PrefetchMode == 0) {
return dml_max(
DRAMClockChangeLatency + UrgentLatencyPixelDataOnly,
dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly));
} else if (PrefetchMode == 1) {
return dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly);
} else {
return UrgentLatencyPixelDataOnly;
}
}
static double CalculateRemoteSurfaceFlipDelay(
struct display_mode_lib *mode_lib,
double VRatio,
double SwathWidth,
double Bpp,
double LineTime,
double XFCTSlvVupdateOffset,
double XFCTSlvVupdateWidth,
double XFCTSlvVreadyOffset,
double XFCXBUFLatencyTolerance,
double XFCFillBWOverhead,
double XFCSlvChunkSize,
double XFCBusTransportTime,
double TCalc,
double TWait,
double *SrcActiveDrainRate,
double *TInitXFill,
double *TslvChk)
{
(void)mode_lib;
double TSlvSetup, AvgfillRate, result;
*SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
*TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
*TslvChk = XFCSlvChunkSize / AvgfillRate;
dml_print(
"DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
*SrcActiveDrainRate);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill;
dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
return result;
}
static double CalculateWriteBackDelay(
enum source_format_class WritebackPixelFormat,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackLumaHTaps,
unsigned int WritebackLumaVTaps,
unsigned int WritebackChromaHTaps,
unsigned int WritebackChromaVTaps,
unsigned int WritebackDestinationWidth)
{
double CalculateWriteBackDelay =
dml_max(
dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
* dml_ceil(
WritebackDestinationWidth
/ 4.0,
1)
+ dml_ceil(1.0 / WritebackVRatio, 1)
* (dml_ceil(
WritebackLumaVTaps
/ 4.0,
1) + 4));
if (WritebackPixelFormat != dm_444_32) {
CalculateWriteBackDelay =
dml_max(
CalculateWriteBackDelay,
dml_max(
dml_ceil(
WritebackChromaHTaps
/ 2.0,
1)
/ (2
* WritebackHRatio),
WritebackChromaVTaps
* dml_ceil(
1
/ (2
* WritebackVRatio),
1)
* dml_ceil(
WritebackDestinationWidth
/ 2.0
/ 2.0,
1)
+ dml_ceil(
1
/ (2
* WritebackVRatio),
1)
* (dml_ceil(
WritebackChromaVTaps
/ 4.0,
1)
+ 4)));
}
return CalculateWriteBackDelay;
}
static void CalculateActiveRowBandwidth(
bool GPUVMEnable,
enum source_format_class SourcePixelFormat,
double VRatio,
bool DCCEnable,
double LineTime,
unsigned int MetaRowByteLuma,
unsigned int MetaRowByteChroma,
unsigned int meta_row_height_luma,
unsigned int meta_row_height_chroma,
unsigned int PixelPTEBytesPerRowLuma,
unsigned int PixelPTEBytesPerRowChroma,
unsigned int dpte_row_height_luma,
unsigned int dpte_row_height_chroma,
double *meta_row_bw,
double *dpte_row_bw,
double *qual_row_bw)
{
if (DCCEnable != true) {
*meta_row_bw = 0;
} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
+ VRatio / 2 * MetaRowByteChroma
/ (meta_row_height_chroma * LineTime);
} else {
*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
}
if (GPUVMEnable != true) {
*dpte_row_bw = 0;
} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
+ VRatio / 2 * PixelPTEBytesPerRowChroma
/ (dpte_row_height_chroma * LineTime);
} else {
*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
}
if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
*qual_row_bw = *meta_row_bw + *dpte_row_bw;
} else {
*qual_row_bw = 0;
}
}
static void CalculateFlipSchedule(
struct display_mode_lib *mode_lib,
double UrgentExtraLatency,
double UrgentLatencyPixelDataOnly,
unsigned int GPUVMMaxPageTableLevels,
bool GPUVMEnable,
double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum source_format_class SourcePixelFormat,
unsigned int ImmediateFlipBytes,
double LineTime,
double VRatio,
double Tno_bw,
double PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
bool DCCEnable,
unsigned int dpte_row_height,
unsigned int meta_row_height,
double qual_row_bw,
double *DestinationLinesToRequestVMInImmediateFlip,
double *DestinationLinesToRequestRowInImmediateFlip,
double *final_flip_bw,
bool *ImmediateFlipSupportedForPipe)
{
double min_row_time = 0.0;
if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
*DestinationLinesToRequestVMInImmediateFlip = 0.0;
*DestinationLinesToRequestRowInImmediateFlip = 0.0;
*final_flip_bw = qual_row_bw;
*ImmediateFlipSupportedForPipe = true;
} else {
double TimeForFetchingMetaPTEImmediateFlip;
double TimeForFetchingRowInVBlankImmediateFlip;
if (GPUVMEnable == true) {
mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
* ImmediateFlipBytes / TotImmediateFlipBytes;
TimeForFetchingMetaPTEImmediateFlip =
dml_max(
Tno_bw
+ PDEAndMetaPTEBytesFrame
/ mode_lib->vba.ImmediateFlipBW[0],
dml_max(
UrgentExtraLatency
+ UrgentLatencyPixelDataOnly
* (GPUVMMaxPageTableLevels
- 1),
LineTime / 4.0));
} else {
TimeForFetchingMetaPTEImmediateFlip = 0;
}
*DestinationLinesToRequestVMInImmediateFlip = dml_floor(
4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
1) / 4.0;
if ((GPUVMEnable == true || DCCEnable == true)) {
mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
* ImmediateFlipBytes / TotImmediateFlipBytes;
TimeForFetchingRowInVBlankImmediateFlip = dml_max(
(MetaRowByte + PixelPTEBytesPerRow)
/ mode_lib->vba.ImmediateFlipBW[0],
dml_max(UrgentLatencyPixelDataOnly, LineTime / 4.0));
} else {
TimeForFetchingRowInVBlankImmediateFlip = 0;
}
*DestinationLinesToRequestRowInImmediateFlip = dml_floor(
4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
1) / 4.0;
if (GPUVMEnable == true) {
*final_flip_bw =
dml_max(
PDEAndMetaPTEBytesFrame
/ (*DestinationLinesToRequestVMInImmediateFlip
* LineTime),
(MetaRowByte + PixelPTEBytesPerRow)
/ (TimeForFetchingRowInVBlankImmediateFlip
* LineTime));
} else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
*final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
/ (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
} else {
*final_flip_bw = 0;
}
if (GPUVMEnable && !DCCEnable)
min_row_time = dpte_row_height * LineTime / VRatio;
else if (!GPUVMEnable && DCCEnable)
min_row_time = meta_row_height * LineTime / VRatio;
else
min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
/ VRatio;
if (*DestinationLinesToRequestVMInImmediateFlip >= 8
|| *DestinationLinesToRequestRowInImmediateFlip >= 16
|| TimeForFetchingMetaPTEImmediateFlip
+ 2 * TimeForFetchingRowInVBlankImmediateFlip
> min_row_time)
*ImmediateFlipSupportedForPipe = false;
else
*ImmediateFlipSupportedForPipe = true;
}
}
static unsigned int TruncToValidBPP(
double DecimalBPP,
double DesiredBPP,
bool DSCEnabled,
enum output_encoder_class Output,
enum output_format_class Format,
unsigned int DSCInputBitPerComponent)
{
if (Output == dm_hdmi) {
if (Format == dm_420) {
if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else if (DecimalBPP >= 15 && (DesiredBPP == 0 || DesiredBPP == 15))
return 15;
else if (DecimalBPP >= 12 && (DesiredBPP == 0 || DesiredBPP == 12))
return 12;
else
return BPP_INVALID;
} else if (Format == dm_444) {
if (DecimalBPP >= 36 && (DesiredBPP == 0 || DesiredBPP == 36))
return 36;
else if (DecimalBPP >= 30 && (DesiredBPP == 0 || DesiredBPP == 30))
return 30;
else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else
return BPP_INVALID;
} else {
if (DecimalBPP / 1.5 >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP / 1.5 >= 20 && (DesiredBPP == 0 || DesiredBPP == 20))
return 20;
else if (DecimalBPP / 1.5 >= 16 && (DesiredBPP == 0 || DesiredBPP == 16))
return 16;
else
return BPP_INVALID;
}
} else {
if (DSCEnabled) {
if (Format == dm_420) {
if (DesiredBPP == 0) {
if (DecimalBPP < 6)
return BPP_INVALID;
else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1.0 / 16.0)
return (unsigned int)(1.5 * DSCInputBitPerComponent - 1.0 / 16.0);
else
return (unsigned int)(dml_floor(16 * DecimalBPP, 1) / 16.0);
} else {
if (DecimalBPP < 6
|| DesiredBPP < 6
|| DesiredBPP > 1.5 * DSCInputBitPerComponent - 1.0 / 16.0
|| DecimalBPP < DesiredBPP) {
return BPP_INVALID;
} else {
return (unsigned int)DesiredBPP;
}
}
} else if (Format == dm_n422) {
if (DesiredBPP == 0) {
if (DecimalBPP < 7)
return BPP_INVALID;
else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1.0 / 16.0)
return (unsigned int)(2 * DSCInputBitPerComponent - 1.0 / 16.0);
else
return (unsigned int)(dml_floor(16 * DecimalBPP, 1) / 16.0);
} else {
if (DecimalBPP < 7
|| DesiredBPP < 7
|| DesiredBPP > 2 * DSCInputBitPerComponent - 1.0 / 16.0
|| DecimalBPP < DesiredBPP) {
return BPP_INVALID;
} else {
return (unsigned int)DesiredBPP;
}
}
} else {
if (DesiredBPP == 0) {
if (DecimalBPP < 8)
return BPP_INVALID;
else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1.0 / 16.0)
return (unsigned int)(3 * DSCInputBitPerComponent - 1.0 / 16.0);
else
return (unsigned int)(dml_floor(16 * DecimalBPP, 1) / 16.0);
} else {
if (DecimalBPP < 8
|| DesiredBPP < 8
|| DesiredBPP > 3 * DSCInputBitPerComponent - 1.0 / 16.0
|| DecimalBPP < DesiredBPP) {
return BPP_INVALID;
} else {
return (unsigned int)DesiredBPP;
}
}
}
} else if (Format == dm_420) {
if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else if (DecimalBPP >= 15 && (DesiredBPP == 0 || DesiredBPP == 15))
return 15;
else if (DecimalBPP >= 12 && (DesiredBPP == 0 || DesiredBPP == 12))
return 12;
else
return BPP_INVALID;
} else if (Format == dm_s422 || Format == dm_n422) {
if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP >= 20 && (DesiredBPP == 0 || DesiredBPP == 20))
return 20;
else if (DecimalBPP >= 16 && (DesiredBPP == 0 || DesiredBPP == 16))
return 16;
else
return BPP_INVALID;
} else {
if (DecimalBPP >= 36 && (DesiredBPP == 0 || DesiredBPP == 36))
return 36;
else if (DecimalBPP >= 30 && (DesiredBPP == 0 || DesiredBPP == 30))
return 30;
else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
return 24;
else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
return 18;
else
return BPP_INVALID;
}
}
}
void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
{
struct vba_vars_st *locals = &mode_lib->vba;
int idx;
unsigned int i, j, k, m;
mode_lib->vba.ScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ScalerEnabled[k] == false
&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
|| mode_lib->vba.HRatio[k] != 1.0
|| mode_lib->vba.htaps[k] != 1.0
|| mode_lib->vba.VRatio[k] != 1.0
|| mode_lib->vba.vtaps[k] != 1.0)) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
|| (mode_lib->vba.htaps[k] > 1.0
&& (mode_lib->vba.htaps[k] % 2) == 1)
|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
&& (mode_lib->vba.HRatio[k] / 2.0
> mode_lib->vba.HTAPsChroma[k]
|| mode_lib->vba.VRatio[k] / 2.0
> mode_lib->vba.VTAPsChroma[k]))) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
}
}
mode_lib->vba.SourceFormatPixelAndScanSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
&& mode_lib->vba.SourceScan[k] != dm_horz)
|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10))
|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_gfx7_2d_thin_l_vp)
&& !((mode_lib->vba.SourcePixelFormat[k]
== dm_444_64
|| mode_lib->vba.SourcePixelFormat[k]
== dm_444_32)
&& mode_lib->vba.SourceScan[k]
== dm_horz
&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
== true
&& mode_lib->vba.DCCEnable[k]
== false))
|| (mode_lib->vba.DCCEnable[k] == true
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_linear
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10)))) {
mode_lib->vba.SourceFormatPixelAndScanSupport = false;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
locals->BytePerPixelInDETY[k] = 8.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
locals->BytePerPixelInDETY[k] = 4.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
locals->BytePerPixelInDETY[k] = 2.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
locals->BytePerPixelInDETY[k] = 1.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
locals->BytePerPixelInDETY[k] = 1.0;
locals->BytePerPixelInDETC[k] = 2.0;
} else {
locals->BytePerPixelInDETY[k] = 4.0 / 3;
locals->BytePerPixelInDETC[k] = 8.0 / 3;
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
} else {
locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->ReadBandwidthLuma[k] = locals->SwathWidthYSingleDPP[k] * dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
locals->ReadBandwidthChroma[k] = locals->SwathWidthYSingleDPP[k] / 2 * dml_ceil(locals->BytePerPixelInDETC[k], 2.0)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k] / 2.0;
locals->ReadBandwidth[k] = locals->ReadBandwidthLuma[k] + locals->ReadBandwidthChroma[k];
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 4.0;
} else if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 3.0;
} else if (mode_lib->vba.WritebackEnable[k] == true) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 1.5;
} else {
locals->WriteBandwidth[k] = 0.0;
}
}
mode_lib->vba.DCCEnabledInAnyPlane = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.DCCEnabledInAnyPlane = true;
}
}
mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
* mode_lib->vba.DRAMChannelWidth,
mode_lib->vba.FabricClockPerState[i]
* mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000;
locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth * locals->DCFCLKPerState[i],
locals->FabricAndDRAMBandwidthPerState[i] * 1000)
* locals->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
locals->ReturnBWPerState[i][0] = locals->ReturnBWToDCNPerState;
if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
* locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
}
locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
4 * locals->ReturnBWToDCNPerState *
(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
}
locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth *
locals->DCFCLKPerState[i], locals->FabricAndDRAMBandwidthPerState[i] * 1000);
if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
* locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
}
locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
4 * locals->ReturnBWToDCNPerState *
(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
}
}
mode_lib->vba.WritebackLatencySupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
if (locals->WriteBandwidth[k]
> (mode_lib->vba.WritebackInterfaceLumaBufferSize
+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ mode_lib->vba.WritebackLatency) {
mode_lib->vba.WritebackLatencySupport = false;
}
} else {
if (locals->WriteBandwidth[k]
> 1.5
* dml_min(
mode_lib->vba.WritebackInterfaceLumaBufferSize,
2.0
* mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ mode_lib->vba.WritebackLatency) {
mode_lib->vba.WritebackLatencySupport = false;
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
(mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i][0];
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i][0]
> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
locals->ROBSupport[i][0] = true;
} else {
locals->ROBSupport[i][0] = false;
}
}
mode_lib->vba.TotalNumberOfActiveWriteback = 0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.ActiveWritebacksPerPlane[k] == 0)
mode_lib->vba.ActiveWritebacksPerPlane[k] = 1;
mode_lib->vba.TotalNumberOfActiveWriteback =
mode_lib->vba.TotalNumberOfActiveWriteback
+ mode_lib->vba.ActiveWritebacksPerPlane[k];
}
}
mode_lib->vba.WritebackModeSupport = true;
if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
mode_lib->vba.WritebackModeSupport = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.Writeback10bpc420Supported != true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
mode_lib->vba.WritebackModeSupport = false;
}
}
mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
&& (mode_lib->vba.WritebackHRatio[k] != 1.0
|| mode_lib->vba.WritebackVRatio[k] != 1.0)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
|| mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackMaxVSCLRatio
|| mode_lib->vba.WritebackHRatio[k]
< mode_lib->vba.WritebackMinHSCLRatio
|| mode_lib->vba.WritebackVRatio[k]
< mode_lib->vba.WritebackMinVSCLRatio
|| mode_lib->vba.WritebackLumaHTaps[k]
> mode_lib->vba.WritebackMaxHSCLTaps
|| mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackMaxVSCLTaps
|| mode_lib->vba.WritebackHRatio[k]
> mode_lib->vba.WritebackLumaHTaps[k]
|| mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackLumaVTaps[k]
|| (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
&& ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
== 1))
|| (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
&& (mode_lib->vba.WritebackChromaHTaps[k]
> mode_lib->vba.WritebackMaxHSCLTaps
|| mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackMaxVSCLTaps
|| 2.0
* mode_lib->vba.WritebackHRatio[k]
> mode_lib->vba.WritebackChromaHTaps[k]
|| 2.0
* mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackChromaVTaps[k]
|| (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
&& ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
mode_lib->vba.WritebackLumaVExtra =
dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
} else {
mode_lib->vba.WritebackLumaVExtra = -1;
}
if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
&& mode_lib->vba.WritebackLumaVTaps[k]
> (mode_lib->vba.WritebackLineBufferLumaBufferSize
+ mode_lib->vba.WritebackLineBufferChromaBufferSize)
/ 3.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
&& mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackLineBufferLumaBufferSize
* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
&& mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackLineBufferLumaBufferSize
* 8.0 / 10.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
mode_lib->vba.WritebackChromaVExtra = 0.0;
} else {
mode_lib->vba.WritebackChromaVExtra = -1;
}
if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
&& mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackLineBufferChromaBufferSize
* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackChromaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
&& mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackLineBufferChromaBufferSize
* 8.0 / 10.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackChromaVExtra)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
}
}
mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.WritebackRequiredDISPCLK =
dml_max(
mode_lib->vba.WritebackRequiredDISPCLK,
CalculateWriteBackDISPCLK(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.PixelClock[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.WritebackChromaLineBufferWidth));
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.HRatio[k] > 1.0) {
locals->PSCL_FACTOR[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ dml_ceil(
mode_lib->vba.htaps[k]
/ 6.0,
1.0));
} else {
locals->PSCL_FACTOR[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
if (locals->BytePerPixelInDETC[k] == 0.0) {
locals->PSCL_FACTOR_CHROMA[k] = 0.0;
locals->MinDPPCLKUsingSingleDPP[k] =
mode_lib->vba.PixelClock[k]
* dml_max3(
mode_lib->vba.vtaps[k] / 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]),
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ locals->PSCL_FACTOR[k],
1.0);
if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
&& locals->MinDPPCLKUsingSingleDPP[k]
< 2.0 * mode_lib->vba.PixelClock[k]) {
locals->MinDPPCLKUsingSingleDPP[k] = 2.0
* mode_lib->vba.PixelClock[k];
}
} else {
if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
locals->PSCL_FACTOR_CHROMA[k] =
dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput
* mode_lib->vba.HRatio[k]
/ 2.0
/ dml_ceil(
mode_lib->vba.HTAPsChroma[k]
/ 6.0,
1.0));
} else {
locals->PSCL_FACTOR_CHROMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
locals->MinDPPCLKUsingSingleDPP[k] =
mode_lib->vba.PixelClock[k]
* dml_max5(
mode_lib->vba.vtaps[k] / 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]),
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ locals->PSCL_FACTOR[k],
mode_lib->vba.VTAPsChroma[k]
/ 6.0
* dml_min(
1.0,
mode_lib->vba.HRatio[k]
/ 2.0),
mode_lib->vba.HRatio[k]
* mode_lib->vba.VRatio[k]
/ 4.0
/ locals->PSCL_FACTOR_CHROMA[k],
1.0);
if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
|| mode_lib->vba.HTAPsChroma[k] > 6.0
|| mode_lib->vba.VTAPsChroma[k] > 6.0)
&& locals->MinDPPCLKUsingSingleDPP[k]
< 2.0 * mode_lib->vba.PixelClock[k]) {
locals->MinDPPCLKUsingSingleDPP[k] = 2.0
* mode_lib->vba.PixelClock[k];
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
Calculate256BBlockSizes(
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
(unsigned int)dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
(unsigned int)dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
&locals->Read256BlockHeightY[k],
&locals->Read256BlockHeightC[k],
&locals->Read256BlockWidthY[k],
&locals->Read256BlockWidthC[k]);
if (mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MaxSwathHeightY[k] = locals->Read256BlockHeightY[k];
locals->MaxSwathHeightC[k] = locals->Read256BlockHeightC[k];
} else {
locals->MaxSwathHeightY[k] = locals->Read256BlockWidthY[k];
locals->MaxSwathHeightC[k] = locals->Read256BlockWidthC[k];
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_t
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s_x)
&& mode_lib->vba.SourceScan[k] == dm_horz)) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
} else {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
/ 2.0;
}
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
&& mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
/ 2.0;
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
&& mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k]
/ 2.0;
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
} else {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
}
}
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
} else {
mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
}
mode_lib->vba.MaximumSwathWidthInDETBuffer =
dml_min(
mode_lib->vba.MaximumSwathWidthSupport,
mode_lib->vba.DETBufferSizeInKByte[0] * 1024.0 / 2.0
/ (locals->BytePerPixelInDETY[k]
* locals->MinSwathHeightY[k]
+ locals->BytePerPixelInDETC[k]
/ 2.0
* locals->MinSwathHeightC[k]));
if (locals->BytePerPixelInDETC[k] == 0.0) {
mode_lib->vba.MaximumSwathWidthInLineBuffer =
mode_lib->vba.LineBufferSize
* dml_max(mode_lib->vba.HRatio[k], 1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.vtaps[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k],
1.0)
- 2,
0.0));
} else {
mode_lib->vba.MaximumSwathWidthInLineBuffer =
dml_min(
mode_lib->vba.LineBufferSize
* dml_max(
mode_lib->vba.HRatio[k],
1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.vtaps[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k],
1.0)
- 2,
0.0)),
2.0 * mode_lib->vba.LineBufferSize
* dml_max(
mode_lib->vba.HRatio[k]
/ 2.0,
1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.VTAPsChroma[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k]
/ 2.0,
1.0)
- 2,
0.0)));
}
locals->MaximumSwathWidth[k] = dml_min(
mode_lib->vba.MaximumSwathWidthInDETBuffer,
mode_lib->vba.MaximumSwathWidthInLineBuffer);
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown(
mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states],
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
for (j = 0; j < 2; j++) {
mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
mode_lib->vba.MaxDispclk[i],
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
mode_lib->vba.MaxDppclk[i],
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
locals->RequiredDISPCLK[i][j] = 0.0;
locals->DISPCLK_DPPCLK_Support[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
mode_lib->vba.PixelClock[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
if (mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine >= mode_lib->vba.MaxDispclk[i]
&& i == mode_lib->vba.soc.num_states)
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = mode_lib->vba.PixelClock[k]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
if (mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine >= mode_lib->vba.MaxDispclk[i]
&& i == mode_lib->vba.soc.num_states)
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
if (mode_lib->vba.ODMCapability) {
if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
} else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN20_MAX_DSC_IMAGE_WIDTH)) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
} else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
}
}
if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
&& locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
locals->NoOfDPP[i][j][k] = 1;
locals->RequiredDPPCLK[i][j][k] =
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
} else {
locals->NoOfDPP[i][j][k] = 2;
locals->RequiredDPPCLK[i][j][k] =
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.PlaneRequiredDISPCLK);
if ((locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
|| (mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
}
locals->TotalNumberOfActiveDPP[i][j] = (unsigned int)0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
if (j == 1) {
while (locals->TotalNumberOfActiveDPP[i][j] < mode_lib->vba.MaxNumDPP
&& locals->TotalNumberOfActiveDPP[i][j] < 2 * mode_lib->vba.NumberOfActivePlanes) {
double BWOfNonSplitPlaneOfMaximumBandwidth;
unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
BWOfNonSplitPlaneOfMaximumBandwidth = 0;
NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (locals->ReadBandwidth[k] > BWOfNonSplitPlaneOfMaximumBandwidth && locals->NoOfDPP[i][j][k] == 1) {
BWOfNonSplitPlaneOfMaximumBandwidth = locals->ReadBandwidth[k];
NumberOfNonSplitPlaneOfMaximumBandwidth = k;
}
}
locals->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
locals->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
locals->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + 1;
}
}
if (locals->TotalNumberOfActiveDPP[i][j] > mode_lib->vba.MaxNumDPP) {
locals->RequiredDISPCLK[i][j] = 0.0;
locals->DISPCLK_DPPCLK_Support[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
locals->NoOfDPP[i][j][k] = 1;
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
} else {
locals->NoOfDPP[i][j][k] = 2;
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
}
if (i != mode_lib->vba.soc.num_states) {
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PixelClock[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
} else {
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PixelClock[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.PlaneRequiredDISPCLK);
if (locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
|| mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
locals->TotalNumberOfActiveDPP[i][j] = (unsigned int)0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.WritebackRequiredDISPCLK);
if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
< mode_lib->vba.WritebackRequiredDISPCLK) {
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->ViewportSizeSupport[i][0] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
> locals->MaximumSwathWidth[k]) {
locals->ViewportSizeSupport[i][0] = false;
}
} else {
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
locals->ViewportSizeSupport[i][0] = false;
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
if (locals->TotalNumberOfActiveDPP[i][j] <= mode_lib->vba.MaxNumDPP)
locals->TotalAvailablePipesSupport[i][j] = true;
else
locals->TotalAvailablePipesSupport[i][j] = false;
}
}
mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+ 1.0;
}
}
if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
mode_lib->vba.NumberOfOTGSupport = true;
} else {
mode_lib->vba.NumberOfOTGSupport = false;
}
mode_lib->vba.NonsupportedDSCInputBPC = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
mode_lib->vba.NonsupportedDSCInputBPC = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->RequiresDSC[i][k] = 0;
locals->RequiresFEC[i][k] = 0;
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.Output[k] == dm_hdmi) {
locals->RequiresDSC[i][k] = 0;
locals->RequiresFEC[i][k] = 0;
locals->OutputBppPerState[i][k] = TruncToValidBPP(
dml_min(600.0, mode_lib->vba.PHYCLKPerState[i]) / mode_lib->vba.PixelClockBackEnd[k] * 24,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
} else if (mode_lib->vba.Output[k] == dm_dp
|| mode_lib->vba.Output[k] == dm_edp) {
if (mode_lib->vba.Output[k] == dm_edp) {
mode_lib->vba.EffectiveFECOverhead = 0.0;
} else {
mode_lib->vba.EffectiveFECOverhead =
mode_lib->vba.FECOverhead;
}
if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
mode_lib->vba.Outbpp = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
mode_lib->vba.OutbppDSC = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
}
if (mode_lib->vba.Outbpp == BPP_INVALID && mode_lib->vba.PHYCLKPerState[i] >= 540.0) {
mode_lib->vba.Outbpp = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
mode_lib->vba.OutbppDSC = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
}
if (mode_lib->vba.Outbpp == BPP_INVALID
&& mode_lib->vba.PHYCLKPerState[i]
>= 810.0) {
mode_lib->vba.Outbpp = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
false,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
mode_lib->vba.OutbppDSC = TruncToValidBPP(
(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
mode_lib->vba.ForcedOutputLinkBPP[k],
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true || mode_lib->vba.Outbpp == BPP_INVALID) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] =
mode_lib->vba.Outbpp;
}
}
} else {
locals->OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->DIOSupport[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!mode_lib->vba.skip_dio_check[k]
&& (locals->OutputBppPerState[i][k] == BPP_INVALID
|| (mode_lib->vba.OutputFormat[k] == dm_420
&& mode_lib->vba.Interlace[k] == true
&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) {
locals->DIOSupport[i] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->DSCCLKRequiredMoreThanSupported[i] = false;
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if ((mode_lib->vba.Output[k] == dm_dp
|| mode_lib->vba.Output[k] == dm_edp)) {
if (mode_lib->vba.OutputFormat[k] == dm_420
|| mode_lib->vba.OutputFormat[k]
== dm_n422) {
mode_lib->vba.DSCFormatFactor = 2;
} else {
mode_lib->vba.DSCFormatFactor = 1;
}
if (locals->RequiresDSC[i][k] == true) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
locals->DSCCLKRequiredMoreThanSupported[i] =
true;
}
} else {
if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 / mode_lib->vba.DSCFormatFactor
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
locals->DSCCLKRequiredMoreThanSupported[i] =
true;
}
}
}
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->NotEnoughDSCUnits[i] = false;
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->RequiresDSC[i][k] == true) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
} else {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 1.0;
}
}
}
if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
locals->NotEnoughDSCUnits[i] = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] != k) {
mode_lib->vba.slices = 0;
} else if (locals->RequiresDSC[i][k] == 0
|| locals->RequiresDSC[i][k] == false) {
mode_lib->vba.slices = 0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
mode_lib->vba.slices = (unsigned int)dml_ceil(
mode_lib->vba.PixelClockBackEnd[k] / 400.0,
4.0);
} else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
mode_lib->vba.slices = (unsigned int)8.0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
mode_lib->vba.slices = (unsigned int)4.0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
mode_lib->vba.slices = (unsigned int)2.0;
} else {
mode_lib->vba.slices = (unsigned int)1.0;
}
if (locals->OutputBppPerState[i][k] == BPP_BLENDED_PIPE
|| locals->OutputBppPerState[i][k] == BPP_INVALID) {
mode_lib->vba.bpp = 0.0;
} else {
mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
}
if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
locals->DSCDelayPerState[i][k] =
dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
mode_lib->vba.bpp,
(unsigned int)dml_ceil(
mode_lib->vba.HActive[k]
/ mode_lib->vba.slices,
1.0),
mode_lib->vba.slices,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]);
} else {
locals->DSCDelayPerState[i][k] =
2.0 * (dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
mode_lib->vba.bpp,
(unsigned int)dml_ceil(mode_lib->vba.HActive[k] / mode_lib->vba.slices, 1.0),
mode_lib->vba.slices / 2,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(mode_lib->vba.OutputFormat[k]));
}
locals->DSCDelayPerState[i][k] =
locals->DSCDelayPerState[i][k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k];
} else {
locals->DSCDelayPerState[i][k] = 0.0;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
if (mode_lib->vba.BlendingAndTiming[k] == m && locals->RequiresDSC[i][m] == true)
locals->DSCDelayPerState[i][k] = locals->DSCDelayPerState[i][m];
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1)
locals->SwathWidthYPerState[i][j][k] = (unsigned int)dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
else
locals->SwathWidthYPerState[i][j][k] = (unsigned int)locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
locals->SwathWidthGranularityY = 256 / dml_ceil(locals->BytePerPixelInDETY[k], 1) / locals->MaxSwathHeightY[k];
locals->RoundedUpMaxSwathSizeBytesY = (dml_ceil(locals->SwathWidthYPerState[i][j][k] - 1, locals->SwathWidthGranularityY)
+ locals->SwathWidthGranularityY) * locals->BytePerPixelInDETY[k] * locals->MaxSwathHeightY[k];
if (locals->SourcePixelFormat[k] == dm_420_10) {
locals->RoundedUpMaxSwathSizeBytesY = dml_ceil(locals->RoundedUpMaxSwathSizeBytesY, 256) + 256;
}
if (locals->MaxSwathHeightC[k] > 0) {
locals->SwathWidthGranularityC = 256 / dml_ceil(locals->BytePerPixelInDETC[k], 2) / locals->MaxSwathHeightC[k];
locals->RoundedUpMaxSwathSizeBytesC = (dml_ceil(locals->SwathWidthYPerState[i][j][k] / 2 - 1, locals->SwathWidthGranularityC)
+ locals->SwathWidthGranularityC) * locals->BytePerPixelInDETC[k] * locals->MaxSwathHeightC[k];
}
if (locals->SourcePixelFormat[k] == dm_420_10) {
locals->RoundedUpMaxSwathSizeBytesC = dml_ceil(locals->RoundedUpMaxSwathSizeBytesC, 256) + 256;
} else {
locals->RoundedUpMaxSwathSizeBytesC = 0;
}
if (locals->RoundedUpMaxSwathSizeBytesY + locals->RoundedUpMaxSwathSizeBytesC <= locals->DETBufferSizeInKByte[0] * 1024.0 / 2) {
locals->SwathHeightYPerState[i][j][k] = (unsigned int)locals->MaxSwathHeightY[k];
locals->SwathHeightCPerState[i][j][k] = (unsigned int)locals->MaxSwathHeightC[k];
} else {
locals->SwathHeightYPerState[i][j][k] = (unsigned int)locals->MinSwathHeightY[k];
locals->SwathHeightCPerState[i][j][k] = (unsigned int)locals->MinSwathHeightC[k];
}
if (locals->BytePerPixelInDETC[k] == 0) {
locals->LinesInDETLuma = locals->DETBufferSizeInKByte[0] * 1024 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
locals->LinesInDETChroma = 0;
} else if (locals->SwathHeightYPerState[i][j][k] <= locals->SwathHeightCPerState[i][j][k]) {
locals->LinesInDETLuma = locals->DETBufferSizeInKByte[0] * 1024 / 2 / locals->BytePerPixelInDETY[k] /
locals->SwathWidthYPerState[i][j][k];
locals->LinesInDETChroma = locals->DETBufferSizeInKByte[0] * 1024 / 2 / locals->BytePerPixelInDETC[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
} else {
locals->LinesInDETLuma = locals->DETBufferSizeInKByte[0] * 1024 * 2 / 3 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
locals->LinesInDETChroma = locals->DETBufferSizeInKByte[0] * 1024 / 3 / locals->BytePerPixelInDETY[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
}
locals->EffectiveLBLatencyHidingSourceLinesLuma = (unsigned int)dml_min(locals->MaxLineBufferLines,
dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k] / (locals->SwathWidthYPerState[i][j][k]
/ dml_max(locals->HRatio[k], 1)), 1)) - (locals->vtaps[k] - 1);
locals->EffectiveLBLatencyHidingSourceLinesChroma = (unsigned int)dml_min(locals->MaxLineBufferLines,
dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k]
/ (locals->SwathWidthYPerState[i][j][k] / 2
/ dml_max(locals->HRatio[k] / 2, 1)), 1)) - (locals->VTAPsChroma[k] - 1);
locals->EffectiveDETLBLinesLuma = (unsigned int)dml_floor(locals->LinesInDETLuma + dml_min(
locals->LinesInDETLuma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETY[k] *
locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i][0],
locals->EffectiveLBLatencyHidingSourceLinesLuma),
locals->SwathHeightYPerState[i][j][k]);
if (locals->BytePerPixelInDETC[k] == 0) {
locals->UrgentLatencySupportUsPerState[i][j][k] = locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]);
} else {
locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min(
locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] *
locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i][0],
locals->EffectiveLBLatencyHidingSourceLinesChroma),
locals->SwathHeightCPerState[i][j][k]);
locals->UrgentLatencySupportUsPerState[i][j][k] = dml_min(
locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]),
locals->EffectiveDETLBLinesChroma * (locals->HTotal[k] / locals->PixelClock[k]) / (locals->VRatio[k] / 2) -
locals->EffectiveDETLBLinesChroma * locals->SwathWidthYPerState[i][j][k] / 2 *
dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]));
}
}
}
}
for (i = 0; i <= locals->soc.num_states; i++) {
for (j = 0; j < 2; j++) {
locals->UrgentLatencySupport[i][j] = true;
for (k = 0; k < locals->NumberOfActivePlanes; k++) {
if (locals->UrgentLatencySupportUsPerState[i][j][k] < locals->UrgentLatency)
locals->UrgentLatencySupport[i][j] = false;
}
}
}
for (i = 0; i <= locals->soc.num_states; i++) {
for (j = 0; j < 2; j++) {
locals->TotalNumberOfDCCActiveDPP[i][j] = 0;
for (k = 0; k < locals->NumberOfActivePlanes; k++) {
if (locals->DCCEnable[k] == true) {
locals->TotalNumberOfDCCActiveDPP[i][j] =
locals->TotalNumberOfDCCActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
}
}
}
}
CalculateMinAndMaxPrefetchMode(locals->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &locals->MinPrefetchMode, &locals->MaxPrefetchMode);
locals->MaxTotalVActiveRDBandwidth = 0;
for (k = 0; k < locals->NumberOfActivePlanes; k++) {
locals->MaxTotalVActiveRDBandwidth = locals->MaxTotalVActiveRDBandwidth + locals->ReadBandwidth[k];
}
for (i = 0; i <= locals->soc.num_states; i++) {
for (j = 0; j < 2; j++) {
for (k = 0; k < locals->NumberOfActivePlanes; k++) {
locals->NoOfDPPThisState[k] = locals->NoOfDPP[i][j][k];
locals->RequiredDPPCLKThisState[k] = locals->RequiredDPPCLK[i][j][k];
locals->SwathHeightYThisState[k] = locals->SwathHeightYPerState[i][j][k];
locals->SwathHeightCThisState[k] = locals->SwathHeightCPerState[i][j][k];
locals->SwathWidthYThisState[k] = locals->SwathWidthYPerState[i][j][k];
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] = dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
mode_lib->vba.PixelClock[k] / 16.0);
if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
if (mode_lib->vba.VRatio[k] <= 1.0) {
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ 64.0
* mode_lib->vba.HRatio[k]
* mode_lib->vba.PixelClock[k]
/ mode_lib->vba.NoOfDPP[i][j][k]);
} else {
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ 64.0
* mode_lib->vba.PSCL_FACTOR[k]
* mode_lib->vba.RequiredDPPCLK[i][j][k]);
}
} else {
if (mode_lib->vba.VRatio[k] <= 1.0) {
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ 32.0
* mode_lib->vba.HRatio[k]
* mode_lib->vba.PixelClock[k]
/ mode_lib->vba.NoOfDPP[i][j][k]);
} else {
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ 32.0
* mode_lib->vba.PSCL_FACTOR[k]
* mode_lib->vba.RequiredDPPCLK[i][j][k]);
}
if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETC[k],
2.0)
/ 32.0
* mode_lib->vba.HRatio[k]
/ 2.0
* mode_lib->vba.PixelClock[k]
/ mode_lib->vba.NoOfDPP[i][j][k]);
} else {
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETC[k],
2.0)
/ 32.0
* mode_lib->vba.PSCL_FACTOR_CHROMA[k]
* mode_lib->vba.RequiredDPPCLK[i][j][k]);
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
mode_lib->vba.Read256BlockHeightY[k],
mode_lib->vba.Read256BlockWidthY[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
(unsigned int)dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k],
mode_lib->vba.ViewportHeight[k],
mode_lib->vba.SwathWidthYPerState[i][j][k],
mode_lib->vba.GPUVMEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequestsLuma,
mode_lib->vba.PDEProcessingBufIn64KBReqs,
mode_lib->vba.PitchY[k],
mode_lib->vba.DCCMetaPitchY[k],
&mode_lib->vba.MacroTileWidthY[k],
&mode_lib->vba.MetaRowBytesY,
&mode_lib->vba.DPTEBytesPerRowY,
&mode_lib->vba.PTEBufferSizeNotExceededY[i][j][k],
&mode_lib->vba.dpte_row_height[k],
&mode_lib->vba.meta_row_height[k]);
mode_lib->vba.PrefetchLinesY[0][0][k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k],
mode_lib->vba.vtaps[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.SwathHeightYPerState[i][j][k],
mode_lib->vba.ViewportYStartY[k],
&mode_lib->vba.PrefillY[k],
&mode_lib->vba.MaxNumSwY[k]);
if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
mode_lib,
mode_lib->vba.DCCEnable[k],
mode_lib->vba.Read256BlockHeightY[k],
mode_lib->vba.Read256BlockWidthY[k],
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.SurfaceTiling[k],
(unsigned int)dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
mode_lib->vba.SourceScan[k],
(unsigned int)(mode_lib->vba.ViewportWidth[k] / 2.0),
(unsigned int)(mode_lib->vba.ViewportHeight[k] / 2.0),
(unsigned int)(mode_lib->vba.SwathWidthYPerState[i][j][k] / 2.0),
mode_lib->vba.GPUVMEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequestsLuma,
mode_lib->vba.PDEProcessingBufIn64KBReqs,
mode_lib->vba.PitchC[k],
(unsigned int)0.0,
&mode_lib->vba.MacroTileWidthC[k],
&mode_lib->vba.MetaRowBytesC,
&mode_lib->vba.DPTEBytesPerRowC,
&mode_lib->vba.PTEBufferSizeNotExceededC[i][j][k],
&mode_lib->vba.dpte_row_height_chroma[k],
&mode_lib->vba.meta_row_height_chroma[k]);
mode_lib->vba.PrefetchLinesC[0][0][k] = CalculatePrefetchSourceLines(
mode_lib,
mode_lib->vba.VRatio[k] / 2.0,
mode_lib->vba.VTAPsChroma[k],
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.SwathHeightCPerState[i][j][k],
mode_lib->vba.ViewportYStartC[k],
&mode_lib->vba.PrefillC[k],
&mode_lib->vba.MaxNumSwC[k]);
} else {
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
mode_lib->vba.MetaRowBytesC = (unsigned int)0.0;
mode_lib->vba.DPTEBytesPerRowC = (unsigned int)0.0;
locals->PrefetchLinesC[0][0][k] = 0.0;
locals->PTEBufferSizeNotExceededC[i][j][k] = true;
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
}
locals->PDEAndMetaPTEBytesPerFrame[0][0][k] =
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
locals->MetaRowBytes[0][0][k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
locals->DPTEBytesPerRow[0][0][k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
CalculateActiveRowBandwidth(
mode_lib->vba.GPUVMEnable,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.VRatio[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.MetaRowBytesY,
mode_lib->vba.MetaRowBytesC,
mode_lib->vba.meta_row_height[k],
mode_lib->vba.meta_row_height_chroma[k],
mode_lib->vba.DPTEBytesPerRowY,
mode_lib->vba.DPTEBytesPerRowC,
mode_lib->vba.dpte_row_height[k],
mode_lib->vba.dpte_row_height_chroma[k],
&mode_lib->vba.meta_row_bw[k],
&mode_lib->vba.dpte_row_bw[k],
&mode_lib->vba.qual_row_bw[k]);
}
mode_lib->vba.ExtraLatency =
mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
+ (mode_lib->vba.TotalNumberOfActiveDPP[i][j]
* mode_lib->vba.PixelChunkSizeInKByte
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i][j]
* mode_lib->vba.MetaChunkSize)
* 1024.0
/ mode_lib->vba.ReturnBWPerState[i][0];
if (mode_lib->vba.GPUVMEnable == true) {
mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
+ mode_lib->vba.TotalNumberOfActiveDPP[i][j]
* mode_lib->vba.PTEGroupSize
/ mode_lib->vba.ReturnBWPerState[i][0];
}
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.WritebackEnable[k] == true) {
locals->WritebackDelay[i][k] = mode_lib->vba.WritebackLatency
+ CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
(unsigned int)mode_lib->vba.WritebackDestinationWidth[k]) / locals->RequiredDISPCLK[i][j];
} else {
locals->WritebackDelay[i][k] = 0.0;
}
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
if (mode_lib->vba.BlendingAndTiming[m] == k
&& mode_lib->vba.WritebackEnable[m]
== true) {
locals->WritebackDelay[i][k] = dml_max(locals->WritebackDelay[i][k],
mode_lib->vba.WritebackLatency + CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[m],
mode_lib->vba.WritebackHRatio[m],
mode_lib->vba.WritebackVRatio[m],
mode_lib->vba.WritebackLumaHTaps[m],
mode_lib->vba.WritebackLumaVTaps[m],
mode_lib->vba.WritebackChromaHTaps[m],
mode_lib->vba.WritebackChromaVTaps[m],
(unsigned int)mode_lib->vba.WritebackDestinationWidth[m]) / locals->RequiredDISPCLK[i][j]);
}
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
if (mode_lib->vba.BlendingAndTiming[k] == m) {
locals->WritebackDelay[i][k] = locals->WritebackDelay[i][m];
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m < locals->NumberOfCursors[k]; m++)
locals->cursor_bw[k] = locals->NumberOfCursors[k] * locals->CursorWidth[k][m] * locals->CursorBPP[k][m]
/ 8 / (locals->HTotal[k] / locals->PixelClock[k]) * locals->VRatio[k];
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->MaximumVStartup[0][0][k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
}
mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
do {
mode_lib->vba.PrefetchMode[i][j] = mode_lib->vba.NextPrefetchMode;
mode_lib->vba.NextPrefetchMode = mode_lib->vba.NextPrefetchMode + 1;
mode_lib->vba.TWait = CalculateTWait(
mode_lib->vba.PrefetchMode[i][j],
mode_lib->vba.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatency,
mode_lib->vba.SREnterPlusExitTime);
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.XFCEnabled[k] == true) {
mode_lib->vba.XFCRemoteSurfaceFlipDelay =
CalculateRemoteSurfaceFlipDelay(
mode_lib,
mode_lib->vba.VRatio[k],
locals->SwathWidthYPerState[i][j][k],
dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
mode_lib->vba.XFCTSlvVupdateOffset,
mode_lib->vba.XFCTSlvVupdateWidth,
mode_lib->vba.XFCTSlvVreadyOffset,
mode_lib->vba.XFCXBUFLatencyTolerance,
mode_lib->vba.XFCFillBWOverhead,
mode_lib->vba.XFCSlvChunkSize,
mode_lib->vba.XFCBusTransportTime,
mode_lib->vba.TimeCalc,
mode_lib->vba.TWait,
&mode_lib->vba.SrcActiveDrainRate,
&mode_lib->vba.TInitXFill,
&mode_lib->vba.TslvChk);
} else {
mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
}
CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBWPerState[i][0], mode_lib->vba.ReadBandwidthLuma[k], mode_lib->vba.ReadBandwidthChroma[k], mode_lib->vba.MaxTotalVActiveRDBandwidth,
mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k],
(unsigned int)mode_lib->vba.RequiredDPPCLK[i][j][k], (unsigned int)mode_lib->vba.RequiredDISPCLK[i][j], mode_lib->vba.PixelClock[k], (unsigned int)mode_lib->vba.DSCDelayPerState[i][k], mode_lib->vba.NoOfDPP[i][j][k], mode_lib->vba.ScalerEnabled[k], mode_lib->vba.NumberOfCursors[k],
mode_lib->vba.DPPCLKDelaySubtotal, mode_lib->vba.DPPCLKDelaySCL, mode_lib->vba.DPPCLKDelaySCLLBOnly, mode_lib->vba.DPPCLKDelayCNVCFormater, mode_lib->vba.DPPCLKDelayCNVCCursor, mode_lib->vba.DISPCLKDelaySubtotal,
(unsigned int)(mode_lib->vba.SwathWidthYPerState[i][j][k] / mode_lib->vba.HRatio[k]), mode_lib->vba.OutputFormat[k], mode_lib->vba.HTotal[k],
(unsigned int)mode_lib->vba.SwathWidthYSingleDPP[k], mode_lib->vba.BytePerPixelInDETY[k], mode_lib->vba.BytePerPixelInDETC[k], mode_lib->vba.SwathHeightYThisState[k], mode_lib->vba.SwathHeightCThisState[k], mode_lib->vba.Interlace[k], mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
&mode_lib->vba.DSTXAfterScaler[k], &mode_lib->vba.DSTYAfterScaler[k]);
mode_lib->vba.IsErrorResult[i][j][k] =
CalculatePrefetchSchedule(
mode_lib,
mode_lib->vba.RequiredDPPCLK[i][j][k],
mode_lib->vba.RequiredDISPCLK[i][j],
mode_lib->vba.PixelClock[k],
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
mode_lib->vba.NoOfDPP[i][j][k],
mode_lib->vba.NumberOfCursors[k],
mode_lib->vba.VTotal[k]
- mode_lib->vba.VActive[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.MaxInterDCNTileRepeaters,
(unsigned int)mode_lib->vba.MaximumVStartup[0][0][k],
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.DynamicMetadataEnable[k],
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
mode_lib->vba.DynamicMetadataTransmittedBytes[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.ExtraLatency,
mode_lib->vba.TimeCalc,
(unsigned int)mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
(unsigned int)mode_lib->vba.MetaRowBytes[0][0][k],
(unsigned int)mode_lib->vba.DPTEBytesPerRow[0][0][k],
mode_lib->vba.PrefetchLinesY[0][0][k],
mode_lib->vba.SwathWidthYPerState[i][j][k],
mode_lib->vba.BytePerPixelInDETY[k],
mode_lib->vba.PrefillY[k],
mode_lib->vba.MaxNumSwY[k],
mode_lib->vba.PrefetchLinesC[0][0][k],
mode_lib->vba.BytePerPixelInDETC[k],
mode_lib->vba.PrefillC[k],
mode_lib->vba.MaxNumSwC[k],
mode_lib->vba.SwathHeightYPerState[i][j][k],
mode_lib->vba.SwathHeightCPerState[i][j][k],
mode_lib->vba.TWait,
mode_lib->vba.XFCEnabled[k],
mode_lib->vba.XFCRemoteSurfaceFlipDelay,
mode_lib->vba.Interlace[k],
mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
mode_lib->vba.DSTXAfterScaler[k],
mode_lib->vba.DSTYAfterScaler[k],
&mode_lib->vba.LineTimesForPrefetch[k],
&mode_lib->vba.PrefetchBW[k],
&mode_lib->vba.LinesForMetaPTE[k],
&mode_lib->vba.LinesForMetaAndDPTERow[k],
&mode_lib->vba.VRatioPreY[i][j][k],
&mode_lib->vba.VRatioPreC[i][j][k],
&mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k],
&mode_lib->vba.Tno_bw[k],
&mode_lib->vba.VUpdateOffsetPix[k],
&mode_lib->vba.VUpdateWidthPix[k],
&mode_lib->vba.VReadyOffsetPix[k]);
}
mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0;
mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
locals->prefetch_vm_bw_valid = true;
locals->prefetch_row_bw_valid = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->PDEAndMetaPTEBytesPerFrame[0][0][k] == 0)
locals->prefetch_vm_bw[k] = 0;
else if (locals->LinesForMetaPTE[k] > 0)
locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[0][0][k]
/ (locals->LinesForMetaPTE[k] * locals->HTotal[k] / locals->PixelClock[k]);
else {
locals->prefetch_vm_bw[k] = 0;
locals->prefetch_vm_bw_valid = false;
}
if (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k] == 0)
locals->prefetch_row_bw[k] = 0;
else if (locals->LinesForMetaAndDPTERow[k] > 0)
locals->prefetch_row_bw[k] = (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k])
/ (locals->LinesForMetaAndDPTERow[k] * locals->HTotal[k] / locals->PixelClock[k]);
else {
locals->prefetch_row_bw[k] = 0;
locals->prefetch_row_bw_valid = false;
}
mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = mode_lib->vba.MaximumReadBandwidthWithPrefetch
+ mode_lib->vba.cursor_bw[k] + mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k];
mode_lib->vba.MaximumReadBandwidthWithPrefetch =
mode_lib->vba.MaximumReadBandwidthWithPrefetch
+ mode_lib->vba.cursor_bw[k]
+ dml_max3(
mode_lib->vba.prefetch_vm_bw[k],
mode_lib->vba.prefetch_row_bw[k],
dml_max(mode_lib->vba.ReadBandwidth[k],
mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k])
+ mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k]);
}
locals->BandwidthWithoutPrefetchSupported[i][0] = true;
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i][0]) {
locals->BandwidthWithoutPrefetchSupported[i][0] = false;
}
locals->PrefetchSupported[i][j] = true;
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i][0]) {
locals->PrefetchSupported[i][j] = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->LineTimesForPrefetch[k] < 2.0
|| locals->LinesForMetaPTE[k] >= 8.0
|| locals->LinesForMetaAndDPTERow[k] >= 16.0
|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
locals->PrefetchSupported[i][j] = false;
}
}
locals->VRatioInPrefetchSupported[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->VRatioPreY[i][j][k] > 4.0
|| locals->VRatioPreC[i][j][k] > 4.0
|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
locals->VRatioInPrefetchSupported[i][j] = false;
}
}
} while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true)
&& mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode);
if (mode_lib->vba.PrefetchSupported[i][j] == true
&& mode_lib->vba.VRatioInPrefetchSupported[i][j] == true) {
mode_lib->vba.BandwidthAvailableForImmediateFlip =
mode_lib->vba.ReturnBWPerState[i][0];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.BandwidthAvailableForImmediateFlip =
mode_lib->vba.BandwidthAvailableForImmediateFlip
- mode_lib->vba.cursor_bw[k]
- dml_max(
mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.qual_row_bw[k],
mode_lib->vba.PrefetchBW[k]);
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.ImmediateFlipBytes[k] = (unsigned int)0.0;
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
mode_lib->vba.ImmediateFlipBytes[k] = (unsigned int)(
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k]
+ mode_lib->vba.MetaRowBytes[0][0][k]
+ mode_lib->vba.DPTEBytesPerRow[0][0][k]);
}
}
mode_lib->vba.TotImmediateFlipBytes = 0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
mode_lib->vba.TotImmediateFlipBytes =
mode_lib->vba.TotImmediateFlipBytes
+ mode_lib->vba.ImmediateFlipBytes[k];
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
CalculateFlipSchedule(
mode_lib,
mode_lib->vba.ExtraLatency,
mode_lib->vba.UrgentLatencyPixelDataOnly,
mode_lib->vba.GPUVMMaxPageTableLevels,
mode_lib->vba.GPUVMEnable,
mode_lib->vba.BandwidthAvailableForImmediateFlip,
mode_lib->vba.TotImmediateFlipBytes,
mode_lib->vba.SourcePixelFormat[k],
mode_lib->vba.ImmediateFlipBytes[k],
mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k],
mode_lib->vba.VRatio[k],
mode_lib->vba.Tno_bw[k],
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
(unsigned int)mode_lib->vba.MetaRowBytes[0][0][k],
(unsigned int)mode_lib->vba.DPTEBytesPerRow[0][0][k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.dpte_row_height[k],
mode_lib->vba.meta_row_height[k],
mode_lib->vba.qual_row_bw[k],
&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
&mode_lib->vba.final_flip_bw[k],
&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
}
mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.total_dcn_read_bw_with_flip =
mode_lib->vba.total_dcn_read_bw_with_flip
+ mode_lib->vba.cursor_bw[k]
+ dml_max3(
mode_lib->vba.prefetch_vm_bw[k],
mode_lib->vba.prefetch_row_bw[k],
mode_lib->vba.final_flip_bw[k]
+ dml_max(
mode_lib->vba.ReadBandwidth[k],
mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k]));
}
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = true;
if (mode_lib->vba.total_dcn_read_bw_with_flip
> mode_lib->vba.ReturnBWPerState[i][0]) {
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
}
}
} else {
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0] = dml_min(mode_lib->vba.ReturnBusWidth *
mode_lib->vba.DCFCLKPerState[i], mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000) *
mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100;
if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0])
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = true;
else
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = false;
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
locals->PTEBufferSizeNotExceeded[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->PTEBufferSizeNotExceededY[i][j][k] == false
|| locals->PTEBufferSizeNotExceededC[i][j][k] == false) {
locals->PTEBufferSizeNotExceeded[i][j] = false;
}
}
}
}
mode_lib->vba.CursorSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (j = 0; j < 2; j++) {
if (mode_lib->vba.CursorWidth[k][j] > 0.0) {
if (dml_floor(
dml_floor(
mode_lib->vba.CursorBufferSize
- mode_lib->vba.CursorChunkSize,
mode_lib->vba.CursorChunkSize) * 1024.0
/ (mode_lib->vba.CursorWidth[k][j]
* mode_lib->vba.CursorBPP[k][j]
/ 8.0),
1.0)
* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatencyPixelDataOnly
|| (mode_lib->vba.CursorBPP[k][j] == 64.0
&& mode_lib->vba.Cursor64BppSupport == false)) {
mode_lib->vba.CursorSupport = false;
}
}
}
}
mode_lib->vba.PitchSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->AlignedYPitch[k] = dml_ceil(
dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
locals->MacroTileWidthY[k]);
if (locals->AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
mode_lib->vba.PitchSupport = false;
}
if (mode_lib->vba.DCCEnable[k] == true) {
locals->AlignedDCCMetaPitch[k] = dml_ceil(
dml_max(
mode_lib->vba.DCCMetaPitchY[k],
mode_lib->vba.ViewportWidth[k]),
64.0 * locals->Read256BlockWidthY[k]);
} else {
locals->AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
}
if (locals->AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
mode_lib->vba.PitchSupport = false;
}
if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
locals->AlignedCPitch[k] = dml_ceil(
dml_max(
mode_lib->vba.PitchC[k],
mode_lib->vba.ViewportWidth[k] / 2.0),
locals->MacroTileWidthC[k]);
} else {
locals->AlignedCPitch[k] = mode_lib->vba.PitchC[k];
}
if (locals->AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
mode_lib->vba.PitchSupport = false;
}
}
for (idx = mode_lib->vba.soc.num_states; idx >= 0; idx--) {
for (j = 0; j < 2; j++) {
enum dm_validation_status status = DML_VALIDATION_OK;
if (mode_lib->vba.ScaleRatioAndTapsSupport != true) {
status = DML_FAIL_SCALE_RATIO_TAP;
} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
} else if (locals->ViewportSizeSupport[idx][0] != true) {
status = DML_FAIL_VIEWPORT_SIZE;
} else if (locals->DIOSupport[idx] != true) {
status = DML_FAIL_DIO_SUPPORT;
} else if (locals->NotEnoughDSCUnits[idx] != false) {
status = DML_FAIL_NOT_ENOUGH_DSC;
} else if (locals->DSCCLKRequiredMoreThanSupported[idx] != false) {
status = DML_FAIL_DSC_CLK_REQUIRED;
} else if (locals->UrgentLatencySupport[idx][j] != true) {
status = DML_FAIL_URGENT_LATENCY;
} else if (locals->ROBSupport[idx][0] != true) {
status = DML_FAIL_REORDERING_BUFFER;
} else if (locals->DISPCLK_DPPCLK_Support[idx][j] != true) {
status = DML_FAIL_DISPCLK_DPPCLK;
} else if (locals->TotalAvailablePipesSupport[idx][j] != true) {
status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
} else if (mode_lib->vba.NumberOfOTGSupport != true) {
status = DML_FAIL_NUM_OTG;
} else if (mode_lib->vba.WritebackModeSupport != true) {
status = DML_FAIL_WRITEBACK_MODE;
} else if (mode_lib->vba.WritebackLatencySupport != true) {
status = DML_FAIL_WRITEBACK_LATENCY;
} else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) {
status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
} else if (mode_lib->vba.CursorSupport != true) {
status = DML_FAIL_CURSOR_SUPPORT;
} else if (mode_lib->vba.PitchSupport != true) {
status = DML_FAIL_PITCH_SUPPORT;
} else if (locals->PrefetchSupported[idx][j] != true) {
status = DML_FAIL_PREFETCH_SUPPORT;
} else if (locals->TotalVerticalActiveBandwidthSupport[idx][0] != true) {
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
} else if (locals->VRatioInPrefetchSupported[idx][j] != true) {
status = DML_FAIL_V_RATIO_PREFETCH;
} else if (locals->PTEBufferSizeNotExceeded[idx][j] != true) {
status = DML_FAIL_PTE_BUFFER_SIZE;
} else if (mode_lib->vba.NonsupportedDSCInputBPC != false) {
status = DML_FAIL_DSC_INPUT_BPC;
}
if (status == DML_VALIDATION_OK) {
locals->ModeSupport[idx][j] = true;
} else {
locals->ModeSupport[idx][j] = false;
}
locals->ValidationStatus[idx] = status;
}
}
{
unsigned int MaximumMPCCombine = 0;
mode_lib->vba.VoltageLevel = mode_lib->vba.soc.num_states + 1;
for (i = mode_lib->vba.VoltageOverrideLevel; i <= mode_lib->vba.soc.num_states; i++) {
if (locals->ModeSupport[i][0] == true || locals->ModeSupport[i][1] == true) {
mode_lib->vba.VoltageLevel = i;
if (locals->ModeSupport[i][1] == true && (locals->ModeSupport[i][0] == false
|| mode_lib->vba.WhenToDoMPCCombine == dm_mpc_always_when_possible)) {
MaximumMPCCombine = 1;
} else {
MaximumMPCCombine = 0;
}
break;
}
}
mode_lib->vba.ImmediateFlipSupport =
locals->ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.DPPPerPlane[k] = locals->NoOfDPP[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
locals->DPPCLK[k] = locals->RequiredDPPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
}
mode_lib->vba.DISPCLK = locals->RequiredDISPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
mode_lib->vba.maxMpcComb = MaximumMPCCombine;
}
mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
mode_lib->vba.FabricAndDRAMBandwidth = locals->FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.ODMCombineEnabled[k] =
locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
} else {
mode_lib->vba.ODMCombineEnabled[k] = 0;
}
mode_lib->vba.DSCEnabled[k] =
locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
mode_lib->vba.OutputBpp[k] =
locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
}
}