#include "../display_mode_lib.h"
#include "display_mode_vba_20.h"
#include "../dml_inline_defs.h"
#define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff
#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 CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double DPPCLK,
double DISPCLK,
double PixelClock,
double DCFCLKDeepSleep,
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 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,
unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
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 dml20_DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
struct display_mode_lib *mode_lib);
void dml20_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);
dml20_DisplayPipeConfiguration(mode_lib);
dml20_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 = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
if (bpc == 8)
D = 81;
else if (bpc == 10)
D = 89;
else
D = 113;
w = sliceWidth / pixelsPerClock;
if (pixelFormat == dm_s422)
s = 1;
else
s = 0;
ix = initalXmitDelay + 45;
wx = (w + 2) / 3;
p = 3 * wx - w;
l0 = ix / w;
a = ix + p * l0;
ax = (a + 2) / 3 + D + 6 + 1;
l = (ax + wx - 1) / wx;
if ((ix % w) == 0 && p != 0)
lstall = 1;
else
lstall = 0;
Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
pixels = Delay * 3 * pixelsPerClock;
return pixels;
}
static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
{
unsigned int Delay = 0;
if (pixelFormat == dm_420) {
Delay = Delay + 2;
Delay = Delay + 0;
Delay = Delay + 3;
Delay = Delay + 2;
Delay = Delay + 12;
Delay = Delay + 13;
Delay = Delay + 2;
Delay = Delay + 7;
Delay = Delay + 3;
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 1;
} else if (pixelFormat == dm_n422) {
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 5;
Delay = Delay + 25;
Delay = Delay + 2;
Delay = Delay + 10;
Delay = Delay + 2;
Delay = Delay + 1;
Delay = Delay + 1;
} else {
Delay = Delay + 2;
Delay = Delay + 0;
Delay = Delay + 3;
Delay = Delay + 12;
Delay = Delay + 2;
Delay = Delay + 7;
Delay = Delay + 1;
Delay = Delay + 2;
Delay = Delay + 1;
}
return Delay;
}
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double DPPCLK,
double DISPCLK,
double PixelClock,
double DCFCLKDeepSleep,
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 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,
unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
double *Tno_bw,
unsigned int *VUpdateOffsetPix,
double *VUpdateWidthPix,
double *VReadyOffsetPix)
{
bool MyError = false;
unsigned int DPPCycles, DISPCLKCycles;
double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
double Tdm, LineTime, Tsetup;
double dst_y_prefetch_equ;
double Tsw_oto;
double prefetch_bw_oto;
double Tvm_oto;
double Tr0_oto;
double Tpre_oto;
double dst_y_prefetch_oto;
double TimeForFetchingMetaPTE = 0;
double TimeForFetchingRowInVBlank = 0;
double LinesToRequestPrefetchPixelData = 0;
if (ScalerEnabled)
DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
else
DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
DISPCLKCycles = 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 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
*DSTYAfterScaler = 1;
else
*DSTYAfterScaler = 0;
DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
*VUpdateOffsetPix = 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;
*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
+ UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
} else
*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
} 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;
TimeForFetchingMetaPTE = 0;
TimeForFetchingRowInVBlank = 0;
*DestinationLinesToRequestVMInVBlank = 0;
*DestinationLinesToRequestRowInVBlank = 0;
*DestinationLinesForPrefetch = 0;
LinesToRequestPrefetchPixelData = 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 = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
if (*VInitPreFill > 1.0)
MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
else
MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
% SwathHeight;
MaxPartialSwath = dml_max(1U, MaxPartialSwath);
} else {
if (ViewportYStart != 0)
dml_print(
"WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
*MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
if (*VInitPreFill > 1.0)
MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
else
MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
% SwathHeight;
}
return *MaxNumSwath * SwathHeight + MaxPartialSwath;
}
static unsigned int CalculateVMAndRowBytes(
struct display_mode_lib *mode_lib,
bool DCCEnable,
unsigned int BlockHeight256Bytes,
unsigned int BlockWidth256Bytes,
enum source_format_class SourcePixelFormat,
unsigned int SurfaceTiling,
unsigned int BytePerPixel,
enum scan_direction_class ScanDirection,
unsigned int ViewportWidth,
unsigned int ViewportHeight,
unsigned int SwathWidth,
bool GPUVMEnable,
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)
{
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 = MetaRequestHeight;
MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
+ MetaRequestWidth;
*MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
} else {
*meta_row_height = MetaRequestWidth;
MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
+ MetaRequestHeight;
*MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
}
if (ScanDirection == dm_horz) {
DCCMetaSurfaceBytes = DCCMetaPitch
* (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
+ 64 * BlockHeight256Bytes) * BytePerPixel
/ 256;
} else {
DCCMetaSurfaceBytes = DCCMetaPitch
* (dml_ceil(
(double) ViewportHeight - 1,
64 * BlockHeight256Bytes)
+ 64 * BlockHeight256Bytes) * BytePerPixel
/ 256;
}
if (GPUVMEnable == true) {
MetaPTEBytesFrame = (dml_ceil(
(double) (DCCMetaSurfaceBytes - VMMPageSize)
/ (8 * VMMPageSize),
1) + 1) * 64;
MPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 1);
} 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 =
64
* (dml_ceil(
((Pitch
* (dml_ceil(
ViewportHeight
- 1,
MacroTileHeight)
+ MacroTileHeight)
* BytePerPixel)
- MacroTileSizeBytes)
/ (8
* 2097152),
1) + 1);
} else {
DPDE0BytesFrame =
64
* (dml_ceil(
((Pitch
* (dml_ceil(
(double) SwathWidth
- 1,
MacroTileHeight)
+ MacroTileHeight)
* BytePerPixel)
- MacroTileSizeBytes)
/ (8
* 2097152),
1) + 1);
}
ExtraDPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 2);
} else {
DPDE0BytesFrame = 0;
ExtraDPDEBytesFrame = 0;
}
PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
+ ExtraDPDEBytesFrame;
if (GPUVMEnable == true) {
unsigned int PTERequestSize;
unsigned int PixelPTEReqHeight;
unsigned int PixelPTEReqWidth;
double FractionOfPTEReturnDrop;
unsigned int EffectivePDEProcessingBufIn64KBReqs;
if (SurfaceTiling == dm_sw_linear) {
PixelPTEReqHeight = 1;
PixelPTEReqWidth = 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 / 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 =
dml_min(
128,
1
<< (unsigned int) dml_floor(
dml_log2(
dml_min(
(double) PTEBufferSizeInRequestsLuma
* PixelPTEReqWidth,
EffectivePDEProcessingBufIn64KBReqs
* 65536.0
/ BytePerPixel)
/ Pitch),
1));
*PixelPTEBytesPerRow = PTERequestSize
* (dml_ceil(
(double) (Pitch * *dpte_row_height - 1)
/ PixelPTEReqWidth,
1) + 1);
} else if (ScanDirection == dm_horz) {
*dpte_row_height = PixelPTEReqHeight;
*PixelPTEBytesPerRow = PTERequestSize
* (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
+ 1);
} else {
*dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
*PixelPTEBytesPerRow = PTERequestSize
* (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 dml20_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) {
double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma;
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];
DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k]
* mode_lib->vba.SwathHeightY[k]
* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
/ (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k]
/ mode_lib->vba.TotalDataReadBandwidth);
mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(
mode_lib->vba.LastPixelOfLineExtraWatermark,
DataFabricLineDeliveryTimeLuma
- mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[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];
DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0
* mode_lib->vba.SwathHeightC[k]
* dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
/ (mode_lib->vba.ReturnBW
* mode_lib->vba.ReadBandwidthPlaneChroma[k]
/ mode_lib->vba.TotalDataReadBandwidth);
mode_lib->vba.LastPixelOfLineExtraWatermark =
dml_max(
mode_lib->vba.LastPixelOfLineExtraWatermark,
DataFabricLineDeliveryTimeChroma
- mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[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] = mode_lib->vba.DETBufferSizeC[k]
/ mode_lib->vba.BytePerPixelDETC[k]
/ (mode_lib->vba.SwathWidthY[k] / 2);
mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 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,
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,
dml_ceil(
(double) mode_lib->vba.HActive[k]
/ mode_lib->vba.NumberOfDSCSlices[k],
1),
slices / 2.0,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]));
}
mode_lib->vba.DSCDelay[k] = 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],
dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
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],
dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k],
mode_lib->vba.ViewportHeight[k],
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],
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,
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],
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],
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] =
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 = 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;
}
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.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.VTotal[k]
- mode_lib->vba.VActive[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.MaxInterDCNTileRepeaters,
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,
mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
mode_lib->vba.MetaRowByte[k],
mode_lib->vba.PixelPTEBytesPerRow[k],
mode_lib->vba.PrefetchSourceLinesY[k],
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.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
&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] = 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] =
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] =
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],
mode_lib->vba.MetaRowByte[k],
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 =
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 =
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);
}
}
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];
}
}
mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
mode_lib->vba.MinActiveDRAMClockChangeMargin
+ mode_lib->vba.DRAMClockChangeLatency;
if (mode_lib->vba.DRAMClockChangeSupportsVActive &&
mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) {
mode_lib->vba.DRAMClockChangeWatermark += 25;
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
} else {
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
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 = (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 = 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 dml20_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] = MaximumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
} else {
mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
}
if (mode_lib->vba.SwathHeightC[k] == 0) {
mode_lib->vba.DETBufferSizeY[k] = 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] = mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 / 2;
mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 / 2;
} else {
mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte[0]
* 1024.0 * 2 / 3;
mode_lib->vba.DETBufferSizeC[k] = 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)
{
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 || DCCEnable)) {
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,
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)
return 18;
else if (DecimalBPP >= 15)
return 15;
else if (DecimalBPP >= 12)
return 12;
else
return BPP_INVALID;
} else if (Format == dm_444) {
if (DecimalBPP >= 36)
return 36;
else if (DecimalBPP >= 30)
return 30;
else if (DecimalBPP >= 24)
return 24;
else if (DecimalBPP >= 18)
return 18;
else
return BPP_INVALID;
} else {
if (DecimalBPP / 1.5 >= 24)
return 24;
else if (DecimalBPP / 1.5 >= 20)
return 20;
else if (DecimalBPP / 1.5 >= 16)
return 16;
else
return BPP_INVALID;
}
} else {
if (DSCEnabled) {
if (Format == dm_420) {
if (DecimalBPP < 6)
return BPP_INVALID;
else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
return 1.5 * DSCInputBitPerComponent - 1 / 16;
else
return dml_floor(16 * DecimalBPP, 1) / 16;
} else if (Format == dm_n422) {
if (DecimalBPP < 7)
return BPP_INVALID;
else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
return 2 * DSCInputBitPerComponent - 1 / 16;
else
return dml_floor(16 * DecimalBPP, 1) / 16;
} else {
if (DecimalBPP < 8)
return BPP_INVALID;
else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
return 3 * DSCInputBitPerComponent - 1 / 16;
else
return dml_floor(16 * DecimalBPP, 1) / 16;
}
} else if (Format == dm_420) {
if (DecimalBPP >= 18)
return 18;
else if (DecimalBPP >= 15)
return 15;
else if (DecimalBPP >= 12)
return 12;
else
return BPP_INVALID;
} else if (Format == dm_s422 || Format == dm_n422) {
if (DecimalBPP >= 24)
return 24;
else if (DecimalBPP >= 20)
return 20;
else if (DecimalBPP >= 16)
return 16;
else
return BPP_INVALID;
} else {
if (DecimalBPP >= 36)
return 36;
else if (DecimalBPP >= 30)
return 30;
else if (DecimalBPP >= 24)
return 24;
else if (DecimalBPP >= 18)
return 18;
else
return BPP_INVALID;
}
}
}
void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
{
struct vba_vars_st *locals = &mode_lib->vba;
int i;
unsigned int j, k, m;
mode_lib->vba.ScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ScalerEnabled[k] == false
&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
|| mode_lib->vba.HRatio[k] != 1.0
|| mode_lib->vba.htaps[k] != 1.0
|| mode_lib->vba.VRatio[k] != 1.0
|| mode_lib->vba.vtaps[k] != 1.0)) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
|| (mode_lib->vba.htaps[k] > 1.0
&& (mode_lib->vba.htaps[k] % 2) == 1)
|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
&& (mode_lib->vba.HRatio[k] / 2.0
> mode_lib->vba.HTAPsChroma[k]
|| mode_lib->vba.VRatio[k] / 2.0
> mode_lib->vba.VTAPsChroma[k]))) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
}
}
mode_lib->vba.SourceFormatPixelAndScanSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
&& mode_lib->vba.SourceScan[k] != dm_horz)
|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10))
|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_gfx7_2d_thin_l_vp)
&& !((mode_lib->vba.SourcePixelFormat[k]
== dm_444_64
|| mode_lib->vba.SourcePixelFormat[k]
== dm_444_32)
&& mode_lib->vba.SourceScan[k]
== dm_horz
&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
== true
&& mode_lib->vba.DCCEnable[k]
== false))
|| (mode_lib->vba.DCCEnable[k] == true
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_linear
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10)))) {
mode_lib->vba.SourceFormatPixelAndScanSupport = false;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
locals->BytePerPixelInDETY[k] = 8.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
locals->BytePerPixelInDETY[k] = 4.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
locals->BytePerPixelInDETY[k] = 2.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
locals->BytePerPixelInDETY[k] = 1.0;
locals->BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
locals->BytePerPixelInDETY[k] = 1.0;
locals->BytePerPixelInDETC[k] = 2.0;
} else {
locals->BytePerPixelInDETY[k] = 4.0 / 3;
locals->BytePerPixelInDETC[k] = 8.0 / 3;
}
if (mode_lib->vba.SourceScan[k] == dm_horz) {
locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
} else {
locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->ReadBandwidthLuma[k] = locals->SwathWidthYSingleDPP[k] * dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
locals->ReadBandwidthChroma[k] = locals->SwathWidthYSingleDPP[k] / 2 * dml_ceil(locals->BytePerPixelInDETC[k], 2.0)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k] / 2.0;
locals->ReadBandwidth[k] = locals->ReadBandwidthLuma[k] + locals->ReadBandwidthChroma[k];
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 4.0;
} else if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 3.0;
} else if (mode_lib->vba.WritebackEnable[k] == true) {
locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
* mode_lib->vba.WritebackDestinationHeight[k]
/ (mode_lib->vba.WritebackSourceHeight[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]) * 1.5;
} else {
locals->WriteBandwidth[k] = 0.0;
}
}
mode_lib->vba.DCCEnabledInAnyPlane = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.DCCEnabledInAnyPlane = true;
}
}
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],
dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
&locals->Read256BlockHeightY[k],
&locals->Read256BlockHeightC[k],
&locals->Read256BlockWidthY[k],
&locals->Read256BlockWidthC[k]);
if (mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MaxSwathHeightY[k] = locals->Read256BlockHeightY[k];
locals->MaxSwathHeightC[k] = locals->Read256BlockHeightC[k];
} else {
locals->MaxSwathHeightY[k] = locals->Read256BlockWidthY[k];
locals->MaxSwathHeightC[k] = locals->Read256BlockWidthC[k];
}
if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_4kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_t
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_64kb_s_x
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_var_s_x)
&& mode_lib->vba.SourceScan[k] == dm_horz)) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
} else {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
/ 2.0;
}
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
&& mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
/ 2.0;
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
&& mode_lib->vba.SourceScan[k] == dm_horz) {
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k]
/ 2.0;
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
} else {
locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
}
}
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
} else {
mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
}
mode_lib->vba.MaximumSwathWidthInDETBuffer =
dml_min(
mode_lib->vba.MaximumSwathWidthSupport,
mode_lib->vba.DETBufferSizeInKByte[0] * 1024.0 / 2.0
/ (locals->BytePerPixelInDETY[k]
* locals->MinSwathHeightY[k]
+ locals->BytePerPixelInDETC[k]
/ 2.0
* locals->MinSwathHeightC[k]));
if (locals->BytePerPixelInDETC[k] == 0.0) {
mode_lib->vba.MaximumSwathWidthInLineBuffer =
mode_lib->vba.LineBufferSize
* dml_max(mode_lib->vba.HRatio[k], 1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.vtaps[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k],
1.0)
- 2,
0.0));
} else {
mode_lib->vba.MaximumSwathWidthInLineBuffer =
dml_min(
mode_lib->vba.LineBufferSize
* dml_max(
mode_lib->vba.HRatio[k],
1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.vtaps[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k],
1.0)
- 2,
0.0)),
2.0 * mode_lib->vba.LineBufferSize
* dml_max(
mode_lib->vba.HRatio[k]
/ 2.0,
1.0)
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.VTAPsChroma[k]
+ dml_max(
dml_ceil(
mode_lib->vba.VRatio[k]
/ 2.0,
1.0)
- 2,
0.0)));
}
locals->MaximumSwathWidth[k] = dml_min(
mode_lib->vba.MaximumSwathWidthInDETBuffer,
mode_lib->vba.MaximumSwathWidthInLineBuffer);
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
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 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
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] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
if (j == 1) {
while (locals->TotalNumberOfActiveDPP[i][j] < mode_lib->vba.MaxNumDPP
&& locals->TotalNumberOfActiveDPP[i][j] < 2 * mode_lib->vba.NumberOfActivePlanes) {
double BWOfNonSplitPlaneOfMaximumBandwidth;
unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
BWOfNonSplitPlaneOfMaximumBandwidth = 0;
NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (locals->ReadBandwidth[k] > BWOfNonSplitPlaneOfMaximumBandwidth && locals->NoOfDPP[i][j][k] == 1) {
BWOfNonSplitPlaneOfMaximumBandwidth = locals->ReadBandwidth[k];
NumberOfNonSplitPlaneOfMaximumBandwidth = k;
}
}
locals->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
locals->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
locals->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + 1;
}
}
if (locals->TotalNumberOfActiveDPP[i][j] > mode_lib->vba.MaxNumDPP) {
locals->RequiredDISPCLK[i][j] = 0.0;
locals->DISPCLK_DPPCLK_Support[i][j] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
locals->NoOfDPP[i][j][k] = 1;
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
} else {
locals->NoOfDPP[i][j][k] = 2;
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
}
if (i != mode_lib->vba.soc.num_states) {
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PixelClock[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
} else {
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PixelClock[k]
* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.PlaneRequiredDISPCLK);
if (locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
|| mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
locals->TotalNumberOfActiveDPP[i][j] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
}
locals->RequiredDISPCLK[i][j] = dml_max(
locals->RequiredDISPCLK[i][j],
mode_lib->vba.WritebackRequiredDISPCLK);
if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
< mode_lib->vba.WritebackRequiredDISPCLK) {
locals->DISPCLK_DPPCLK_Support[i][j] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->ViewportSizeSupport[i][0] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
> locals->MaximumSwathWidth[k]) {
locals->ViewportSizeSupport[i][0] = false;
}
} else {
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
locals->ViewportSizeSupport[i][0] = false;
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 2; j++) {
if (locals->TotalNumberOfActiveDPP[i][j] <= mode_lib->vba.MaxNumDPP)
locals->TotalAvailablePipesSupport[i][j] = true;
else
locals->TotalAvailablePipesSupport[i][j] = false;
}
}
mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+ 1.0;
}
}
if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
mode_lib->vba.NumberOfOTGSupport = true;
} else {
mode_lib->vba.NumberOfOTGSupport = false;
}
mode_lib->vba.NonsupportedDSCInputBPC = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
mode_lib->vba.NonsupportedDSCInputBPC = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->RequiresDSC[i][k] = 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,
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,
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,
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,
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,
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,
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,
true,
mode_lib->vba.Output[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.DSCInputBitPerComponent[k]);
if (mode_lib->vba.DSCEnabled[k] == true || mode_lib->vba.Outbpp == BPP_INVALID) {
locals->RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
locals->RequiresFEC[i][k] = true;
} else {
locals->RequiresFEC[i][k] = false;
}
mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
} else {
locals->RequiresDSC[i][k] = false;
locals->RequiresFEC[i][k] = false;
}
locals->OutputBppPerState[i][k] =
mode_lib->vba.Outbpp;
}
}
} else {
locals->OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->DIOSupport[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!mode_lib->vba.skip_dio_check[k]
&& (locals->OutputBppPerState[i][k] == BPP_INVALID
|| (mode_lib->vba.OutputFormat[k] == dm_420
&& mode_lib->vba.Interlace[k] == true
&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) {
locals->DIOSupport[i] = false;
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
locals->DSCCLKRequiredMoreThanSupported[i] = false;
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if ((mode_lib->vba.Output[k] == dm_dp
|| mode_lib->vba.Output[k] == dm_edp)) {
if (mode_lib->vba.OutputFormat[k] == dm_420
|| mode_lib->vba.OutputFormat[k]
== dm_n422) {
mode_lib->vba.DSCFormatFactor = 2;
} else {
mode_lib->vba.DSCFormatFactor = 1;
}
if (locals->RequiresDSC[i][k] == true) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
locals->DSCCLKRequiredMoreThanSupported[i] =
true;
}
} else {
if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 / mode_lib->vba.DSCFormatFactor
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
locals->DSCCLKRequiredMoreThanSupported[i] =
true;
}
}
}
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
locals->NotEnoughDSCUnits[i] = false;
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (locals->RequiresDSC[i][k] == true) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
} else {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 1.0;
}
}
}
if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
locals->NotEnoughDSCUnits[i] = true;
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] != k) {
mode_lib->vba.slices = 0;
} else if (locals->RequiresDSC[i][k] == 0
|| locals->RequiresDSC[i][k] == false) {
mode_lib->vba.slices = 0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
mode_lib->vba.slices = dml_ceil(
mode_lib->vba.PixelClockBackEnd[k] / 400.0,
4.0);
} else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
mode_lib->vba.slices = 8.0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
mode_lib->vba.slices = 4.0;
} else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
mode_lib->vba.slices = 2.0;
} else {
mode_lib->vba.slices = 1.0;
}
if (locals->OutputBppPerState[i][k] == BPP_BLENDED_PIPE
|| locals->OutputBppPerState[i][k] == BPP_INVALID) {
mode_lib->vba.bpp = 0.0;
} else {
mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
}
if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
locals->DSCDelayPerState[i][k] =
dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
mode_lib->vba.bpp,
dml_ceil(
mode_lib->vba.HActive[k]
/ mode_lib->vba.slices,
1.0),
mode_lib->vba.slices,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(
mode_lib->vba.OutputFormat[k]);
} else {
locals->DSCDelayPerState[i][k] =
2.0 * (dscceComputeDelay(
mode_lib->vba.DSCInputBitPerComponent[k],
mode_lib->vba.bpp,
dml_ceil(mode_lib->vba.HActive[k] / mode_lib->vba.slices, 1.0),
mode_lib->vba.slices / 2,
mode_lib->vba.OutputFormat[k])
+ dscComputeDelay(mode_lib->vba.OutputFormat[k]));
}
locals->DSCDelayPerState[i][k] =
locals->DSCDelayPerState[i][k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k];
} else {
locals->DSCDelayPerState[i][k] = 0.0;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
if (mode_lib->vba.BlendingAndTiming[k] == m && locals->RequiresDSC[i][m] == true)
locals->DSCDelayPerState[i][k] = locals->DSCDelayPerState[i][m];
}
}
}
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
for (j = 0; j < 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] = dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
else
locals->SwathWidthYPerState[i][j][k] = 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 / 2) {
locals->SwathHeightYPerState[i][j][k] = locals->MaxSwathHeightY[k];
locals->SwathHeightCPerState[i][j][k] = locals->MaxSwathHeightC[k];
} else {
locals->SwathHeightYPerState[i][j][k] = locals->MinSwathHeightY[k];
locals->SwathHeightCPerState[i][j][k] = 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 = 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 = 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 = 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->LinesInDETChroma) {
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]);
} else {
locals->EffectiveDETLBLinesChroma = 0;
}
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->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);
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],
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],
dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
mode_lib->vba.SourceScan[k],
mode_lib->vba.ViewportWidth[k] / 2.0,
mode_lib->vba.ViewportHeight[k] / 2.0,
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],
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 = 0.0;
mode_lib->vba.DPTEBytesPerRowC = 0.0;
locals->PrefetchLinesC[0][0][k] = 0.0;
locals->PTEBufferSizeNotExceededC[i][j][k] = true;
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
}
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],
mode_lib->vba.WritebackDestinationWidth[k]) / locals->RequiredDISPCLK[i][j];
} else {
locals->WritebackDelay[i][k] = 0.0;
}
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
if (mode_lib->vba.BlendingAndTiming[m] == k
&& mode_lib->vba.WritebackEnable[m]
== true) {
locals->WritebackDelay[i][k] = dml_max(locals->WritebackDelay[i][k],
mode_lib->vba.WritebackLatency + CalculateWriteBackDelay(
mode_lib->vba.WritebackPixelFormat[m],
mode_lib->vba.WritebackHRatio[m],
mode_lib->vba.WritebackVRatio[m],
mode_lib->vba.WritebackLumaHTaps[m],
mode_lib->vba.WritebackLumaVTaps[m],
mode_lib->vba.WritebackChromaHTaps[m],
mode_lib->vba.WritebackChromaVTaps[m],
mode_lib->vba.WritebackDestinationWidth[m]) / locals->RequiredDISPCLK[i][j]);
}
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
if (mode_lib->vba.BlendingAndTiming[k] == m) {
locals->WritebackDelay[i][k] = locals->WritebackDelay[i][m];
}
}
}
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;
}
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.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,
mode_lib->vba.SwathWidthYPerState[i][j][k]
/ mode_lib->vba.HRatio[k],
mode_lib->vba.OutputFormat[k],
mode_lib->vba.VTotal[k]
- mode_lib->vba.VActive[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.MaxInterDCNTileRepeaters,
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,
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
mode_lib->vba.MetaRowBytes[0][0][k],
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,
mode_lib->vba.DSTYAfterScaler,
&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.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
&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] = 0.0;
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
mode_lib->vba.ImmediateFlipBytes[k] =
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.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],
mode_lib->vba.MetaRowBytes[0][0][k],
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;
}
}
}
mode_lib->vba.MaxTotalVActiveRDBandwidth = 0;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
mode_lib->vba.MaxTotalVActiveRDBandwidth = mode_lib->vba.MaxTotalVActiveRDBandwidth + mode_lib->vba.ReadBandwidth[k];
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 (i = mode_lib->vba.soc.num_states; i >= 0; i--) {
for (j = 0; j < 2; j++) {
enum dm_validation_status status = DML_VALIDATION_OK;
if (mode_lib->vba.ScaleRatioAndTapsSupport != true) {
status = DML_FAIL_SCALE_RATIO_TAP;
} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
} else if (locals->ViewportSizeSupport[i][0] != true) {
status = DML_FAIL_VIEWPORT_SIZE;
} else if (locals->DIOSupport[i] != true) {
status = DML_FAIL_DIO_SUPPORT;
} else if (locals->NotEnoughDSCUnits[i] != false) {
status = DML_FAIL_NOT_ENOUGH_DSC;
} else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) {
status = DML_FAIL_DSC_CLK_REQUIRED;
} else if (locals->UrgentLatencySupport[i][j] != true) {
status = DML_FAIL_URGENT_LATENCY;
} else if (locals->ROBSupport[i][0] != true) {
status = DML_FAIL_REORDERING_BUFFER;
} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
status = DML_FAIL_DISPCLK_DPPCLK;
} else if (locals->TotalAvailablePipesSupport[i][j] != true) {
status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
} else if (mode_lib->vba.NumberOfOTGSupport != true) {
status = DML_FAIL_NUM_OTG;
} else if (mode_lib->vba.WritebackModeSupport != true) {
status = DML_FAIL_WRITEBACK_MODE;
} else if (mode_lib->vba.WritebackLatencySupport != true) {
status = DML_FAIL_WRITEBACK_LATENCY;
} else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) {
status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
} else if (mode_lib->vba.CursorSupport != true) {
status = DML_FAIL_CURSOR_SUPPORT;
} else if (mode_lib->vba.PitchSupport != true) {
status = DML_FAIL_PITCH_SUPPORT;
} else if (locals->PrefetchSupported[i][j] != true) {
status = DML_FAIL_PREFETCH_SUPPORT;
} else if (locals->TotalVerticalActiveBandwidthSupport[i][0] != true) {
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
} else if (locals->VRatioInPrefetchSupported[i][j] != true) {
status = DML_FAIL_V_RATIO_PREFETCH;
} else if (locals->PTEBufferSizeNotExceeded[i][j] != true) {
status = DML_FAIL_PTE_BUFFER_SIZE;
} else if (mode_lib->vba.NonsupportedDSCInputBPC != false) {
status = DML_FAIL_DSC_INPUT_BPC;
}
if (status == DML_VALIDATION_OK) {
locals->ModeSupport[i][j] = true;
} else {
locals->ModeSupport[i][j] = false;
}
locals->ValidationStatus[i] = status;
}
}
{
unsigned int MaximumMPCCombine = 0;
mode_lib->vba.VoltageLevel = mode_lib->vba.soc.num_states + 1;
for (i = mode_lib->vba.VoltageOverrideLevel; i <= mode_lib->vba.soc.num_states; i++) {
if (locals->ModeSupport[i][0] == true || locals->ModeSupport[i][1] == true) {
mode_lib->vba.VoltageLevel = i;
if (locals->ModeSupport[i][1] == true && (locals->ModeSupport[i][0] == false
|| mode_lib->vba.WhenToDoMPCCombine == dm_mpc_always_when_possible)) {
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];
}
}