in drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c [2052:3382]
static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib)
{
struct vba_vars_st *v = &mode_lib->vba;
unsigned int j, k;
double HostVMInefficiencyFactor = 1.0;
bool NoChromaPlanes = true;
int ReorderBytes;
double VMDataOnlyReturnBW;
double MaxTotalRDBandwidth = 0;
int PrefetchMode = v->PrefetchModePerState[v->VoltageLevel][v->maxMpcComb];
v->WritebackDISPCLK = 0.0;
v->DISPCLKWithRamping = 0;
v->DISPCLKWithoutRamping = 0;
v->GlobalDPPCLK = 0.0;
/* DAL custom code: need to update ReturnBW in case min dcfclk is overriden */
{
double IdealFabricAndSDPPortBandwidthPerState = dml_min(
v->ReturnBusWidth * v->DCFCLKState[v->VoltageLevel][v->maxMpcComb],
v->FabricClockPerState[v->VoltageLevel] * v->FabricDatapathToDCNDataReturn);
double IdealDRAMBandwidthPerState = v->DRAMSpeedPerState[v->VoltageLevel] * v->NumberOfChannels * v->DRAMChannelWidth;
if (v->HostVMEnable != true) {
v->ReturnBW = dml_min(
IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly / 100.0);
} else {
v->ReturnBW = dml_min(
IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0);
}
}
/* End DAL custom code */
// DISPCLK and DPPCLK Calculation
//
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->WritebackEnable[k]) {
v->WritebackDISPCLK = dml_max(
v->WritebackDISPCLK,
dml31_CalculateWriteBackDISPCLK(
v->WritebackPixelFormat[k],
v->PixelClock[k],
v->WritebackHRatio[k],
v->WritebackVRatio[k],
v->WritebackHTaps[k],
v->WritebackVTaps[k],
v->WritebackSourceWidth[k],
v->WritebackDestinationWidth[k],
v->HTotal[k],
v->WritebackLineBufferSize));
}
}
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->HRatio[k] > 1) {
v->PSCL_THROUGHPUT_LUMA[k] = dml_min(
v->MaxDCHUBToPSCLThroughput,
v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1));
} else {
v->PSCL_THROUGHPUT_LUMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
}
v->DPPCLKUsingSingleDPPLuma = v->PixelClock[k]
* dml_max(
v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
dml_max(v->HRatio[k] * v->VRatio[k] / v->PSCL_THROUGHPUT_LUMA[k], 1.0));
if ((v->htaps[k] > 6 || v->vtaps[k] > 6) && v->DPPCLKUsingSingleDPPLuma < 2 * v->PixelClock[k]) {
v->DPPCLKUsingSingleDPPLuma = 2 * v->PixelClock[k];
}
if ((v->SourcePixelFormat[k] != dm_420_8 && v->SourcePixelFormat[k] != dm_420_10 && v->SourcePixelFormat[k] != dm_420_12
&& v->SourcePixelFormat[k] != dm_rgbe_alpha)) {
v->PSCL_THROUGHPUT_CHROMA[k] = 0.0;
v->DPPCLKUsingSingleDPP[k] = v->DPPCLKUsingSingleDPPLuma;
} else {
if (v->HRatioChroma[k] > 1) {
v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(
v->MaxDCHUBToPSCLThroughput,
v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
} else {
v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
}
v->DPPCLKUsingSingleDPPChroma = v->PixelClock[k]
* dml_max3(
v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_THROUGHPUT_CHROMA[k],
1.0);
if ((v->HTAPsChroma[k] > 6 || v->VTAPsChroma[k] > 6) && v->DPPCLKUsingSingleDPPChroma < 2 * v->PixelClock[k]) {
v->DPPCLKUsingSingleDPPChroma = 2 * v->PixelClock[k];
}
v->DPPCLKUsingSingleDPP[k] = dml_max(v->DPPCLKUsingSingleDPPLuma, v->DPPCLKUsingSingleDPPChroma);
}
}
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->BlendingAndTiming[k] != k)
continue;
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1) {
v->DISPCLKWithRamping = dml_max(
v->DISPCLKWithRamping,
v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
* (1 + v->DISPCLKRampingMargin / 100));
v->DISPCLKWithoutRamping = dml_max(
v->DISPCLKWithoutRamping,
v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
v->DISPCLKWithRamping = dml_max(
v->DISPCLKWithRamping,
v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
* (1 + v->DISPCLKRampingMargin / 100));
v->DISPCLKWithoutRamping = dml_max(
v->DISPCLKWithoutRamping,
v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
} else {
v->DISPCLKWithRamping = dml_max(
v->DISPCLKWithRamping,
v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) * (1 + v->DISPCLKRampingMargin / 100));
v->DISPCLKWithoutRamping = dml_max(
v->DISPCLKWithoutRamping,
v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
}
}
v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping, v->WritebackDISPCLK);
v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping, v->WritebackDISPCLK);
ASSERT(v->DISPCLKDPPCLKVCOSpeed != 0);
v->DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(v->DISPCLKWithRamping, v->DISPCLKDPPCLKVCOSpeed);
v->DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(v->DISPCLKWithoutRamping, v->DISPCLKDPPCLKVCOSpeed);
v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
v->soc.clock_limits[v->soc.num_states - 1].dispclk_mhz,
v->DISPCLKDPPCLKVCOSpeed);
if (v->DISPCLKWithoutRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) {
v->DISPCLK_calculated = v->DISPCLKWithoutRampingRoundedToDFSGranularity;
} else if (v->DISPCLKWithRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) {
v->DISPCLK_calculated = v->MaxDispclkRoundedToDFSGranularity;
} else {
v->DISPCLK_calculated = v->DISPCLKWithRampingRoundedToDFSGranularity;
}
v->DISPCLK = v->DISPCLK_calculated;
DTRACE(" dispclk_mhz (calculated) = %f", v->DISPCLK_calculated);
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->DPPCLK_calculated[k] = v->DPPCLKUsingSingleDPP[k] / v->DPPPerPlane[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
v->GlobalDPPCLK = dml_max(v->GlobalDPPCLK, v->DPPCLK_calculated[k]);
}
v->GlobalDPPCLK = RoundToDFSGranularityUp(v->GlobalDPPCLK, v->DISPCLKDPPCLKVCOSpeed);
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->DPPCLK_calculated[k] = v->GlobalDPPCLK / 255 * dml_ceil(v->DPPCLK_calculated[k] * 255.0 / v->GlobalDPPCLK, 1);
DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, v->DPPCLK_calculated[k]);
}
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->DPPCLK[k] = v->DPPCLK_calculated[k];
}
// Urgent and B P-State/DRAM Clock Change Watermark
DTRACE(" dcfclk_mhz = %f", v->DCFCLK);
DTRACE(" return_bus_bw = %f", v->ReturnBW);
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
CalculateBytePerPixelAnd256BBlockSizes(
v->SourcePixelFormat[k],
v->SurfaceTiling[k],
&v->BytePerPixelY[k],
&v->BytePerPixelC[k],
&v->BytePerPixelDETY[k],
&v->BytePerPixelDETC[k],
&v->BlockHeight256BytesY[k],
&v->BlockHeight256BytesC[k],
&v->BlockWidth256BytesY[k],
&v->BlockWidth256BytesC[k]);
}
CalculateSwathWidth(
false,
v->NumberOfActivePlanes,
v->SourcePixelFormat,
v->SourceScan,
v->ViewportWidth,
v->ViewportHeight,
v->SurfaceWidthY,
v->SurfaceWidthC,
v->SurfaceHeightY,
v->SurfaceHeightC,
v->ODMCombineEnabled,
v->BytePerPixelY,
v->BytePerPixelC,
v->BlockHeight256BytesY,
v->BlockHeight256BytesC,
v->BlockWidth256BytesY,
v->BlockWidth256BytesC,
v->BlendingAndTiming,
v->HActive,
v->HRatio,
v->DPPPerPlane,
v->SwathWidthSingleDPPY,
v->SwathWidthSingleDPPC,
v->SwathWidthY,
v->SwathWidthC,
v->dummyinteger3,
v->dummyinteger4,
v->swath_width_luma_ub,
v->swath_width_chroma_ub);
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->ReadBandwidthPlaneLuma[k] = v->SwathWidthSingleDPPY[k] * v->BytePerPixelY[k] / (v->HTotal[k] / v->PixelClock[k])
* v->VRatio[k];
v->ReadBandwidthPlaneChroma[k] = v->SwathWidthSingleDPPC[k] * v->BytePerPixelC[k] / (v->HTotal[k] / v->PixelClock[k])
* v->VRatioChroma[k];
DTRACE(" read_bw[%i] = %fBps", k, v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
}
// DCFCLK Deep Sleep
CalculateDCFCLKDeepSleep(
mode_lib,
v->NumberOfActivePlanes,
v->BytePerPixelY,
v->BytePerPixelC,
v->VRatio,
v->VRatioChroma,
v->SwathWidthY,
v->SwathWidthC,
v->DPPPerPlane,
v->HRatio,
v->HRatioChroma,
v->PixelClock,
v->PSCL_THROUGHPUT_LUMA,
v->PSCL_THROUGHPUT_CHROMA,
v->DPPCLK,
v->ReadBandwidthPlaneLuma,
v->ReadBandwidthPlaneChroma,
v->ReturnBusWidth,
&v->DCFCLKDeepSleep);
// DSCCLK
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if ((v->BlendingAndTiming[k] != k) || !v->DSCEnabled[k]) {
v->DSCCLK_calculated[k] = 0.0;
} else {
if (v->OutputFormat[k] == dm_420)
v->DSCFormatFactor = 2;
else if (v->OutputFormat[k] == dm_444)
v->DSCFormatFactor = 1;
else if (v->OutputFormat[k] == dm_n422)
v->DSCFormatFactor = 2;
else
v->DSCFormatFactor = 1;
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 12 / v->DSCFormatFactor
/ (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 6 / v->DSCFormatFactor
/ (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
else
v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 3 / v->DSCFormatFactor
/ (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
}
}
// DSC Delay
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
double BPP = v->OutputBpp[k];
if (v->DSCEnabled[k] && BPP != 0) {
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_disabled) {
v->DSCDelay[k] = dscceComputeDelay(
v->DSCInputBitPerComponent[k],
BPP,
dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
v->NumberOfDSCSlices[k],
v->OutputFormat[k],
v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
v->DSCDelay[k] = 2
* (dscceComputeDelay(
v->DSCInputBitPerComponent[k],
BPP,
dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
v->NumberOfDSCSlices[k] / 2.0,
v->OutputFormat[k],
v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
} else {
v->DSCDelay[k] = 4
* (dscceComputeDelay(
v->DSCInputBitPerComponent[k],
BPP,
dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
v->NumberOfDSCSlices[k] / 4.0,
v->OutputFormat[k],
v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
}
v->DSCDelay[k] = v->DSCDelay[k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
} else {
v->DSCDelay[k] = 0;
}
}
for (k = 0; k < v->NumberOfActivePlanes; ++k)
for (j = 0; j < v->NumberOfActivePlanes; ++j) // NumberOfPlanes
if (j != k && v->BlendingAndTiming[k] == j && v->DSCEnabled[j])
v->DSCDelay[k] = v->DSCDelay[j];
// Prefetch
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
unsigned int PDEAndMetaPTEBytesFrameY;
unsigned int PixelPTEBytesPerRowY;
unsigned int MetaRowByteY;
unsigned int MetaRowByteC;
unsigned int PDEAndMetaPTEBytesFrameC;
unsigned int PixelPTEBytesPerRowC;
bool PTEBufferSizeNotExceededY;
bool PTEBufferSizeNotExceededC;
if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
|| v->SourcePixelFormat[k] == dm_rgbe_alpha) {
if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
} else {
v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
}
PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(
mode_lib,
v->DCCEnable[k],
v->BlockHeight256BytesC[k],
v->BlockWidth256BytesC[k],
v->SourcePixelFormat[k],
v->SurfaceTiling[k],
v->BytePerPixelC[k],
v->SourceScan[k],
v->SwathWidthC[k],
v->ViewportHeightChroma[k],
v->GPUVMEnable,
v->HostVMEnable,
v->HostVMMaxNonCachedPageTableLevels,
v->GPUVMMinPageSize,
v->HostVMMinPageSize,
v->PTEBufferSizeInRequestsForChroma,
v->PitchC[k],
v->DCCMetaPitchC[k],
&v->MacroTileWidthC[k],
&MetaRowByteC,
&PixelPTEBytesPerRowC,
&PTEBufferSizeNotExceededC,
&v->dpte_row_width_chroma_ub[k],
&v->dpte_row_height_chroma[k],
&v->meta_req_width_chroma[k],
&v->meta_req_height_chroma[k],
&v->meta_row_width_chroma[k],
&v->meta_row_height_chroma[k],
&v->dummyinteger1,
&v->dummyinteger2,
&v->PixelPTEReqWidthC[k],
&v->PixelPTEReqHeightC[k],
&v->PTERequestSizeC[k],
&v->dpde0_bytes_per_frame_ub_c[k],
&v->meta_pte_bytes_per_frame_ub_c[k]);
v->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
mode_lib,
v->VRatioChroma[k],
v->VTAPsChroma[k],
v->Interlace[k],
v->ProgressiveToInterlaceUnitInOPP,
v->SwathHeightC[k],
v->ViewportYStartC[k],
&v->VInitPreFillC[k],
&v->MaxNumSwathC[k]);
} else {
v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
v->PTEBufferSizeInRequestsForChroma = 0;
PixelPTEBytesPerRowC = 0;
PDEAndMetaPTEBytesFrameC = 0;
MetaRowByteC = 0;
v->MaxNumSwathC[k] = 0;
v->PrefetchSourceLinesC[k] = 0;
}
PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
mode_lib,
v->DCCEnable[k],
v->BlockHeight256BytesY[k],
v->BlockWidth256BytesY[k],
v->SourcePixelFormat[k],
v->SurfaceTiling[k],
v->BytePerPixelY[k],
v->SourceScan[k],
v->SwathWidthY[k],
v->ViewportHeight[k],
v->GPUVMEnable,
v->HostVMEnable,
v->HostVMMaxNonCachedPageTableLevels,
v->GPUVMMinPageSize,
v->HostVMMinPageSize,
v->PTEBufferSizeInRequestsForLuma,
v->PitchY[k],
v->DCCMetaPitchY[k],
&v->MacroTileWidthY[k],
&MetaRowByteY,
&PixelPTEBytesPerRowY,
&PTEBufferSizeNotExceededY,
&v->dpte_row_width_luma_ub[k],
&v->dpte_row_height[k],
&v->meta_req_width[k],
&v->meta_req_height[k],
&v->meta_row_width[k],
&v->meta_row_height[k],
&v->vm_group_bytes[k],
&v->dpte_group_bytes[k],
&v->PixelPTEReqWidthY[k],
&v->PixelPTEReqHeightY[k],
&v->PTERequestSizeY[k],
&v->dpde0_bytes_per_frame_ub_l[k],
&v->meta_pte_bytes_per_frame_ub_l[k]);
v->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
mode_lib,
v->VRatio[k],
v->vtaps[k],
v->Interlace[k],
v->ProgressiveToInterlaceUnitInOPP,
v->SwathHeightY[k],
v->ViewportYStartY[k],
&v->VInitPreFillY[k],
&v->MaxNumSwathY[k]);
v->PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
v->PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC;
v->MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
CalculateRowBandwidth(
v->GPUVMEnable,
v->SourcePixelFormat[k],
v->VRatio[k],
v->VRatioChroma[k],
v->DCCEnable[k],
v->HTotal[k] / v->PixelClock[k],
MetaRowByteY,
MetaRowByteC,
v->meta_row_height[k],
v->meta_row_height_chroma[k],
PixelPTEBytesPerRowY,
PixelPTEBytesPerRowC,
v->dpte_row_height[k],
v->dpte_row_height_chroma[k],
&v->meta_row_bw[k],
&v->dpte_row_bw[k]);
}
v->TotalDCCActiveDPP = 0;
v->TotalActiveDPP = 0;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->TotalActiveDPP = v->TotalActiveDPP + v->DPPPerPlane[k];
if (v->DCCEnable[k])
v->TotalDCCActiveDPP = v->TotalDCCActiveDPP + v->DPPPerPlane[k];
if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
|| v->SourcePixelFormat[k] == dm_rgbe_alpha)
NoChromaPlanes = false;
}
ReorderBytes = v->NumberOfChannels
* dml_max3(
v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
VMDataOnlyReturnBW = dml_min(
dml_min(v->ReturnBusWidth * v->DCFCLK, v->FabricClock * v->FabricDatapathToDCNDataReturn)
* v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
v->DRAMSpeed * v->NumberOfChannels * v->DRAMChannelWidth
* v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly / 100.0);
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: v->ReturnBusWidth = %f\n", __func__, v->ReturnBusWidth);
dml_print("DML::%s: v->DCFCLK = %f\n", __func__, v->DCFCLK);
dml_print("DML::%s: v->FabricClock = %f\n", __func__, v->FabricClock);
dml_print("DML::%s: v->FabricDatapathToDCNDataReturn = %f\n", __func__, v->FabricDatapathToDCNDataReturn);
dml_print("DML::%s: v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = %f\n", __func__, v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency);
dml_print("DML::%s: v->DRAMSpeed = %f\n", __func__, v->DRAMSpeed);
dml_print("DML::%s: v->NumberOfChannels = %f\n", __func__, v->NumberOfChannels);
dml_print("DML::%s: v->DRAMChannelWidth = %f\n", __func__, v->DRAMChannelWidth);
dml_print("DML::%s: v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = %f\n", __func__, v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly);
dml_print("DML::%s: VMDataOnlyReturnBW = %f\n", __func__, VMDataOnlyReturnBW);
dml_print("DML::%s: ReturnBW = %f\n", __func__, v->ReturnBW);
#endif
if (v->GPUVMEnable && v->HostVMEnable)
HostVMInefficiencyFactor = v->ReturnBW / VMDataOnlyReturnBW;
v->UrgentExtraLatency = CalculateExtraLatency(
v->RoundTripPingLatencyCycles,
ReorderBytes,
v->DCFCLK,
v->TotalActiveDPP,
v->PixelChunkSizeInKByte,
v->TotalDCCActiveDPP,
v->MetaChunkSize,
v->ReturnBW,
v->GPUVMEnable,
v->HostVMEnable,
v->NumberOfActivePlanes,
v->DPPPerPlane,
v->dpte_group_bytes,
HostVMInefficiencyFactor,
v->HostVMMinPageSize,
v->HostVMMaxNonCachedPageTableLevels);
v->TCalc = 24.0 / v->DCFCLKDeepSleep;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->BlendingAndTiming[k] == k) {
if (v->WritebackEnable[k] == true) {
v->WritebackDelay[v->VoltageLevel][k] = v->WritebackLatency
+ CalculateWriteBackDelay(
v->WritebackPixelFormat[k],
v->WritebackHRatio[k],
v->WritebackVRatio[k],
v->WritebackVTaps[k],
v->WritebackDestinationWidth[k],
v->WritebackDestinationHeight[k],
v->WritebackSourceHeight[k],
v->HTotal[k]) / v->DISPCLK;
} else
v->WritebackDelay[v->VoltageLevel][k] = 0;
for (j = 0; j < v->NumberOfActivePlanes; ++j) {
if (v->BlendingAndTiming[j] == k && v->WritebackEnable[j] == true) {
v->WritebackDelay[v->VoltageLevel][k] = dml_max(
v->WritebackDelay[v->VoltageLevel][k],
v->WritebackLatency
+ CalculateWriteBackDelay(
v->WritebackPixelFormat[j],
v->WritebackHRatio[j],
v->WritebackVRatio[j],
v->WritebackVTaps[j],
v->WritebackDestinationWidth[j],
v->WritebackDestinationHeight[j],
v->WritebackSourceHeight[j],
v->HTotal[k]) / v->DISPCLK);
}
}
}
}
for (k = 0; k < v->NumberOfActivePlanes; ++k)
for (j = 0; j < v->NumberOfActivePlanes; ++j)
if (v->BlendingAndTiming[k] == j)
v->WritebackDelay[v->VoltageLevel][k] = v->WritebackDelay[v->VoltageLevel][j];
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->MaxVStartupLines[k] =
(v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP) ?
dml_floor((v->VTotal[k] - v->VActive[k]) / 2.0, 1.0) :
v->VTotal[k] - v->VActive[k]
- dml_max(
1.0,
dml_ceil(
(double) v->WritebackDelay[v->VoltageLevel][k]
/ (v->HTotal[k] / v->PixelClock[k]),
1));
if (v->MaxVStartupLines[k] > 1023)
v->MaxVStartupLines[k] = 1023;
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: k=%d MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]);
dml_print("DML::%s: k=%d VoltageLevel = %d\n", __func__, k, v->VoltageLevel);
dml_print("DML::%s: k=%d WritebackDelay = %f\n", __func__, k, v->WritebackDelay[v->VoltageLevel][k]);
#endif
}
v->MaximumMaxVStartupLines = 0;
for (k = 0; k < v->NumberOfActivePlanes; ++k)
v->MaximumMaxVStartupLines = dml_max(v->MaximumMaxVStartupLines, v->MaxVStartupLines[k]);
// VBA_DELTA
// We don't really care to iterate between the various prefetch modes
//v->PrefetchERROR = CalculateMinAndMaxPrefetchMode(v->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &v->MinPrefetchMode, &v->MaxPrefetchMode);
v->UrgentLatency = CalculateUrgentLatency(
v->UrgentLatencyPixelDataOnly,
v->UrgentLatencyPixelMixedWithVMData,
v->UrgentLatencyVMDataOnly,
v->DoUrgentLatencyAdjustment,
v->UrgentLatencyAdjustmentFabricClockComponent,
v->UrgentLatencyAdjustmentFabricClockReference,
v->FabricClock);
v->FractionOfUrgentBandwidth = 0.0;
v->FractionOfUrgentBandwidthImmediateFlip = 0.0;
v->VStartupLines = __DML_VBA_MIN_VSTARTUP__;
do {
double MaxTotalRDBandwidthNoUrgentBurst = 0.0;
bool DestinationLineTimesForPrefetchLessThan2 = false;
bool VRatioPrefetchMoreThan4 = false;
double TWait = CalculateTWait(PrefetchMode, v->DRAMClockChangeLatency, v->UrgentLatency, v->SREnterPlusExitTime);
MaxTotalRDBandwidth = 0;
dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, v->VStartupLines);
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
Pipe myPipe;
myPipe.DPPCLK = v->DPPCLK[k];
myPipe.DISPCLK = v->DISPCLK;
myPipe.PixelClock = v->PixelClock[k];
myPipe.DCFCLKDeepSleep = v->DCFCLKDeepSleep;
myPipe.DPPPerPlane = v->DPPPerPlane[k];
myPipe.ScalerEnabled = v->ScalerEnabled[k];
myPipe.SourceScan = v->SourceScan[k];
myPipe.BlockWidth256BytesY = v->BlockWidth256BytesY[k];
myPipe.BlockHeight256BytesY = v->BlockHeight256BytesY[k];
myPipe.BlockWidth256BytesC = v->BlockWidth256BytesC[k];
myPipe.BlockHeight256BytesC = v->BlockHeight256BytesC[k];
myPipe.InterlaceEnable = v->Interlace[k];
myPipe.NumberOfCursors = v->NumberOfCursors[k];
myPipe.VBlank = v->VTotal[k] - v->VActive[k];
myPipe.HTotal = v->HTotal[k];
myPipe.DCCEnable = v->DCCEnable[k];
myPipe.ODMCombineIsEnabled = v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1
|| v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1;
myPipe.SourcePixelFormat = v->SourcePixelFormat[k];
myPipe.BytePerPixelY = v->BytePerPixelY[k];
myPipe.BytePerPixelC = v->BytePerPixelC[k];
myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP;
v->ErrorResult[k] = CalculatePrefetchSchedule(
mode_lib,
HostVMInefficiencyFactor,
&myPipe,
v->DSCDelay[k],
v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
v->DPPCLKDelaySCL,
v->DPPCLKDelaySCLLBOnly,
v->DPPCLKDelayCNVCCursor,
v->DISPCLKDelaySubtotal,
(unsigned int) (v->SwathWidthY[k] / v->HRatio[k]),
v->OutputFormat[k],
v->MaxInterDCNTileRepeaters,
dml_min(v->VStartupLines, v->MaxVStartupLines[k]),
v->MaxVStartupLines[k],
v->GPUVMMaxPageTableLevels,
v->GPUVMEnable,
v->HostVMEnable,
v->HostVMMaxNonCachedPageTableLevels,
v->HostVMMinPageSize,
v->DynamicMetadataEnable[k],
v->DynamicMetadataVMEnabled,
v->DynamicMetadataLinesBeforeActiveRequired[k],
v->DynamicMetadataTransmittedBytes[k],
v->UrgentLatency,
v->UrgentExtraLatency,
v->TCalc,
v->PDEAndMetaPTEBytesFrame[k],
v->MetaRowByte[k],
v->PixelPTEBytesPerRow[k],
v->PrefetchSourceLinesY[k],
v->SwathWidthY[k],
v->VInitPreFillY[k],
v->MaxNumSwathY[k],
v->PrefetchSourceLinesC[k],
v->SwathWidthC[k],
v->VInitPreFillC[k],
v->MaxNumSwathC[k],
v->swath_width_luma_ub[k],
v->swath_width_chroma_ub[k],
v->SwathHeightY[k],
v->SwathHeightC[k],
TWait,
&v->DSTXAfterScaler[k],
&v->DSTYAfterScaler[k],
&v->DestinationLinesForPrefetch[k],
&v->PrefetchBandwidth[k],
&v->DestinationLinesToRequestVMInVBlank[k],
&v->DestinationLinesToRequestRowInVBlank[k],
&v->VRatioPrefetchY[k],
&v->VRatioPrefetchC[k],
&v->RequiredPrefetchPixDataBWLuma[k],
&v->RequiredPrefetchPixDataBWChroma[k],
&v->NotEnoughTimeForDynamicMetadata[k],
&v->Tno_bw[k],
&v->prefetch_vmrow_bw[k],
&v->Tdmdl_vm[k],
&v->Tdmdl[k],
&v->TSetup[k],
&v->VUpdateOffsetPix[k],
&v->VUpdateWidthPix[k],
&v->VReadyOffsetPix[k]);
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: k=%0d Prefetch cal result=%0d\n", __func__, k, v->ErrorResult[k]);
#endif
v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[k]);
}
v->NoEnoughUrgentLatencyHiding = false;
v->NoEnoughUrgentLatencyHidingPre = false;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->cursor_bw[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatioPrefetchY[k];
CalculateUrgentBurstFactor(
v->swath_width_luma_ub[k],
v->swath_width_chroma_ub[k],
v->SwathHeightY[k],
v->SwathHeightC[k],
v->HTotal[k] / v->PixelClock[k],
v->UrgentLatency,
v->CursorBufferSize,
v->CursorWidth[k][0],
v->CursorBPP[k][0],
v->VRatio[k],
v->VRatioChroma[k],
v->BytePerPixelDETY[k],
v->BytePerPixelDETC[k],
v->DETBufferSizeY[k],
v->DETBufferSizeC[k],
&v->UrgBurstFactorCursor[k],
&v->UrgBurstFactorLuma[k],
&v->UrgBurstFactorChroma[k],
&v->NoUrgentLatencyHiding[k]);
CalculateUrgentBurstFactor(
v->swath_width_luma_ub[k],
v->swath_width_chroma_ub[k],
v->SwathHeightY[k],
v->SwathHeightC[k],
v->HTotal[k] / v->PixelClock[k],
v->UrgentLatency,
v->CursorBufferSize,
v->CursorWidth[k][0],
v->CursorBPP[k][0],
v->VRatioPrefetchY[k],
v->VRatioPrefetchC[k],
v->BytePerPixelDETY[k],
v->BytePerPixelDETC[k],
v->DETBufferSizeY[k],
v->DETBufferSizeC[k],
&v->UrgBurstFactorCursorPre[k],
&v->UrgBurstFactorLumaPre[k],
&v->UrgBurstFactorChromaPre[k],
&v->NoUrgentLatencyHidingPre[k]);
MaxTotalRDBandwidth = MaxTotalRDBandwidth
+ dml_max3(
v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
v->ReadBandwidthPlaneLuma[k] * v->UrgBurstFactorLuma[k]
+ v->ReadBandwidthPlaneChroma[k] * v->UrgBurstFactorChroma[k]
+ v->cursor_bw[k] * v->UrgBurstFactorCursor[k]
+ v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
v->DPPPerPlane[k]
* (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
+ v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
+ v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
MaxTotalRDBandwidthNoUrgentBurst = MaxTotalRDBandwidthNoUrgentBurst
+ dml_max3(
v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k]
+ v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k])
+ v->cursor_bw_pre[k]);
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: k=%0d DPPPerPlane=%d\n", __func__, k, v->DPPPerPlane[k]);
dml_print("DML::%s: k=%0d UrgBurstFactorLuma=%f\n", __func__, k, v->UrgBurstFactorLuma[k]);
dml_print("DML::%s: k=%0d UrgBurstFactorChroma=%f\n", __func__, k, v->UrgBurstFactorChroma[k]);
dml_print("DML::%s: k=%0d UrgBurstFactorLumaPre=%f\n", __func__, k, v->UrgBurstFactorLumaPre[k]);
dml_print("DML::%s: k=%0d UrgBurstFactorChromaPre=%f\n", __func__, k, v->UrgBurstFactorChromaPre[k]);
dml_print("DML::%s: k=%0d VRatioPrefetchY=%f\n", __func__, k, v->VRatioPrefetchY[k]);
dml_print("DML::%s: k=%0d VRatioY=%f\n", __func__, k, v->VRatio[k]);
dml_print("DML::%s: k=%0d prefetch_vmrow_bw=%f\n", __func__, k, v->prefetch_vmrow_bw[k]);
dml_print("DML::%s: k=%0d ReadBandwidthPlaneLuma=%f\n", __func__, k, v->ReadBandwidthPlaneLuma[k]);
dml_print("DML::%s: k=%0d ReadBandwidthPlaneChroma=%f\n", __func__, k, v->ReadBandwidthPlaneChroma[k]);
dml_print("DML::%s: k=%0d cursor_bw=%f\n", __func__, k, v->cursor_bw[k]);
dml_print("DML::%s: k=%0d meta_row_bw=%f\n", __func__, k, v->meta_row_bw[k]);
dml_print("DML::%s: k=%0d dpte_row_bw=%f\n", __func__, k, v->dpte_row_bw[k]);
dml_print("DML::%s: k=%0d RequiredPrefetchPixDataBWLuma=%f\n", __func__, k, v->RequiredPrefetchPixDataBWLuma[k]);
dml_print("DML::%s: k=%0d RequiredPrefetchPixDataBWChroma=%f\n", __func__, k, v->RequiredPrefetchPixDataBWChroma[k]);
dml_print("DML::%s: k=%0d cursor_bw_pre=%f\n", __func__, k, v->cursor_bw_pre[k]);
dml_print("DML::%s: k=%0d MaxTotalRDBandwidthNoUrgentBurst=%f\n", __func__, k, MaxTotalRDBandwidthNoUrgentBurst);
#endif
if (v->DestinationLinesForPrefetch[k] < 2)
DestinationLineTimesForPrefetchLessThan2 = true;
if (v->VRatioPrefetchY[k] > 4 || v->VRatioPrefetchC[k] > 4)
VRatioPrefetchMoreThan4 = true;
if (v->NoUrgentLatencyHiding[k] == true)
v->NoEnoughUrgentLatencyHiding = true;
if (v->NoUrgentLatencyHidingPre[k] == true)
v->NoEnoughUrgentLatencyHidingPre = true;
}
v->FractionOfUrgentBandwidth = MaxTotalRDBandwidthNoUrgentBurst / v->ReturnBW;
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: MaxTotalRDBandwidthNoUrgentBurst=%f \n", __func__, MaxTotalRDBandwidthNoUrgentBurst);
dml_print("DML::%s: ReturnBW=%f \n", __func__, v->ReturnBW);
dml_print("DML::%s: FractionOfUrgentBandwidth=%f \n", __func__, v->FractionOfUrgentBandwidth);
#endif
if (MaxTotalRDBandwidth <= v->ReturnBW && v->NoEnoughUrgentLatencyHiding == 0 && v->NoEnoughUrgentLatencyHidingPre == 0
&& !VRatioPrefetchMoreThan4 && !DestinationLineTimesForPrefetchLessThan2)
v->PrefetchModeSupported = true;
else {
v->PrefetchModeSupported = false;
dml_print("DML::%s: ***failed***. Bandwidth violation. Results are NOT valid\n", __func__);
dml_print("DML::%s: MaxTotalRDBandwidth:%f AvailReturnBandwidth:%f\n", __func__, MaxTotalRDBandwidth, v->ReturnBW);
dml_print("DML::%s: VRatioPrefetch %s more than 4\n", __func__, (VRatioPrefetchMoreThan4) ? "is" : "is not");
dml_print("DML::%s: DestinationLines for Prefetch %s less than 2\n", __func__, (DestinationLineTimesForPrefetchLessThan2) ? "is" : "is not");
}
// PREVIOUS_ERROR
// This error result check was done after the PrefetchModeSupported. So we will
// still try to calculate flip schedule even prefetch mode not supported
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->ErrorResult[k] == true || v->NotEnoughTimeForDynamicMetadata[k] == true) {
v->PrefetchModeSupported = false;
dml_print("DML::%s: ***failed***. Prefetch schedule violation. Results are NOT valid\n", __func__);
}
}
if (v->PrefetchModeSupported == true && v->ImmediateFlipSupport == true) {
v->BandwidthAvailableForImmediateFlip = v->ReturnBW;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
- dml_max(
v->ReadBandwidthPlaneLuma[k] * v->UrgBurstFactorLuma[k]
+ v->ReadBandwidthPlaneChroma[k] * v->UrgBurstFactorChroma[k]
+ v->cursor_bw[k] * v->UrgBurstFactorCursor[k],
v->DPPPerPlane[k]
* (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
+ v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
+ v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
}
v->TotImmediateFlipBytes = 0;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->TotImmediateFlipBytes = v->TotImmediateFlipBytes
+ v->DPPPerPlane[k] * (v->PDEAndMetaPTEBytesFrame[k] + v->MetaRowByte[k] + v->PixelPTEBytesPerRow[k]);
}
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
CalculateFlipSchedule(
mode_lib,
HostVMInefficiencyFactor,
v->UrgentExtraLatency,
v->UrgentLatency,
v->GPUVMMaxPageTableLevels,
v->HostVMEnable,
v->HostVMMaxNonCachedPageTableLevels,
v->GPUVMEnable,
v->HostVMMinPageSize,
v->PDEAndMetaPTEBytesFrame[k],
v->MetaRowByte[k],
v->PixelPTEBytesPerRow[k],
v->BandwidthAvailableForImmediateFlip,
v->TotImmediateFlipBytes,
v->SourcePixelFormat[k],
v->HTotal[k] / v->PixelClock[k],
v->VRatio[k],
v->VRatioChroma[k],
v->Tno_bw[k],
v->DCCEnable[k],
v->dpte_row_height[k],
v->meta_row_height[k],
v->dpte_row_height_chroma[k],
v->meta_row_height_chroma[k],
&v->DestinationLinesToRequestVMInImmediateFlip[k],
&v->DestinationLinesToRequestRowInImmediateFlip[k],
&v->final_flip_bw[k],
&v->ImmediateFlipSupportedForPipe[k]);
}
v->total_dcn_read_bw_with_flip = 0.0;
v->total_dcn_read_bw_with_flip_no_urgent_burst = 0.0;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
+ dml_max3(
v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
v->DPPPerPlane[k] * v->final_flip_bw[k]
+ v->ReadBandwidthLuma[k] * v->UrgBurstFactorLuma[k]
+ v->ReadBandwidthChroma[k] * v->UrgBurstFactorChroma[k]
+ v->cursor_bw[k] * v->UrgBurstFactorCursor[k],
v->DPPPerPlane[k]
* (v->final_flip_bw[k]
+ v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
+ v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
+ v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
v->total_dcn_read_bw_with_flip_no_urgent_burst = v->total_dcn_read_bw_with_flip_no_urgent_burst
+ dml_max3(
v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
v->DPPPerPlane[k] * v->final_flip_bw[k] + v->ReadBandwidthPlaneLuma[k]
+ v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k],
v->DPPPerPlane[k]
* (v->final_flip_bw[k] + v->RequiredPrefetchPixDataBWLuma[k]
+ v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
}
v->FractionOfUrgentBandwidthImmediateFlip = v->total_dcn_read_bw_with_flip_no_urgent_burst / v->ReturnBW;
v->ImmediateFlipSupported = true;
if (v->total_dcn_read_bw_with_flip > v->ReturnBW) {
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: total_dcn_read_bw_with_flip %f (bw w/ flip too high!)\n", __func__, v->total_dcn_read_bw_with_flip);
#endif
v->ImmediateFlipSupported = false;
v->total_dcn_read_bw_with_flip = MaxTotalRDBandwidth;
}
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->ImmediateFlipSupportedForPipe[k] == false) {
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: Pipe %0d not supporting iflip\n",
__func__, k);
#endif
v->ImmediateFlipSupported = false;
}
}
} else {
v->ImmediateFlipSupported = false;
}
v->PrefetchAndImmediateFlipSupported =
(v->PrefetchModeSupported == true && ((!v->ImmediateFlipSupport && !v->HostVMEnable
&& v->ImmediateFlipRequirement[0] != dm_immediate_flip_required) ||
v->ImmediateFlipSupported)) ? true : false;
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: PrefetchModeSupported %d\n", __func__, v->PrefetchModeSupported);
dml_print("DML::%s: ImmediateFlipRequirement %d\n", __func__, v->ImmediateFlipRequirement == dm_immediate_flip_required);
dml_print("DML::%s: ImmediateFlipSupported %d\n", __func__, v->ImmediateFlipSupported);
dml_print("DML::%s: ImmediateFlipSupport %d\n", __func__, v->ImmediateFlipSupport);
dml_print("DML::%s: HostVMEnable %d\n", __func__, v->HostVMEnable);
dml_print("DML::%s: PrefetchAndImmediateFlipSupported %d\n", __func__, v->PrefetchAndImmediateFlipSupported);
#endif
dml_print("DML::%s: Done loop: Vstartup=%d, Max Vstartup is %d\n", __func__, v->VStartupLines, v->MaximumMaxVStartupLines);
v->VStartupLines = v->VStartupLines + 1;
} while (!v->PrefetchAndImmediateFlipSupported && v->VStartupLines <= v->MaximumMaxVStartupLines);
ASSERT(v->PrefetchAndImmediateFlipSupported);
// Unbounded Request Enabled
CalculateUnboundedRequestAndCompressedBufferSize(
v->DETBufferSizeInKByte[0],
v->ConfigReturnBufferSizeInKByte,
v->UseUnboundedRequesting,
v->TotalActiveDPP,
NoChromaPlanes,
v->MaxNumDPP,
v->CompressedBufferSegmentSizeInkByte,
v->Output,
&v->UnboundedRequestEnabled,
&v->CompressedBufferSizeInkByte);
//Watermarks and NB P-State/DRAM Clock Change Support
{
enum clock_change_support DRAMClockChangeSupport; // dummy
CalculateWatermarksAndDRAMSpeedChangeSupport(
mode_lib,
PrefetchMode,
v->NumberOfActivePlanes,
v->MaxLineBufferLines,
v->LineBufferSize,
v->WritebackInterfaceBufferSize,
v->DCFCLK,
v->ReturnBW,
v->SynchronizedVBlank,
v->dpte_group_bytes,
v->MetaChunkSize,
v->UrgentLatency,
v->UrgentExtraLatency,
v->WritebackLatency,
v->WritebackChunkSize,
v->SOCCLK,
v->DRAMClockChangeLatency,
v->SRExitTime,
v->SREnterPlusExitTime,
v->SRExitZ8Time,
v->SREnterPlusExitZ8Time,
v->DCFCLKDeepSleep,
v->DETBufferSizeY,
v->DETBufferSizeC,
v->SwathHeightY,
v->SwathHeightC,
v->LBBitPerPixel,
v->SwathWidthY,
v->SwathWidthC,
v->HRatio,
v->HRatioChroma,
v->vtaps,
v->VTAPsChroma,
v->VRatio,
v->VRatioChroma,
v->HTotal,
v->PixelClock,
v->BlendingAndTiming,
v->DPPPerPlane,
v->BytePerPixelDETY,
v->BytePerPixelDETC,
v->DSTXAfterScaler,
v->DSTYAfterScaler,
v->WritebackEnable,
v->WritebackPixelFormat,
v->WritebackDestinationWidth,
v->WritebackDestinationHeight,
v->WritebackSourceHeight,
v->UnboundedRequestEnabled,
v->CompressedBufferSizeInkByte,
&DRAMClockChangeSupport,
&v->UrgentWatermark,
&v->WritebackUrgentWatermark,
&v->DRAMClockChangeWatermark,
&v->WritebackDRAMClockChangeWatermark,
&v->StutterExitWatermark,
&v->StutterEnterPlusExitWatermark,
&v->Z8StutterExitWatermark,
&v->Z8StutterEnterPlusExitWatermark,
&v->MinActiveDRAMClockChangeLatencySupported);
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->WritebackEnable[k] == true) {
v->WritebackAllowDRAMClockChangeEndPosition[k] = dml_max(
0,
v->VStartup[k] * v->HTotal[k] / v->PixelClock[k] - v->WritebackDRAMClockChangeWatermark);
} else {
v->WritebackAllowDRAMClockChangeEndPosition[k] = 0;
}
}
}
//Display Pipeline Delivery Time in Prefetch, Groups
CalculatePixelDeliveryTimes(
v->NumberOfActivePlanes,
v->VRatio,
v->VRatioChroma,
v->VRatioPrefetchY,
v->VRatioPrefetchC,
v->swath_width_luma_ub,
v->swath_width_chroma_ub,
v->DPPPerPlane,
v->HRatio,
v->HRatioChroma,
v->PixelClock,
v->PSCL_THROUGHPUT_LUMA,
v->PSCL_THROUGHPUT_CHROMA,
v->DPPCLK,
v->BytePerPixelC,
v->SourceScan,
v->NumberOfCursors,
v->CursorWidth,
v->CursorBPP,
v->BlockWidth256BytesY,
v->BlockHeight256BytesY,
v->BlockWidth256BytesC,
v->BlockHeight256BytesC,
v->DisplayPipeLineDeliveryTimeLuma,
v->DisplayPipeLineDeliveryTimeChroma,
v->DisplayPipeLineDeliveryTimeLumaPrefetch,
v->DisplayPipeLineDeliveryTimeChromaPrefetch,
v->DisplayPipeRequestDeliveryTimeLuma,
v->DisplayPipeRequestDeliveryTimeChroma,
v->DisplayPipeRequestDeliveryTimeLumaPrefetch,
v->DisplayPipeRequestDeliveryTimeChromaPrefetch,
v->CursorRequestDeliveryTime,
v->CursorRequestDeliveryTimePrefetch);
CalculateMetaAndPTETimes(
v->NumberOfActivePlanes,
v->GPUVMEnable,
v->MetaChunkSize,
v->MinMetaChunkSizeBytes,
v->HTotal,
v->VRatio,
v->VRatioChroma,
v->DestinationLinesToRequestRowInVBlank,
v->DestinationLinesToRequestRowInImmediateFlip,
v->DCCEnable,
v->PixelClock,
v->BytePerPixelY,
v->BytePerPixelC,
v->SourceScan,
v->dpte_row_height,
v->dpte_row_height_chroma,
v->meta_row_width,
v->meta_row_width_chroma,
v->meta_row_height,
v->meta_row_height_chroma,
v->meta_req_width,
v->meta_req_width_chroma,
v->meta_req_height,
v->meta_req_height_chroma,
v->dpte_group_bytes,
v->PTERequestSizeY,
v->PTERequestSizeC,
v->PixelPTEReqWidthY,
v->PixelPTEReqHeightY,
v->PixelPTEReqWidthC,
v->PixelPTEReqHeightC,
v->dpte_row_width_luma_ub,
v->dpte_row_width_chroma_ub,
v->DST_Y_PER_PTE_ROW_NOM_L,
v->DST_Y_PER_PTE_ROW_NOM_C,
v->DST_Y_PER_META_ROW_NOM_L,
v->DST_Y_PER_META_ROW_NOM_C,
v->TimePerMetaChunkNominal,
v->TimePerChromaMetaChunkNominal,
v->TimePerMetaChunkVBlank,
v->TimePerChromaMetaChunkVBlank,
v->TimePerMetaChunkFlip,
v->TimePerChromaMetaChunkFlip,
v->time_per_pte_group_nom_luma,
v->time_per_pte_group_vblank_luma,
v->time_per_pte_group_flip_luma,
v->time_per_pte_group_nom_chroma,
v->time_per_pte_group_vblank_chroma,
v->time_per_pte_group_flip_chroma);
CalculateVMGroupAndRequestTimes(
v->NumberOfActivePlanes,
v->GPUVMEnable,
v->GPUVMMaxPageTableLevels,
v->HTotal,
v->BytePerPixelC,
v->DestinationLinesToRequestVMInVBlank,
v->DestinationLinesToRequestVMInImmediateFlip,
v->DCCEnable,
v->PixelClock,
v->dpte_row_width_luma_ub,
v->dpte_row_width_chroma_ub,
v->vm_group_bytes,
v->dpde0_bytes_per_frame_ub_l,
v->dpde0_bytes_per_frame_ub_c,
v->meta_pte_bytes_per_frame_ub_l,
v->meta_pte_bytes_per_frame_ub_c,
v->TimePerVMGroupVBlank,
v->TimePerVMGroupFlip,
v->TimePerVMRequestVBlank,
v->TimePerVMRequestFlip);
// Min TTUVBlank
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (PrefetchMode == 0) {
v->AllowDRAMClockChangeDuringVBlank[k] = true;
v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
v->MinTTUVBlank[k] = dml_max(
v->DRAMClockChangeWatermark,
dml_max(v->StutterEnterPlusExitWatermark, v->UrgentWatermark));
} else if (PrefetchMode == 1) {
v->AllowDRAMClockChangeDuringVBlank[k] = false;
v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
v->MinTTUVBlank[k] = dml_max(v->StutterEnterPlusExitWatermark, v->UrgentWatermark);
} else {
v->AllowDRAMClockChangeDuringVBlank[k] = false;
v->AllowDRAMSelfRefreshDuringVBlank[k] = false;
v->MinTTUVBlank[k] = v->UrgentWatermark;
}
if (!v->DynamicMetadataEnable[k])
v->MinTTUVBlank[k] = v->TCalc + v->MinTTUVBlank[k];
}
// DCC Configuration
v->ActiveDPPs = 0;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
CalculateDCCConfiguration(v->DCCEnable[k], false, // We should always know the direction DCCProgrammingAssumesScanDirectionUnknown,
v->SourcePixelFormat[k],
v->SurfaceWidthY[k],
v->SurfaceWidthC[k],
v->SurfaceHeightY[k],
v->SurfaceHeightC[k],
v->DETBufferSizeInKByte[0] * 1024,
v->BlockHeight256BytesY[k],
v->BlockHeight256BytesC[k],
v->SurfaceTiling[k],
v->BytePerPixelY[k],
v->BytePerPixelC[k],
v->BytePerPixelDETY[k],
v->BytePerPixelDETC[k],
v->SourceScan[k],
&v->DCCYMaxUncompressedBlock[k],
&v->DCCCMaxUncompressedBlock[k],
&v->DCCYMaxCompressedBlock[k],
&v->DCCCMaxCompressedBlock[k],
&v->DCCYIndependentBlock[k],
&v->DCCCIndependentBlock[k]);
}
// VStartup Adjustment
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
bool isInterlaceTiming;
double Tvstartup_margin = (v->MaxVStartupLines[k] - v->VStartup[k]) * v->HTotal[k] / v->PixelClock[k];
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: k=%d, MinTTUVBlank = %f (before margin)\n", __func__, k, v->MinTTUVBlank[k]);
#endif
v->MinTTUVBlank[k] = v->MinTTUVBlank[k] + Tvstartup_margin;
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: k=%d, Tvstartup_margin = %f\n", __func__, k, Tvstartup_margin);
dml_print("DML::%s: k=%d, MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]);
dml_print("DML::%s: k=%d, VStartup = %d\n", __func__, k, v->VStartup[k]);
dml_print("DML::%s: k=%d, MinTTUVBlank = %f\n", __func__, k, v->MinTTUVBlank[k]);
#endif
v->Tdmdl[k] = v->Tdmdl[k] + Tvstartup_margin;
if (v->DynamicMetadataEnable[k] && v->DynamicMetadataVMEnabled) {
v->Tdmdl_vm[k] = v->Tdmdl_vm[k] + Tvstartup_margin;
}
isInterlaceTiming = (v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP);
v->MIN_DST_Y_NEXT_START[k] = ((isInterlaceTiming ? dml_floor((v->VTotal[k] - v->VFrontPorch[k]) / 2.0, 1.0) : v->VTotal[k])
- v->VFrontPorch[k])
+ dml_max(1.0, dml_ceil(v->WritebackDelay[v->VoltageLevel][k] / (v->HTotal[k] / v->PixelClock[k]), 1.0))
+ dml_floor(4.0 * v->TSetup[k] / (v->HTotal[k] / v->PixelClock[k]), 1.0) / 4.0;
v->VStartup[k] = (isInterlaceTiming ? (2 * v->MaxVStartupLines[k]) : v->MaxVStartupLines[k]);
if (((v->VUpdateOffsetPix[k] + v->VUpdateWidthPix[k] + v->VReadyOffsetPix[k]) / v->HTotal[k])
<= (isInterlaceTiming ?
dml_floor((v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]) / 2.0, 1.0) :
(int) (v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]))) {
v->VREADY_AT_OR_AFTER_VSYNC[k] = true;
} else {
v->VREADY_AT_OR_AFTER_VSYNC[k] = false;
}
#ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: k=%d, VStartup = %d (max)\n", __func__, k, v->VStartup[k]);
dml_print("DML::%s: k=%d, VUpdateOffsetPix = %d\n", __func__, k, v->VUpdateOffsetPix[k]);
dml_print("DML::%s: k=%d, VUpdateWidthPix = %d\n", __func__, k, v->VUpdateWidthPix[k]);
dml_print("DML::%s: k=%d, VReadyOffsetPix = %d\n", __func__, k, v->VReadyOffsetPix[k]);
dml_print("DML::%s: k=%d, HTotal = %d\n", __func__, k, v->HTotal[k]);
dml_print("DML::%s: k=%d, VTotal = %d\n", __func__, k, v->VTotal[k]);
dml_print("DML::%s: k=%d, VActive = %d\n", __func__, k, v->VActive[k]);
dml_print("DML::%s: k=%d, VFrontPorch = %d\n", __func__, k, v->VFrontPorch[k]);
dml_print("DML::%s: k=%d, VStartup = %d\n", __func__, k, v->VStartup[k]);
dml_print("DML::%s: k=%d, MIN_DST_Y_NEXT_START = %f\n", __func__, k, v->MIN_DST_Y_NEXT_START[k]);
dml_print("DML::%s: k=%d, VREADY_AT_OR_AFTER_VSYNC = %d\n", __func__, k, v->VREADY_AT_OR_AFTER_VSYNC[k]);
#endif
}
{
//Maximum Bandwidth Used
double TotalWRBandwidth = 0;
double MaxPerPlaneVActiveWRBandwidth = 0;
double WRBandwidth = 0;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
if (v->WritebackEnable[k] == true && v->WritebackPixelFormat[k] == dm_444_32) {
WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 4;
} else if (v->WritebackEnable[k] == true) {
WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 8;
}
TotalWRBandwidth = TotalWRBandwidth + WRBandwidth;
MaxPerPlaneVActiveWRBandwidth = dml_max(MaxPerPlaneVActiveWRBandwidth, WRBandwidth);
}
v->TotalDataReadBandwidth = 0;
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->TotalDataReadBandwidth = v->TotalDataReadBandwidth + v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k];
}
}
// Stutter Efficiency
CalculateStutterEfficiency(
mode_lib,
v->CompressedBufferSizeInkByte,
v->UnboundedRequestEnabled,
v->ConfigReturnBufferSizeInKByte,
v->MetaFIFOSizeInKEntries,
v->ZeroSizeBufferEntries,
v->NumberOfActivePlanes,
v->ROBBufferSizeInKByte,
v->TotalDataReadBandwidth,
v->DCFCLK,
v->ReturnBW,
v->COMPBUF_RESERVED_SPACE_64B,
v->COMPBUF_RESERVED_SPACE_ZS,
v->SRExitTime,
v->SRExitZ8Time,
v->SynchronizedVBlank,
v->StutterEnterPlusExitWatermark,
v->Z8StutterEnterPlusExitWatermark,
v->ProgressiveToInterlaceUnitInOPP,
v->Interlace,
v->MinTTUVBlank,
v->DPPPerPlane,
v->DETBufferSizeY,
v->BytePerPixelY,
v->BytePerPixelDETY,
v->SwathWidthY,
v->SwathHeightY,
v->SwathHeightC,
v->DCCRateLuma,
v->DCCRateChroma,
v->DCCFractionOfZeroSizeRequestsLuma,
v->DCCFractionOfZeroSizeRequestsChroma,
v->HTotal,
v->VTotal,
v->PixelClock,
v->VRatio,
v->SourceScan,
v->BlockHeight256BytesY,
v->BlockWidth256BytesY,
v->BlockHeight256BytesC,
v->BlockWidth256BytesC,
v->DCCYMaxUncompressedBlock,
v->DCCCMaxUncompressedBlock,
v->VActive,
v->DCCEnable,
v->WritebackEnable,
v->ReadBandwidthPlaneLuma,
v->ReadBandwidthPlaneChroma,
v->meta_row_bw,
v->dpte_row_bw,
&v->StutterEfficiencyNotIncludingVBlank,
&v->StutterEfficiency,
&v->NumberOfStutterBurstsPerFrame,
&v->Z8StutterEfficiencyNotIncludingVBlank,
&v->Z8StutterEfficiency,
&v->Z8NumberOfStutterBurstsPerFrame,
&v->StutterPeriod);
}