blob: 260e113fcc02682f8e731e2c0ec0ed621b77e0b4 [file] [log] [blame]
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "display_mode_lib.h"
#include "display_mode_vba.h"
#include "dml_inline_defs.h"
/*
* NOTE:
* This file is gcc-parseable HW gospel, coming straight from HW engineers.
*
* It doesn't adhere to Linux kernel style and sometimes will do things in odd
* ways. Unless there is something clearly wrong with it the code should
* remain as-is as it provides us with a guarantee from HW that it is correct.
*/
#define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff
static const unsigned int NumberOfStates = DC__VOLTAGE_STATES;
static void fetch_socbb_params(struct display_mode_lib *mode_lib);
static void fetch_ip_params(struct display_mode_lib *mode_lib);
static void fetch_pipe_params(struct display_mode_lib *mode_lib);
static void recalculate_params(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
static void recalculate(struct display_mode_lib *mode_lib);
static double adjust_ReturnBW(
struct display_mode_lib *mode_lib,
double ReturnBW,
bool DCCEnabledAnyPlane,
double ReturnBandwidthToDCN);
static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
struct display_mode_lib *mode_lib);
static unsigned int dscceComputeDelay(
unsigned int bpc,
double bpp,
unsigned int sliceWidth,
unsigned int numSlices,
enum output_format_class pixelFormat);
static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
// Super monster function with some 45 argument
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double 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 VirtualMemoryEnable,
bool DynamicMetadataEnable,
unsigned int DynamicMetadataLinesBeforeActiveRequired,
unsigned int DynamicMetadataTransmittedBytes,
bool DCCEnable,
double UrgentLatency,
double UrgentExtraLatency,
double TCalc,
unsigned int PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
double PrefetchSourceLinesY,
unsigned int SwathWidthY,
double BytePerPixelDETY,
double VInitPreFillY,
unsigned int MaxNumSwathY,
double PrefetchSourceLinesC,
double BytePerPixelDETC,
double VInitPreFillC,
unsigned int MaxNumSwathC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
double TWait,
bool XFCEnabled,
double XFCRemoteSurfaceFlipDelay,
bool 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,
unsigned int *VUpdateWidthPix,
unsigned int *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 VirtualMemoryEnable,
unsigned int VMMPageSize,
unsigned int PTEBufferSizeInRequests,
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 UrgentLatency,
double SREnterPlusExitTime);
static double CalculateRemoteSurfaceFlipDelay(
struct display_mode_lib *mode_lib,
double VRatio,
double SwathWidth,
double Bpp,
double LineTime,
double XFCTSlvVupdateOffset,
double XFCTSlvVupdateWidth,
double XFCTSlvVreadyOffset,
double XFCXBUFLatencyTolerance,
double XFCFillBWOverhead,
double XFCSlvChunkSize,
double XFCBusTransportTime,
double TCalc,
double TWait,
double *SrcActiveDrainRate,
double *TInitXFill,
double *TslvChk);
static double CalculateWriteBackDISPCLK(
enum source_format_class WritebackPixelFormat,
double PixelClock,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackLumaHTaps,
unsigned int WritebackLumaVTaps,
unsigned int WritebackChromaHTaps,
unsigned int WritebackChromaVTaps,
double WritebackDestinationWidth,
unsigned int HTotal,
unsigned int WritebackChromaLineBufferWidth);
static void CalculateActiveRowBandwidth(
bool VirtualMemoryEnable,
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 UrgentLatency,
unsigned int MaxPageTableLevels,
bool VirtualMemoryEnable,
double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum source_format_class SourcePixelFormat,
unsigned int ImmediateFlipBytes,
double LineTime,
double Tno_bw,
double VRatio,
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 PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib);
static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
void set_prefetch_mode(
struct display_mode_lib *mode_lib,
bool cstate_en,
bool pstate_en,
bool ignore_viewport_pos,
bool immediate_flip_support)
{
unsigned int prefetch_mode;
if (cstate_en && pstate_en)
prefetch_mode = 0;
else if (cstate_en)
prefetch_mode = 1;
else
prefetch_mode = 2;
if (prefetch_mode != mode_lib->vba.PrefetchMode
|| ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning
|| immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) {
DTRACE(
" Prefetch mode has changed from %i to %i. Recalculating.",
prefetch_mode,
mode_lib->vba.PrefetchMode);
mode_lib->vba.PrefetchMode = prefetch_mode;
mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos;
mode_lib->vba.ImmediateFlipSupport = immediate_flip_support;
recalculate(mode_lib);
}
}
unsigned int dml_get_voltage_level(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes)
{
bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
|| num_pipes != mode_lib->vba.cache_num_pipes
|| memcmp(pipes, mode_lib->vba.cache_pipes,
sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
mode_lib->vba.soc = mode_lib->soc;
mode_lib->vba.ip = mode_lib->ip;
memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
mode_lib->vba.cache_num_pipes = num_pipes;
if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
recalculate(mode_lib);
else {
fetch_socbb_params(mode_lib);
fetch_ip_params(mode_lib);
fetch_pipe_params(mode_lib);
}
ModeSupportAndSystemConfigurationFull(mode_lib);
return mode_lib->vba.VoltageLevel;
}
#define dml_get_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \
{ \
recalculate_params(mode_lib, pipes, num_pipes); \
return var; \
}
dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep);
dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark);
dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent
dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs);
dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
dml_get_attr_func(
dram_clock_change_latency,
mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
#define dml_get_pipe_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) \
{\
unsigned int which_plane; \
recalculate_params(mode_lib, pipes, num_pipes); \
which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
return var[which_plane]; \
}
dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
dml_get_pipe_attr_func(
dst_y_per_row_flip,
mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay);
dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay);
dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency);
dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin);
unsigned int get_vstartup_calculated(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes,
unsigned int which_pipe)
{
unsigned int which_plane;
recalculate_params(mode_lib, pipes, num_pipes);
which_plane = mode_lib->vba.pipe_plane[which_pipe];
return mode_lib->vba.VStartup[which_plane];
}
double get_total_immediate_flip_bytes(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes)
{
recalculate_params(mode_lib, pipes, num_pipes);
return mode_lib->vba.TotImmediateFlipBytes;
}
double get_total_immediate_flip_bw(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes)
{
recalculate_params(mode_lib, pipes, num_pipes);
return mode_lib->vba.ImmediateFlipBW;
}
double get_total_prefetch_bw(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes)
{
unsigned int k;
double total_prefetch_bw = 0.0;
recalculate_params(mode_lib, pipes, num_pipes);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
return total_prefetch_bw;
}
static void fetch_socbb_params(struct display_mode_lib *mode_lib)
{
soc_bounding_box_st *soc = &mode_lib->vba.soc;
unsigned int i;
// SOC Bounding Box Parameters
mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
mode_lib->vba.NumberOfChannels = soc->num_chans;
mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency =
soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment!
mode_lib->vba.UrgentLatency = soc->urgent_latency_us;
mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
mode_lib->vba.UrgentOutOfOrderReturnPerChannel =
soc->urgent_out_of_order_return_per_channel_bytes;
mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
mode_lib->vba.Downspreading = soc->downspread_percent;
mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new!
mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new
mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new
mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
// Set the voltage scaling clocks as the defaults. Most of these will
// be set to different values by the test
for (i = 0; i < DC__VOLTAGE_STATES; i++)
if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
break;
mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz;
mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
mode_lib->vba.MaxHSCLRatio = 4;
mode_lib->vba.MaxVSCLRatio = 4;
mode_lib->vba.MaxNumWriteback = 0; /*TODO*/
mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
mode_lib->vba.Cursor64BppSupport = true;
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
}
}
static void fetch_ip_params(struct display_mode_lib *mode_lib)
{
ip_params_st *ip = &mode_lib->vba.ip;
// IP Parameters
mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
mode_lib->vba.MaxNumOTG = ip->max_num_otg;
mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes;
mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs;
mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes;
mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes;
mode_lib->vba.WritebackChromaLineBufferWidth =
ip->writeback_chroma_line_buffer_width_pixels;
mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels;
mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
mode_lib->vba.NumberOfDSC = ip->num_dsc;
mode_lib->vba.ODMCapability = ip->odm_capable;
mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
mode_lib->vba.XFCSupported = ip->xfc_supported;
mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
}
static void fetch_pipe_params(struct display_mode_lib *mode_lib)
{
display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
ip_params_st *ip = &mode_lib->vba.ip;
unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
unsigned int j, k;
bool PlaneVisited[DC__NUM_DPP__MAX];
bool visited[DC__NUM_DPP__MAX];
// Convert Pipes to Planes
for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
visited[k] = false;
mode_lib->vba.NumberOfActivePlanes = 0;
for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
display_pipe_source_params_st *src = &pipes[j].pipe.src;
display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
display_output_params_st *dout = &pipes[j].dout;
display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
if (visited[j])
continue;
visited[j] = true;
mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
(enum scan_direction_class) (src->source_scan);
mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
src->viewport_width;
mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
src->viewport_height;
mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
src->viewport_y_y;
mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
src->viewport_y_c;
mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes])
mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
src->dcc_use_global ?
ip->dcc_supported : src->dcc && ip->dcc_supported;
mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] =
(enum source_format_class) (src->source_format);
mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
(enum dm_swizzle_mode) (src->sw_mode);
mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
dst->odm_combine;
mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
(enum output_format_class) (dout->output_format);
mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
(enum output_encoder_class) (dout->output_type);
mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
dout->dp_lanes;
mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
dout->dsc_slices;
mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
dout->opp_input_bpc == 0 ? 12 : dout->opp_input_bpc;
mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_src_height;
mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_dst_width;
mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_dst_height;
mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
(enum source_format_class) (dout->wb.wb_pixel_format);
mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_htaps_luma;
mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_vtaps_luma;
mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_htaps_chroma;
mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_vtaps_chroma;
mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_hratio;
mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
dout->wb.wb_vratio;
mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
src->dynamic_metadata_enable;
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
src->dynamic_metadata_lines_before_active;
mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
src->dynamic_metadata_xmit_bytes;
mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
&& ip->xfc_supported;
mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
if (ip->is_line_buffer_bpp_fixed)
mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
ip->line_buffer_fixed_bpp;
else {
unsigned int lb_depth;
switch (scl->lb_depth) {
case dm_lb_6:
lb_depth = 18;
break;
case dm_lb_8:
lb_depth = 24;
break;
case dm_lb_10:
lb_depth = 30;
break;
case dm_lb_12:
lb_depth = 36;
break;
case dm_lb_16:
lb_depth = 48;
break;
default:
lb_depth = 36;
}
mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
}
mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
// calculate things a little more accurately
for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
switch (k) {
case 0:
mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
CursorBppEnumToBits(
(enum cursor_bpp) (src->cur0_bpp));
mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
src->cur0_src_width;
if (src->cur0_src_width > 0)
mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
break;
case 1:
mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
CursorBppEnumToBits(
(enum cursor_bpp) (src->cur1_bpp));
mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
src->cur1_src_width;
if (src->cur1_src_width > 0)
mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
break;
default:
dml_print(
"ERROR: Number of cursors specified exceeds supported maximum\n")
;
}
}
OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
if (dst->odm_combine && !src->is_hsplit)
dml_print(
"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
j);
if (src->is_hsplit) {
for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
display_output_params_st *dout_k = &pipes[k].dout;
if (src_k->is_hsplit && !visited[k]
&& src->hsplit_grp == src_k->hsplit_grp) {
mode_lib->vba.pipe_plane[k] =
mode_lib->vba.NumberOfActivePlanes;
mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
== dm_horz)
mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
src_k->viewport_width;
else
mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
src_k->viewport_height;
mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] +=
dout_k->dsc_slices;
visited[k] = true;
}
}
}
mode_lib->vba.NumberOfActivePlanes++;
}
// handle overlays through dml_ml->vba.BlendingAndTiming
// dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
PlaneVisited[j] = false;
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
// doesn't matter, so choose the smaller one
mode_lib->vba.BlendingAndTiming[j] = j;
PlaneVisited[j] = true;
mode_lib->vba.BlendingAndTiming[k] = j;
PlaneVisited[k] = true;
}
}
if (!PlaneVisited[j]) {
mode_lib->vba.BlendingAndTiming[j] = j;
PlaneVisited[j] = true;
}
}
// TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified
// Do we want the dscclk to automatically be halved? Guess not since the value is specified
mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k)
ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
mode_lib->vba.VirtualMemoryEnable = false;
mode_lib->vba.OverridePageTableLevels = 0;
for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable
|| !!pipes[k].pipe.src.vm;
mode_lib->vba.OverridePageTableLevels =
(pipes[k].pipe.src.vm_levels_force_en
&& mode_lib->vba.OverridePageTableLevels
< pipes[k].pipe.src.vm_levels_force) ?
pipes[k].pipe.src.vm_levels_force :
mode_lib->vba.OverridePageTableLevels;
}
if (mode_lib->vba.OverridePageTableLevels)
mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels;
mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable && !!ip->pte_enable;
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;
// TODO: Must be consistent across all pipes
// DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown;
}
static void recalculate(struct display_mode_lib *mode_lib)
{
ModeSupportAndSystemConfiguration(mode_lib);
PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
DisplayPipeConfiguration(mode_lib);
DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
}
// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
// rather than working them out as in recalculate_ms
static void recalculate_params(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes)
{
// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
|| num_pipes != mode_lib->vba.cache_num_pipes
|| memcmp(
pipes,
mode_lib->vba.cache_pipes,
sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
mode_lib->vba.soc = mode_lib->soc;
mode_lib->vba.ip = mode_lib->ip;
memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
mode_lib->vba.cache_num_pipes = num_pipes;
recalculate(mode_lib);
}
}
static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
{
soc_bounding_box_st *soc = &mode_lib->vba.soc;
unsigned int i, k;
unsigned int total_pipes = 0;
mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i)
ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage);
mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
else
mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
fetch_socbb_params(mode_lib);
fetch_ip_params(mode_lib);
fetch_pipe_params(mode_lib);
// Total Available Pipes Support Check
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
total_pipes += mode_lib->vba.DPPPerPlane[k];
ASSERT(total_pipes <= DC__NUM_DPP__MAX);
}
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.UrgentLatency
/ ((mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024
/ ReturnBandwidthToDCN
- mode_lib->vba.DCFCLK
* mode_lib->vba.ReturnBusWidth
/ 4)
+ mode_lib->vba.UrgentLatency));
CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
* mode_lib->vba.UrgentLatency
/ (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency
+ (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.UrgentLatency
/ dml_pow(
(ReturnBandwidthToDCN
* mode_lib->vba.UrgentLatency
+ (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)
{
// valid bpc = source bits per component in the set of {8, 10, 12}
// valid bpp = increments of 1/16 of a bit
// min = 6/7/8 in N420/N422/444, respectively
// max = such that compression is 1:1
//valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
//valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
// fixed value
unsigned int rcModelSize = 8192;
// N422/N420 operate at 2 pixels per clock
unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
Delay, pixels;
if (pixelFormat == dm_n422 || pixelFormat == dm_420)
pixelsPerClock = 2;
// #all other modes operate at 1 pixel per clock
else
pixelsPerClock = 1;
//initial transmit delay as per PPS
initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
//compute ssm delay
if (bpc == 8)
D = 81;
else if (bpc == 10)
D = 89;
else
D = 113;
//divide by pixel per cycle to compute slice width as seen by DSC
w = sliceWidth / pixelsPerClock;
//422 mode has an additional cycle of delay
if (pixelFormat == dm_s422)
s = 1;
else
s = 0;
//main calculation for the dscce
ix = initalXmitDelay + 45;
wx = (w + 2) / 3;
p = 3 * wx - w;
l0 = ix / w;
a = ix + p * l0;
ax = (a + 2) / 3 + D + 6 + 1;
l = (ax + wx - 1) / wx;
if ((ix % w) == 0 && p != 0)
lstall = 1;
else
lstall = 0;
Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
pixels = Delay * 3 * pixelsPerClock;
return pixels;
}
static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
{
unsigned int Delay = 0;
if (pixelFormat == dm_420) {
// sfr
Delay = Delay + 2;
// dsccif
Delay = Delay + 0;
// dscc - input deserializer
Delay = Delay + 3;
// dscc gets pixels every other cycle
Delay = Delay + 2;
// dscc - input cdc fifo
Delay = Delay + 12;
// dscc gets pixels every other cycle
Delay = Delay + 13;
// dscc - cdc uncertainty
Delay = Delay + 2;
// dscc - output cdc fifo
Delay = Delay + 7;
// dscc gets pixels every other cycle
Delay = Delay + 3;
// dscc - cdc uncertainty
Delay = Delay + 2;
// dscc - output serializer
Delay = Delay + 1;
// sft
Delay = Delay + 1;
} else if (pixelFormat == dm_n422) {
// sfr
Delay = Delay + 2;
// dsccif
Delay = Delay + 1;
// dscc - input deserializer
Delay = Delay + 5;
// dscc - input cdc fifo
Delay = Delay + 25;
// dscc - cdc uncertainty
Delay = Delay + 2;
// dscc - output cdc fifo
Delay = Delay + 10;
// dscc - cdc uncertainty
Delay = Delay + 2;
// dscc - output serializer
Delay = Delay + 1;
// sft
Delay = Delay + 1;
} else {
// sfr
Delay = Delay + 2;
// dsccif
Delay = Delay + 0;
// dscc - input deserializer
Delay = Delay + 3;
// dscc - input cdc fifo
Delay = Delay + 12;
// dscc - cdc uncertainty
Delay = Delay + 2;
// dscc - output cdc fifo
Delay = Delay + 7;
// dscc - output serializer
Delay = Delay + 1;
// dscc - cdc uncertainty
Delay = Delay + 2;
// sft
Delay = Delay + 1;
}
return Delay;
}
static bool CalculatePrefetchSchedule(
struct display_mode_lib *mode_lib,
double 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 VirtualMemoryEnable,
bool DynamicMetadataEnable,
unsigned int DynamicMetadataLinesBeforeActiveRequired,
unsigned int DynamicMetadataTransmittedBytes,
bool DCCEnable,
double UrgentLatency,
double UrgentExtraLatency,
double TCalc,
unsigned int PDEAndMetaPTEBytesFrame,
unsigned int MetaRowByte,
unsigned int PixelPTEBytesPerRow,
double PrefetchSourceLinesY,
unsigned int SwathWidthY,
double BytePerPixelDETY,
double VInitPreFillY,
unsigned int MaxNumSwathY,
double PrefetchSourceLinesC,
double BytePerPixelDETC,
double VInitPreFillC,
unsigned int MaxNumSwathC,
unsigned int SwathHeightY,
unsigned int SwathHeightC,
double TWait,
bool XFCEnabled,
double XFCRemoteSurfaceFlipDelay,
bool 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,
unsigned int *VUpdateWidthPix,
unsigned int *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 (VirtualMemoryEnable) {
if (PageTableLevels == 4)
*Tno_bw = UrgentExtraLatency + UrgentLatency;
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 (VirtualMemoryEnable == true) {
Tvm_oto =
dml_max(
*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
dml_max(
UrgentExtraLatency
+ UrgentLatency
* (PageTableLevels
- 1),
LineTime / 4.0));
} else
Tvm_oto = LineTime / 4.0;
if ((VirtualMemoryEnable == true || DCCEnable == true)) {
Tr0_oto = dml_max(
(MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
dml_max(UrgentLatency, 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 (VirtualMemoryEnable) {
TimeForFetchingMetaPTE =
dml_max(
*Tno_bw
+ (double) PDEAndMetaPTEBytesFrame
/ *PrefetchBandwidth,
dml_max(
UrgentExtraLatency
+ UrgentLatency
* (PageTableLevels
- 1),
LineTime / 4));
} else {
if (NumberOfCursors > 0 || XFCEnabled)
TimeForFetchingMetaPTE = LineTime / 4;
else
TimeForFetchingMetaPTE = 0.0;
}
if ((VirtualMemoryEnable == true || DCCEnable == true)) {
TimeForFetchingRowInVBlank =
dml_max(
(MetaRowByte + PixelPTEBytesPerRow)
/ *PrefetchBandwidth,
dml_max(
UrgentLatency,
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 || VirtualMemoryEnable
|| 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 VirtualMemoryEnable,
unsigned int VMMPageSize,
unsigned int PTEBufferSizeInRequests,
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 (VirtualMemoryEnable == true) {
MetaPTEBytesFrame = (dml_ceil(
(double) (DCCMetaSurfaceBytes - VMMPageSize)
/ (8 * VMMPageSize),
1) + 1) * 64;
MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1);
} else {
MetaPTEBytesFrame = 0;
MPDEBytesFrame = 0;
}
} else {
MetaPTEBytesFrame = 0;
MPDEBytesFrame = 0;
*MetaRowByte = 0;
}
if (SurfaceTiling == dm_sw_linear) {
MacroTileSizeBytes = 256;
MacroTileHeight = 1;
} 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 (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 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.MaxPageTableLevels - 2);
} else {
DPDE0BytesFrame = 0;
ExtraDPDEBytesFrame = 0;
}
PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
+ ExtraDPDEBytesFrame;
if (VirtualMemoryEnable == 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) PTEBufferSizeInRequests
* 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 * PTEBufferSizeInRequests) {
*PTEBufferSizeNotExceeded = true;
} else {
*PTEBufferSizeNotExceeded = false;
}
} else {
*PixelPTEBytesPerRow = 0;
*PTEBufferSizeNotExceeded = true;
}
return PDEAndMetaPTEBytesFrame;
}
static void 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;
// dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
//
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.WritebackEnable[k]) {
mode_lib->vba.WritebackDISPCLK =
dml_max(
mode_lib->vba.WritebackDISPCLK,
CalculateWriteBackDISPCLK(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.PixelClock[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.WritebackChromaLineBufferWidth));
}
}
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.HRatio[k] > 1) {
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[NumberOfStates - 1].dispclk_mhz,
mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
mode_lib->vba.DISPCLK_calculated =
mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
} else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
} else {
mode_lib->vba.DISPCLK_calculated =
mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
}
DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.DPPCLK_calculated[k] = 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]);
}
// Urgent Watermark
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.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 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);
// Let's do this calculation again??
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] == true)
MainPlaneDoesODMCombine = true;
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.ODMCombineEnabled[j] == true)
MainPlaneDoesODMCombine = true;
if (MainPlaneDoesODMCombine == true)
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
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 { // dm_420_10
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.UrgentOutOfOrderReturnPerChannel
* 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.VirtualMemoryEnable)
mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
* mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW;
mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency
+ 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.MemoryTripWatermark = mode_lib->vba.UrgentLatency;
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 + 1;
}
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);
// NB P-State/DRAM Clock Change Watermark
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);
// Stutter Efficiency
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.VirtualMemoryEnable) {
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;
// dml_ml->vba.DCFCLK Deep Sleep
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 =
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 = 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 = dml_max(
mode_lib->vba.DCFCLKDeepSleepPerPlane,
mode_lib->vba.PixelClock[k] / 16.0);
mode_lib->vba.DCFClkDeepSleep = dml_max(
mode_lib->vba.DCFClkDeepSleep,
mode_lib->vba.DCFCLKDeepSleepPerPlane);
DTRACE(
" dcfclk_deepsleep_per_plane[%i] = %fMHz",
k,
mode_lib->vba.DCFCLKDeepSleepPerPlane);
}
DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep);
// Stutter Watermark
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);
// Urgent Latency Supported
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]);
}
// Non-Urgent Latency Tolerance
mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
- mode_lib->vba.UrgentWatermark;
// DSCCLK
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);
}
}
// DSC Delay
// TODO
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
double bpp = mode_lib->vba.OutputBpp[k];
unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
if (!mode_lib->vba.ODMCombineEnabled[k]) {
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) // NumberOfPlanes
if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.DSCEnabled[j])
mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
// Prefetch
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
unsigned int PDEAndMetaPTEBytesFrameY;
unsigned int PixelPTEBytesPerRowY;
unsigned int MetaRowByteY;
unsigned int MetaRowByteC;
unsigned int PDEAndMetaPTEBytesFrameC;
unsigned int PixelPTEBytesPerRowC;
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.VirtualMemoryEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequests,
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],
&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.VirtualMemoryEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequests,
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],
&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.VirtualMemoryEnable,
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.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatency,
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.MaxPageTableLevels,
mode_lib->vba.VirtualMemoryEnable,
mode_lib->vba.DynamicMetadataEnable[k],
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
mode_lib->vba.DynamicMetadataTransmittedBytes[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.UrgentLatency,
mode_lib->vba.UrgentExtraLatency,
mode_lib->vba.TCalc,
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.RequiredPrefetchPixDataBW[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.RequiredPrefetchPixDataBW[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.UrgentLatency,
mode_lib->vba.MaxPageTableLevels,
mode_lib->vba.VirtualMemoryEnable,
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.RequiredPrefetchPixDataBW[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));
//Display Pipeline Delivery Time in Prefetch
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];
}
}
}
// Min TTUVBlank
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (mode_lib->vba.PrefetchMode == 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 == 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];
}
// DCC Configuration
mode_lib->vba.ActiveDPPs = 0;
// NB P-State/DRAM Clock Change Support
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.MinActiveDRAMClockChangeMargin > 0) {
mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive;
} else {
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank;
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
mode_lib->vba.DRAMClockChangeSupport =
dm_dram_clock_change_unsupported;
}
}
} else {
mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
}
}
//XFC Parameters:
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.DRAMClockChangeLatency,
mode_lib->vba.UrgentLatency,
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;
}
}
}
static void 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] == true) {
MainPlaneDoesODMCombine = true;
}
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.ODMCombineEnabled[j] == true) {
MainPlaneDoesODMCombine = true;
}
}
if (MainPlaneDoesODMCombine == true) {
SwathWidth = dml_min(
SwathWidth,
mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
} else {
SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
}
SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
RoundedUpMaxSwathSizeBytesY = (dml_ceil(
(double) (SwathWidth - 1),
SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
* MaximumSwathHeightY;
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
+ 256;
}
if (MaximumSwathHeightC > 0) {
SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
/ MaximumSwathHeightC;
RoundedUpMaxSwathSizeBytesC = (dml_ceil(
(double) (SwathWidth / 2.0 - 1),
SwathWidthGranularityC) + SwathWidthGranularityC)
* BytePerPixDETC * MaximumSwathHeightC;
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
RoundedUpMaxSwathSizeBytesC = dml_ceil(
RoundedUpMaxSwathSizeBytesC,
256) + 256;
}
} else
RoundedUpMaxSwathSizeBytesC = 0.0;
if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
<= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
} else {
mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
}
if (mode_lib->vba.SwathHeightC[k] == 0) {
mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 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
* 1024.0 / 2;
mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 / 2;
} else {
mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 * 2 / 3;
mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 / 3;
}
}
}
bool Calculate256BBlockSizes(
enum source_format_class SourcePixelFormat,
enum dm_swizzle_mode SurfaceTiling,
unsigned int BytePerPixelY,
unsigned int BytePerPixelC,
unsigned int *BlockHeight256BytesY,
unsigned int *BlockHeight256BytesC,
unsigned int *BlockWidth256BytesY,
unsigned int *BlockWidth256BytesC)
{
if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
|| SourcePixelFormat == dm_444_16
|| SourcePixelFormat == dm_444_8)) {
if (SurfaceTiling == dm_sw_linear) {
*BlockHeight256BytesY = 1;
} else if (SourcePixelFormat == dm_444_64) {
*BlockHeight256BytesY = 4;
} else if (SourcePixelFormat == dm_444_8) {
*BlockHeight256BytesY = 16;
} else {
*BlockHeight256BytesY = 8;
}
*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
*BlockHeight256BytesC = 0;
*BlockWidth256BytesC = 0;
} else {
if (SurfaceTiling == dm_sw_linear) {
*BlockHeight256BytesY = 1;
*BlockHeight256BytesC = 1;
} else if (SourcePixelFormat == dm_420_8) {
*BlockHeight256BytesY = 16;
*BlockHeight256BytesC = 8;
} else {
*BlockHeight256BytesY = 8;
*BlockHeight256BytesC = 8;
}
*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
}
return true;
}
static double CalculateTWait(
unsigned int PrefetchMode,
double DRAMClockChangeLatency,
double UrgentLatency,
double SREnterPlusExitTime)
{
if (PrefetchMode == 0) {
return dml_max(
DRAMClockChangeLatency + UrgentLatency,
dml_max(SREnterPlusExitTime, UrgentLatency));
} else if (PrefetchMode == 1) {
return dml_max(SREnterPlusExitTime, UrgentLatency);
} else {
return UrgentLatency;
}
}
static double CalculateRemoteSurfaceFlipDelay(
struct display_mode_lib *mode_lib,
double VRatio,
double SwathWidth,
double Bpp,
double LineTime,
double XFCTSlvVupdateOffset,
double XFCTSlvVupdateWidth,
double XFCTSlvVreadyOffset,
double XFCXBUFLatencyTolerance,
double XFCFillBWOverhead,
double XFCSlvChunkSize,
double XFCBusTransportTime,
double TCalc,
double TWait,
double *SrcActiveDrainRate,
double *TInitXFill,
double *TslvChk)
{
double TSlvSetup, AvgfillRate, result;
*SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
*TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
*TslvChk = XFCSlvChunkSize / AvgfillRate;
dml_print(
"DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
*SrcActiveDrainRate);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
return result;
}
static double CalculateWriteBackDISPCLK(
enum source_format_class WritebackPixelFormat,
double PixelClock,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackLumaHTaps,
unsigned int WritebackLumaVTaps,
unsigned int WritebackChromaHTaps,
unsigned int WritebackChromaVTaps,
double WritebackDestinationWidth,
unsigned int HTotal,
unsigned int WritebackChromaLineBufferWidth)
{
double CalculateWriteBackDISPCLK =
1.01 * PixelClock
* dml_max(
dml_ceil(WritebackLumaHTaps / 4.0, 1)
/ WritebackHRatio,
dml_max(
(WritebackLumaVTaps
* dml_ceil(
1.0
/ WritebackVRatio,
1)
* dml_ceil(
WritebackDestinationWidth
/ 4.0,
1)
+ dml_ceil(
WritebackDestinationWidth
/ 4.0,
1))
/ (double) HTotal
+ dml_ceil(
1.0
/ WritebackVRatio,
1)
* (dml_ceil(
WritebackLumaVTaps
/ 4.0,
1)
+ 4.0)
/ (double) HTotal,
dml_ceil(
1.0
/ WritebackVRatio,
1)
* WritebackDestinationWidth
/ (double) HTotal));
if (WritebackPixelFormat != dm_444_32) {
CalculateWriteBackDISPCLK =
dml_max(
CalculateWriteBackDISPCLK,
1.01 * PixelClock
* dml_max(
dml_ceil(
WritebackChromaHTaps
/ 2.0,
1)
/ (2
* WritebackHRatio),
dml_max(
(WritebackChromaVTaps
* dml_ceil(
1
/ (2
* WritebackVRatio),
1)
* dml_ceil(
WritebackDestinationWidth
/ 2.0
/ 2.0,
1)
+ dml_ceil(
WritebackDestinationWidth
/ 2.0
/ WritebackChromaLineBufferWidth,
1))
/ HTotal
+ dml_ceil(
1
/ (2
* WritebackVRatio),
1)
* (dml_ceil(
WritebackChromaVTaps
/ 4.0,
1)
+ 4)
/ HTotal,
dml_ceil(
1.0
/ (2
* WritebackVRatio),
1)
* WritebackDestinationWidth
/ 2.0
/ HTotal)));
}
return CalculateWriteBackDISPCLK;
}
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 VirtualMemoryEnable,
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 (VirtualMemoryEnable != 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 UrgentLatency,
unsigned int MaxPageTableLevels,
bool VirtualMemoryEnable,
double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum source_format_class SourcePixelFormat,
unsigned int ImmediateFlipBytes,
double LineTime,
double Tno_bw,
double VRatio,
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 (VirtualMemoryEnable == true) {
mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
* ImmediateFlipBytes / TotImmediateFlipBytes;
TimeForFetchingMetaPTEImmediateFlip =
dml_max(
Tno_bw
+ PDEAndMetaPTEBytesFrame
/ mode_lib->vba.ImmediateFlipBW,
dml_max(
UrgentExtraLatency
+ UrgentLatency
* (MaxPageTableLevels
- 1),
LineTime / 4.0));
} else {
TimeForFetchingMetaPTEImmediateFlip = 0;
}
*DestinationLinesToRequestVMInImmediateFlip = dml_floor(
4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
1) / 4.0;
if ((VirtualMemoryEnable == true || DCCEnable == true)) {
mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
* ImmediateFlipBytes / TotImmediateFlipBytes;
TimeForFetchingRowInVBlankImmediateFlip = dml_max(
(MetaRowByte + PixelPTEBytesPerRow)
/ mode_lib->vba.ImmediateFlipBW,
dml_max(UrgentLatency, LineTime / 4.0));
} else {
TimeForFetchingRowInVBlankImmediateFlip = 0;
}
*DestinationLinesToRequestRowInImmediateFlip = dml_floor(
4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
1) / 4.0;
if (VirtualMemoryEnable == 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 (VirtualMemoryEnable && !DCCEnable)
min_row_time = dpte_row_height * LineTime / VRatio;
else if (!VirtualMemoryEnable && 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 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
{
unsigned int k;
//Progressive To dml_ml->vba.Interlace Unit Effect
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
if (mode_lib->vba.Interlace[k] == 1
&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
}
}
}
static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
{
switch (ebpp) {
case dm_cur_2bit:
return 2;
case dm_cur_32bit:
return 32;
case dm_cur_64bit:
return 64;
default:
return 0;
}
}
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
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
return BPP_INVALID;
}
}
}
static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
{
int i;
unsigned int j, k;
/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
/*Scale Ratio, taps Support Check*/
mode_lib->vba.ScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ScalerEnabled[k] == false
&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
|| mode_lib->vba.HRatio[k] != 1.0
|| mode_lib->vba.htaps[k] != 1.0
|| mode_lib->vba.VRatio[k] != 1.0
|| mode_lib->vba.vtaps[k] != 1.0)) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
|| (mode_lib->vba.htaps[k] > 1.0
&& (mode_lib->vba.htaps[k] % 2) == 1)
|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
&& (mode_lib->vba.HRatio[k] / 2.0
> mode_lib->vba.HTAPsChroma[k]
|| mode_lib->vba.VRatio[k] / 2.0
> mode_lib->vba.VTAPsChroma[k]))) {
mode_lib->vba.ScaleRatioAndTapsSupport = false;
}
}
/*Source Format, Pixel Format and Scan Support Check*/
mode_lib->vba.SourceFormatPixelAndScanSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
&& mode_lib->vba.SourceScan[k] != dm_horz)
|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10))
|| (((mode_lib->vba.SurfaceTiling[k]
== dm_sw_gfx7_2d_thin_gl
|| mode_lib->vba.SurfaceTiling[k]
== dm_sw_gfx7_2d_thin_lvp)
&& !((mode_lib->vba.SourcePixelFormat[k]
== dm_444_64
|| mode_lib->vba.SourcePixelFormat[k]
== dm_444_32)
&& mode_lib->vba.SourceScan[k]
== dm_horz
&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
== true
&& mode_lib->vba.DCCEnable[k]
== false))
|| (mode_lib->vba.DCCEnable[k] == true
&& (mode_lib->vba.SurfaceTiling[k]
== dm_sw_linear
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_8
|| mode_lib->vba.SourcePixelFormat[k]
== dm_420_10)))) {
mode_lib->vba.SourceFormatPixelAndScanSupport = false;
}
}
/*Bandwidth Support Check*/
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.SourceScan[k] == dm_horz) {
mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
} else {
mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
}
if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
mode_lib->vba.BytePerPixelInDETY[k] = 8.0;
mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
mode_lib->vba.BytePerPixelInDETY[k] = 4.0;
mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
mode_lib->vba.BytePerPixelInDETY[k] = 2.0;
mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
mode_lib->vba.BytePerPixelInDETC[k] = 2.0;
} else {
mode_lib->vba.BytePerPixelInDETY[k] = 4.0 / 3;
mode_lib->vba.BytePerPixelInDETC[k] = 8.0 / 3;
}
}
mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.SwathWidthYSingleDPP[k]
* (dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
* mode_lib->vba.VRatio[k]
+ dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
/ 2.0 * mode_lib->vba.VRatio[k] / 2)
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
* (1 + 1 / 256);
}
if (mode_lib->vba.VirtualMemoryEnable == true
&& mode_lib->vba.SourceScan[k] != dm_horz
&& (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_4kb_d
|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x)) {
mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
* (1 + 1 / 64);
} else if (mode_lib->vba.VirtualMemoryEnable == true
&& mode_lib->vba.SourceScan[k] == dm_horz
&& (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32)
&& (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_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_64kb_r_x)) {
mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
* (1 + 1 / 256);
} else if (mode_lib->vba.VirtualMemoryEnable == true) {
mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
* (1 + 1 / 512);
}
mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond =
mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
+ mode_lib->vba.ReadBandwidth[k] / 1000.0;
}
mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = 0.0;
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) {
mode_lib->vba.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) {
mode_lib->vba.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) {
mode_lib->vba.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 {
mode_lib->vba.WriteBandwidth[k] = 0.0;
}
mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond =
mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond
+ mode_lib->vba.WriteBandwidth[k] / 1000.0;
}
mode_lib->vba.TotalBandwidthConsumedGBytePerSecond =
mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
+ mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond;
mode_lib->vba.DCCEnabledInAnyPlane = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.DCCEnabledInAnyPlane = true;
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.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;
mode_lib->vba.ReturnBWToDCNPerState = dml_min(
mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0)
* mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
/ 100;
mode_lib->vba.ReturnBWPerState[i] = mode_lib->vba.ReturnBWToDCNPerState;
if (mode_lib->vba.DCCEnabledInAnyPlane == true
&& mode_lib->vba.ReturnBWToDCNPerState
> mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.ReturnBusWidth
/ 4.0) {
mode_lib->vba.ReturnBWPerState[i] =
dml_min(
mode_lib->vba.ReturnBWPerState[i],
mode_lib->vba.ReturnBWToDCNPerState * 4.0
* (1.0
- mode_lib->vba.UrgentLatency
/ ((mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0
/ (mode_lib->vba.ReturnBWToDCNPerState
- mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.ReturnBusWidth
/ 4.0)
+ mode_lib->vba.UrgentLatency)));
}
mode_lib->vba.CriticalPoint =
2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.UrgentLatency
/ (mode_lib->vba.ReturnBWToDCNPerState
* mode_lib->vba.UrgentLatency
+ (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0);
if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
&& mode_lib->vba.CriticalPoint < 4.0) {
mode_lib->vba.ReturnBWPerState[i] =
dml_min(
mode_lib->vba.ReturnBWPerState[i],
dml_pow(
4.0
* mode_lib->vba.ReturnBWToDCNPerState
* (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0
* mode_lib->vba.ReturnBusWidth
* mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.UrgentLatency
/ (mode_lib->vba.ReturnBWToDCNPerState
* mode_lib->vba.UrgentLatency
+ (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0),
2));
}
mode_lib->vba.ReturnBWToDCNPerState = dml_min(
mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0);
if (mode_lib->vba.DCCEnabledInAnyPlane == true
&& mode_lib->vba.ReturnBWToDCNPerState
> mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.ReturnBusWidth
/ 4.0) {
mode_lib->vba.ReturnBWPerState[i] =
dml_min(
mode_lib->vba.ReturnBWPerState[i],
mode_lib->vba.ReturnBWToDCNPerState * 4.0
* (1.0
- mode_lib->vba.UrgentLatency
/ ((mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0
/ (mode_lib->vba.ReturnBWToDCNPerState
- mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.ReturnBusWidth
/ 4.0)
+ mode_lib->vba.UrgentLatency)));
}
mode_lib->vba.CriticalPoint =
2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.UrgentLatency
/ (mode_lib->vba.ReturnBWToDCNPerState
* mode_lib->vba.UrgentLatency
+ (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0);
if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
&& mode_lib->vba.CriticalPoint < 4.0) {
mode_lib->vba.ReturnBWPerState[i] =
dml_min(
mode_lib->vba.ReturnBWPerState[i],
dml_pow(
4.0
* mode_lib->vba.ReturnBWToDCNPerState
* (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0
* mode_lib->vba.ReturnBusWidth
* mode_lib->vba.DCFCLKPerState[i]
* mode_lib->vba.UrgentLatency
/ (mode_lib->vba.ReturnBWToDCNPerState
* mode_lib->vba.UrgentLatency
+ (mode_lib->vba.ROBBufferSizeInKByte
- mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0),
2));
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
if ((mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond * 1000.0
<= mode_lib->vba.ReturnBWPerState[i])
&& (mode_lib->vba.TotalBandwidthConsumedGBytePerSecond * 1000.0
<= mode_lib->vba.FabricAndDRAMBandwidthPerState[i]
* 1000.0
* mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
/ 100.0)) {
mode_lib->vba.BandwidthSupport[i] = true;
} else {
mode_lib->vba.BandwidthSupport[i] = false;
}
}
/*Writeback Latency support check*/
mode_lib->vba.WritebackLatencySupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
if (mode_lib->vba.WriteBandwidth[k]
> (mode_lib->vba.WritebackInterfaceLumaBufferSize
+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ mode_lib->vba.WritebackLatency) {
mode_lib->vba.WritebackLatencySupport = false;
}
} else {
if (mode_lib->vba.WriteBandwidth[k]
> 1.5
* dml_min(
mode_lib->vba.WritebackInterfaceLumaBufferSize,
2.0
* mode_lib->vba.WritebackInterfaceChromaBufferSize)
/ mode_lib->vba.WritebackLatency) {
mode_lib->vba.WritebackLatencySupport = false;
}
}
}
}
/*Re-ordering Buffer Support Check*/
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
(mode_lib->vba.RoundTripPingLatencyCycles + 32.0)
/ mode_lib->vba.DCFCLKPerState[i]
+ mode_lib->vba.UrgentOutOfOrderReturnPerChannel
* mode_lib->vba.NumberOfChannels
/ mode_lib->vba.ReturnBWPerState[i];
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte)
* 1024.0 / mode_lib->vba.ReturnBWPerState[i]
> mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
mode_lib->vba.ROBSupport[i] = true;
} else {
mode_lib->vba.ROBSupport[i] = false;
}
}
/*Writeback Mode Support Check*/
mode_lib->vba.TotalNumberOfActiveWriteback = 0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.TotalNumberOfActiveWriteback =
mode_lib->vba.TotalNumberOfActiveWriteback + 1;
}
}
mode_lib->vba.WritebackModeSupport = true;
if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
mode_lib->vba.WritebackModeSupport = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true
&& mode_lib->vba.Writeback10bpc420Supported != true
&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
mode_lib->vba.WritebackModeSupport = false;
}
}
/*Writeback Scale Ratio and Taps Support Check*/
mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
&& (mode_lib->vba.WritebackHRatio[k] != 1.0
|| mode_lib->vba.WritebackVRatio[k] != 1.0)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
|| mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackMaxVSCLRatio
|| mode_lib->vba.WritebackHRatio[k]
< mode_lib->vba.WritebackMinHSCLRatio
|| mode_lib->vba.WritebackVRatio[k]
< mode_lib->vba.WritebackMinVSCLRatio
|| mode_lib->vba.WritebackLumaHTaps[k]
> mode_lib->vba.WritebackMaxHSCLTaps
|| mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackMaxVSCLTaps
|| mode_lib->vba.WritebackHRatio[k]
> mode_lib->vba.WritebackLumaHTaps[k]
|| mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackLumaVTaps[k]
|| (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
&& ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
== 1))
|| (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
&& (mode_lib->vba.WritebackChromaHTaps[k]
> mode_lib->vba.WritebackMaxHSCLTaps
|| mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackMaxVSCLTaps
|| 2.0
* mode_lib->vba.WritebackHRatio[k]
> mode_lib->vba.WritebackChromaHTaps[k]
|| 2.0
* mode_lib->vba.WritebackVRatio[k]
> mode_lib->vba.WritebackChromaVTaps[k]
|| (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
&& ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
mode_lib->vba.WritebackLumaVExtra =
dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
} else {
mode_lib->vba.WritebackLumaVExtra = -1;
}
if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
&& mode_lib->vba.WritebackLumaVTaps[k]
> (mode_lib->vba.WritebackLineBufferLumaBufferSize
+ mode_lib->vba.WritebackLineBufferChromaBufferSize)
/ 3.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackLumaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
&& mode_lib->vba.WritebackLumaVTaps[k]
> mode_lib->vba.WritebackLineBufferLumaBufferSize
/ 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
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackChromaVExtra)
|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
&& mode_lib->vba.WritebackChromaVTaps[k]
> mode_lib->vba.WritebackLineBufferChromaBufferSize
* 8.0 / 10.0
/ mode_lib->vba.WritebackDestinationWidth[k]
- mode_lib->vba.WritebackChromaVExtra)) {
mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
}
}
}
/*Maximum DISPCLK/DPPCLK Support check*/
mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.WritebackRequiredDISPCLK =
dml_max(
mode_lib->vba.WritebackRequiredDISPCLK,
CalculateWriteBackDISPCLK(
mode_lib->vba.WritebackPixelFormat[k],
mode_lib->vba.PixelClock[k],
mode_lib->vba.WritebackHRatio[k],
mode_lib->vba.WritebackVRatio[k],
mode_lib->vba.WritebackLumaHTaps[k],
mode_lib->vba.WritebackLumaVTaps[k],
mode_lib->vba.WritebackChromaHTaps[k],
mode_lib->vba.WritebackChromaVTaps[k],
mode_lib->vba.WritebackDestinationWidth[k],
mode_lib->vba.HTotal[k],
mode_lib->vba.WritebackChromaLineBufferWidth));
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.HRatio[k] > 1.0) {
mode_lib->vba.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 {
mode_lib->vba.PSCL_FACTOR[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
mode_lib->vba.PSCL_FACTOR_CHROMA[k] = 0.0;
mode_lib->vba.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]
/ mode_lib->vba.PSCL_FACTOR[k],
1.0);
if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
&& mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
< 2.0 * mode_lib->vba.PixelClock[k]) {
mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
* mode_lib->vba.PixelClock[k];
}
} else {
if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
mode_lib->vba.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 {
mode_lib->vba.PSCL_FACTOR_CHROMA[k] = dml_min(
mode_lib->vba.MaxDCHUBToPSCLThroughput,
mode_lib->vba.MaxPSCLToLBThroughput);
}
mode_lib->vba.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]
/ mode_lib->vba.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
/ mode_lib->vba.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)
&& mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
< 2.0 * mode_lib->vba.PixelClock[k]) {
mode_lib->vba.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(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
&mode_lib->vba.Read256BlockHeightY[k],
&mode_lib->vba.Read256BlockHeightC[k],
&mode_lib->vba.Read256BlockWidthY[k],
&mode_lib->vba.Read256BlockWidthC[k]);
if (mode_lib->vba.SourceScan[k] == dm_horz) {
mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockHeightY[k];
mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockHeightC[k];
} else {
mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockWidthY[k];
mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.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)) {
mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
} else {
mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
/ 2.0;
}
mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
} else {
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
&& mode_lib->vba.SourceScan[k] == dm_horz) {
mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
/ 2.0;
mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
&& mode_lib->vba.SourceScan[k] == dm_horz) {
mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]
/ 2.0;
mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
} else {
mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
}
}
if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
} else {
mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
}
mode_lib->vba.MaximumSwathWidthInDETBuffer =
dml_min(
mode_lib->vba.MaximumSwathWidthSupport,
mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
/ (mode_lib->vba.BytePerPixelInDETY[k]
* mode_lib->vba.MinSwathHeightY[k]
+ mode_lib->vba.BytePerPixelInDETC[k]
/ 2.0
* mode_lib->vba.MinSwathHeightC[k]));
if (mode_lib->vba.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)));
}
mode_lib->vba.MaximumSwathWidth[k] = dml_min(
mode_lib->vba.MaximumSwathWidthInDETBuffer,
mode_lib->vba.MaximumSwathWidthInLineBuffer);
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
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);
mode_lib->vba.RequiredDISPCLK[i] = 0.0;
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = 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.ODMCapability == true
&& mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
/ 2.0;
} else {
mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
}
if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
<= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
&& mode_lib->vba.SwathWidthYSingleDPP[k]
<= mode_lib->vba.MaximumSwathWidth[k]
&& mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
mode_lib->vba.NoOfDPP[i][k] = 1;
mode_lib->vba.RequiredDPPCLK[i][k] =
mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0);
} else {
mode_lib->vba.NoOfDPP[i][k] = 2;
mode_lib->vba.RequiredDPPCLK[i][k] =
mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
/ 2.0;
}
mode_lib->vba.RequiredDISPCLK[i] = dml_max(
mode_lib->vba.RequiredDISPCLK[i],
mode_lib->vba.PlaneRequiredDISPCLK);
if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] / mode_lib->vba.NoOfDPP[i][k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
|| (mode_lib->vba.PlaneRequiredDISPCLK
> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
}
}
mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.TotalNumberOfActiveDPP[i] =
mode_lib->vba.TotalNumberOfActiveDPP[i]
+ mode_lib->vba.NoOfDPP[i][k];
}
if ((mode_lib->vba.MaxDispclk[i] == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
&& mode_lib->vba.MaxDppclk[i]
== mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])
&& (mode_lib->vba.TotalNumberOfActiveDPP[i]
> mode_lib->vba.MaxNumDPP
|| mode_lib->vba.DISPCLK_DPPCLK_Support[i] == false)) {
mode_lib->vba.RequiredDISPCLK[i] = 0.0;
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = 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);
if (mode_lib->vba.ODMCapability == true
&& mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
/ 2.0;
} else {
mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
mode_lib->vba.PlaneRequiredDISPCLK =
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
}
if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
<= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
&& mode_lib->vba.SwathWidthYSingleDPP[k]
<= mode_lib->vba.MaximumSwathWidth[k]
&& mode_lib->vba.ODMCombineEnablePerState[i][k]
== false) {
mode_lib->vba.NoOfDPP[i][k] = 1;
mode_lib->vba.RequiredDPPCLK[i][k] =
mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0);
} else {
mode_lib->vba.NoOfDPP[i][k] = 2;
mode_lib->vba.RequiredDPPCLK[i][k] =
mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
/ 2.0;
}
mode_lib->vba.RequiredDISPCLK[i] = dml_max(
mode_lib->vba.RequiredDISPCLK[i],
mode_lib->vba.PlaneRequiredDISPCLK);
if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
/ mode_lib->vba.NoOfDPP[i][k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
|| (mode_lib->vba.PlaneRequiredDISPCLK
> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
}
}
mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.TotalNumberOfActiveDPP[i] =
mode_lib->vba.TotalNumberOfActiveDPP[i]
+ mode_lib->vba.NoOfDPP[i][k];
}
}
if (mode_lib->vba.TotalNumberOfActiveDPP[i] > mode_lib->vba.MaxNumDPP) {
mode_lib->vba.RequiredDISPCLK[i] = 0.0;
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
if (mode_lib->vba.SwathWidthYSingleDPP[k]
<= mode_lib->vba.MaximumSwathWidth[k]) {
mode_lib->vba.NoOfDPP[i][k] = 1;
mode_lib->vba.RequiredDPPCLK[i][k] =
mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0);
} else {
mode_lib->vba.NoOfDPP[i][k] = 2;
mode_lib->vba.RequiredDPPCLK[i][k] =
mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
/ 2.0;
}
if (!(mode_lib->vba.MaxDispclk[i]
== mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
&& mode_lib->vba.MaxDppclk[i]
== mode_lib->vba.MaxDppclk[DC__VOLTAGE_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);
}
mode_lib->vba.RequiredDISPCLK[i] = dml_max(
mode_lib->vba.RequiredDISPCLK[i],
mode_lib->vba.PlaneRequiredDISPCLK);
if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
/ mode_lib->vba.NoOfDPP[i][k]
* (1.0
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
|| (mode_lib->vba.PlaneRequiredDISPCLK
> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
}
}
mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.TotalNumberOfActiveDPP[i] =
mode_lib->vba.TotalNumberOfActiveDPP[i]
+ mode_lib->vba.NoOfDPP[i][k];
}
}
mode_lib->vba.RequiredDISPCLK[i] = dml_max(
mode_lib->vba.RequiredDISPCLK[i],
mode_lib->vba.WritebackRequiredDISPCLK);
if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
< mode_lib->vba.WritebackRequiredDISPCLK) {
mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
}
}
/*Viewport Size Check*/
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.ViewportSizeSupport[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
if (dml_min(mode_lib->vba.SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
> mode_lib->vba.MaximumSwathWidth[k]) {
mode_lib->vba.ViewportSizeSupport[i] = false;
}
} else {
if (mode_lib->vba.SwathWidthYSingleDPP[k] / 2.0
> mode_lib->vba.MaximumSwathWidth[k]) {
mode_lib->vba.ViewportSizeSupport[i] = false;
}
}
}
}
/*Total Available Pipes Support Check*/
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
if (mode_lib->vba.TotalNumberOfActiveDPP[i] <= mode_lib->vba.MaxNumDPP) {
mode_lib->vba.TotalAvailablePipesSupport[i] = true;
} else {
mode_lib->vba.TotalAvailablePipesSupport[i] = false;
}
}
/*Total Available OTG Support Check*/
mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+ 1.0;
}
}
if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
mode_lib->vba.NumberOfOTGSupport = true;
} else {
mode_lib->vba.NumberOfOTGSupport = false;
}
/*Display IO and DSC Support Check*/
mode_lib->vba.NonsupportedDSCInputBPC = false;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
mode_lib->vba.NonsupportedDSCInputBPC = true;
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.RequiresDSC[i][k] = 0;
mode_lib->vba.RequiresFEC[i][k] = 0;
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.Output[k] == dm_hdmi) {
mode_lib->vba.RequiresDSC[i][k] = 0;
mode_lib->vba.RequiresFEC[i][k] = 0;
mode_lib->vba.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) {
mode_lib->vba.RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
mode_lib->vba.RequiresFEC[i][k] =
true;
} else {
mode_lib->vba.RequiresFEC[i][k] =
false;
}
mode_lib->vba.Outbpp =
mode_lib->vba.OutbppDSC;
} else {
mode_lib->vba.RequiresDSC[i][k] = false;
mode_lib->vba.RequiresFEC[i][k] = false;
}
mode_lib->vba.OutputBppPerState[i][k] =
mode_lib->vba.Outbpp;
}
if (mode_lib->vba.Outbpp == BPP_INVALID) {
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) {
mode_lib->vba.RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
mode_lib->vba.RequiresFEC[i][k] =
true;
} else {
mode_lib->vba.RequiresFEC[i][k] =
false;
}
mode_lib->vba.Outbpp =
mode_lib->vba.OutbppDSC;
} else {
mode_lib->vba.RequiresDSC[i][k] = false;
mode_lib->vba.RequiresFEC[i][k] = false;
}
mode_lib->vba.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) {
mode_lib->vba.RequiresDSC[i][k] = true;
if (mode_lib->vba.Output[k] == dm_dp) {
mode_lib->vba.RequiresFEC[i][k] =
true;
} else {
mode_lib->vba.RequiresFEC[i][k] =
false;
}
mode_lib->vba.Outbpp =
mode_lib->vba.OutbppDSC;
} else {
mode_lib->vba.RequiresDSC[i][k] = false;
mode_lib->vba.RequiresFEC[i][k] = false;
}
mode_lib->vba.OutputBppPerState[i][k] =
mode_lib->vba.Outbpp;
}
}
} else {
mode_lib->vba.OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
}
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.DIOSupport[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.OutputBppPerState[i][k] == BPP_INVALID
|| (mode_lib->vba.OutputFormat[k] == dm_420
&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP
== true)) {
mode_lib->vba.DIOSupport[i] = false;
}
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.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 (mode_lib->vba.RequiresDSC[i][k] == true) {
if (mode_lib->vba.ODMCombineEnablePerState[i][k]
== true) {
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0
/ mode_lib->vba.DSCFormatFactor
> (1.0
- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
/ 100.0)
* mode_lib->vba.MaxDSCCLK[i]) {
mode_lib->vba.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]) {
mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
true;
}
}
}
}
}
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.NotEnoughDSCUnits[i] = false;
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.RequiresDSC[i][k] == true) {
if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
} else {
mode_lib->vba.TotalDSCUnitsRequired =
mode_lib->vba.TotalDSCUnitsRequired + 1.0;
}
}
}
if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
mode_lib->vba.NotEnoughDSCUnits[i] = true;
}
}
/*DSC Delay per state*/
for (i = 0; i <= DC__VOLTAGE_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 (mode_lib->vba.RequiresDSC[i][k] == 0
|| mode_lib->vba.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 (mode_lib->vba.OutputBppPerState[i][k] == BPP_BLENDED_PIPE
|| mode_lib->vba.OutputBppPerState[i][k] == BPP_INVALID) {
mode_lib->vba.bpp = 0.0;
} else {
mode_lib->vba.bpp = mode_lib->vba.OutputBppPerState[i][k];
}
if (mode_lib->vba.RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
if (mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
mode_lib->vba.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 {
mode_lib->vba.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]));
}
mode_lib->vba.DSCDelayPerState[i][k] =
mode_lib->vba.DSCDelayPerState[i][k]
* mode_lib->vba.PixelClock[k]
/ mode_lib->vba.PixelClockBackEnd[k];
} else {
mode_lib->vba.DSCDelayPerState[i][k] = 0.0;
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
if (mode_lib->vba.BlendingAndTiming[k] == j
&& mode_lib->vba.RequiresDSC[i][j] == true) {
mode_lib->vba.DSCDelayPerState[i][k] =
mode_lib->vba.DSCDelayPerState[i][j];
}
}
}
}
/*Urgent Latency Support Check*/
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
mode_lib->vba.SwathWidthYPerState[i][k] =
dml_min(
mode_lib->vba.SwathWidthYSingleDPP[k],
dml_round(
mode_lib->vba.HActive[k]
/ 2.0
* mode_lib->vba.HRatio[k]));
} else {
mode_lib->vba.SwathWidthYPerState[i][k] =
mode_lib->vba.SwathWidthYSingleDPP[k]
/ mode_lib->vba.NoOfDPP[i][k];
}
mode_lib->vba.SwathWidthGranularityY = 256.0
/ dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
/ mode_lib->vba.MaxSwathHeightY[k];
mode_lib->vba.RoundedUpMaxSwathSizeBytesY = (dml_ceil(
mode_lib->vba.SwathWidthYPerState[i][k] - 1.0,
mode_lib->vba.SwathWidthGranularityY)
+ mode_lib->vba.SwathWidthGranularityY)
* mode_lib->vba.BytePerPixelInDETY[k]
* mode_lib->vba.MaxSwathHeightY[k];
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil(
mode_lib->vba.RoundedUpMaxSwathSizeBytesY,
256.0) + 256;
}
if (mode_lib->vba.MaxSwathHeightC[k] > 0.0) {
mode_lib->vba.SwathWidthGranularityC = 256.0
/ dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
/ mode_lib->vba.MaxSwathHeightC[k];
mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil(
mode_lib->vba.SwathWidthYPerState[i][k] / 2.0 - 1.0,
mode_lib->vba.SwathWidthGranularityC)
+ mode_lib->vba.SwathWidthGranularityC)
* mode_lib->vba.BytePerPixelInDETC[k]
* mode_lib->vba.MaxSwathHeightC[k];
if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil(
mode_lib->vba.RoundedUpMaxSwathSizeBytesC,
256.0) + 256;
}
} else {
mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0;
}
if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesC
<= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
mode_lib->vba.SwathHeightYPerState[i][k] =
mode_lib->vba.MaxSwathHeightY[k];
mode_lib->vba.SwathHeightCPerState[i][k] =
mode_lib->vba.MaxSwathHeightC[k];
} else {
mode_lib->vba.SwathHeightYPerState[i][k] =
mode_lib->vba.MinSwathHeightY[k];
mode_lib->vba.SwathHeightCPerState[i][k] =
mode_lib->vba.MinSwathHeightC[k];
}
if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 / mode_lib->vba.BytePerPixelInDETY[k]
/ mode_lib->vba.SwathWidthYPerState[i][k];
mode_lib->vba.LinesInDETChroma = 0.0;
} else if (mode_lib->vba.SwathHeightYPerState[i][k]
<= mode_lib->vba.SwathHeightCPerState[i][k]) {
mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETY[k]
/ mode_lib->vba.SwathWidthYPerState[i][k];
mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETC[k]
/ (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
} else {
mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 * 2.0 / 3.0
/ mode_lib->vba.BytePerPixelInDETY[k]
/ mode_lib->vba.SwathWidthYPerState[i][k];
mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
* 1024.0 / 3.0 / mode_lib->vba.BytePerPixelInDETY[k]
/ (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
}
mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma =
dml_min(
mode_lib->vba.MaxLineBufferLines,
dml_floor(
mode_lib->vba.LineBufferSize
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.SwathWidthYPerState[i][k]
/ dml_max(
mode_lib->vba.HRatio[k],
1.0)),
1.0))
- (mode_lib->vba.vtaps[k] - 1.0);
mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma =
dml_min(
mode_lib->vba.MaxLineBufferLines,
dml_floor(
mode_lib->vba.LineBufferSize
/ mode_lib->vba.LBBitPerPixel[k]
/ (mode_lib->vba.SwathWidthYPerState[i][k]
/ 2.0
/ dml_max(
mode_lib->vba.HRatio[k]
/ 2.0,
1.0)),
1.0))
- (mode_lib->vba.VTAPsChroma[k] - 1.0);
mode_lib->vba.EffectiveDETLBLinesLuma =
dml_floor(
mode_lib->vba.LinesInDETLuma
+ dml_min(
mode_lib->vba.LinesInDETLuma
* mode_lib->vba.RequiredDISPCLK[i]
* mode_lib->vba.BytePerPixelInDETY[k]
* mode_lib->vba.PSCL_FACTOR[k]
/ mode_lib->vba.ReturnBWPerState[i],
mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
mode_lib->vba.SwathHeightYPerState[i][k]);
mode_lib->vba.EffectiveDETLBLinesChroma =
dml_floor(
mode_lib->vba.LinesInDETChroma
+ dml_min(
mode_lib->vba.LinesInDETChroma
* mode_lib->vba.RequiredDISPCLK[i]
* mode_lib->vba.BytePerPixelInDETC[k]
* mode_lib->vba.PSCL_FACTOR_CHROMA[k]
/ mode_lib->vba.ReturnBWPerState[i],
mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
mode_lib->vba.SwathHeightCPerState[i][k]);
if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
mode_lib->vba.EffectiveDETLBLinesLuma
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k]
- mode_lib->vba.EffectiveDETLBLinesLuma
* mode_lib->vba.SwathWidthYPerState[i][k]
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ (mode_lib->vba.ReturnBWPerState[i]
/ mode_lib->vba.NoOfDPP[i][k]);
} else {
mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
dml_min(
mode_lib->vba.EffectiveDETLBLinesLuma
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k]
- mode_lib->vba.EffectiveDETLBLinesLuma
* mode_lib->vba.SwathWidthYPerState[i][k]
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ (mode_lib->vba.ReturnBWPerState[i]
/ mode_lib->vba.NoOfDPP[i][k]),
mode_lib->vba.EffectiveDETLBLinesChroma
* (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k])
/ (mode_lib->vba.VRatio[k]
/ 2.0)
- mode_lib->vba.EffectiveDETLBLinesChroma
* mode_lib->vba.SwathWidthYPerState[i][k]
/ 2.0
* dml_ceil(
mode_lib->vba.BytePerPixelInDETC[k],
2.0)
/ (mode_lib->vba.ReturnBWPerState[i]
/ mode_lib->vba.NoOfDPP[i][k]));
}
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.UrgentLatencySupport[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.UrgentLatencySupportUsPerState[i][k]
< mode_lib->vba.UrgentLatency / 1.0) {
mode_lib->vba.UrgentLatencySupport[i] = false;
}
}
}
/*Prefetch Check*/
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = 0.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.TotalNumberOfDCCActiveDPP[i] =
mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
+ mode_lib->vba.NoOfDPP[i][k];
}
}
}
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.ProjectedDCFCLKDeepSleep = 8.0;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
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 =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
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][k]);
} else {
mode_lib->vba.ProjectedDCFCLKDeepSleep =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ 64.0
* mode_lib->vba.PSCL_FACTOR[k]
* mode_lib->vba.RequiredDPPCLK[i][k]);
}
} else {
if (mode_lib->vba.VRatio[k] <= 1.0) {
mode_lib->vba.ProjectedDCFCLKDeepSleep =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
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][k]);
} else {
mode_lib->vba.ProjectedDCFCLKDeepSleep =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
1.1
* dml_ceil(
mode_lib->vba.BytePerPixelInDETY[k],
1.0)
/ 32.0
* mode_lib->vba.PSCL_FACTOR[k]
* mode_lib->vba.RequiredDPPCLK[i][k]);
}
if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
mode_lib->vba.ProjectedDCFCLKDeepSleep =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
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][k]);
} else {
mode_lib->vba.ProjectedDCFCLKDeepSleep =
dml_max(
mode_lib->vba.ProjectedDCFCLKDeepSleep,
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][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][k],
mode_lib->vba.VirtualMemoryEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequests,
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][k],
&mode_lib->vba.dpte_row_height[k],
&mode_lib->vba.meta_row_height[k]);
mode_lib->vba.PrefetchLinesY[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][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][k] / 2.0,
mode_lib->vba.VirtualMemoryEnable,
mode_lib->vba.VMMPageSize,
mode_lib->vba.PTEBufferSizeInRequests,
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][k],
&mode_lib->vba.dpte_row_height_chroma[k],
&mode_lib->vba.meta_row_height_chroma[k]);
mode_lib->vba.PrefetchLinesC[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][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;
mode_lib->vba.PrefetchLinesC[k] = 0.0;
mode_lib->vba.PTEBufferSizeNotExceededC[i][k] = true;
}
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] =
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
mode_lib->vba.MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY
+ mode_lib->vba.MetaRowBytesC;
mode_lib->vba.DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY
+ mode_lib->vba.DPTEBytesPerRowC;
}
mode_lib->vba.ExtraLatency =
mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
+ (mode_lib->vba.TotalNumberOfActiveDPP[i]
* mode_lib->vba.PixelChunkSizeInKByte
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
* mode_lib->vba.MetaChunkSize)
* 1024.0
/ mode_lib->vba.ReturnBWPerState[i];
if (mode_lib->vba.VirtualMemoryEnable == true) {
mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
+ mode_lib->vba.TotalNumberOfActiveDPP[i]
* mode_lib->vba.PTEChunkSize * 1024.0
/ mode_lib->vba.ReturnBWPerState[i];
}
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
if (mode_lib->vba.WritebackEnable[k] == true) {
mode_lib->vba.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])
/ mode_lib->vba.RequiredDISPCLK[i];
} else {
mode_lib->vba.WritebackDelay[i][k] = 0.0;
}
for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
if (mode_lib->vba.BlendingAndTiming[j] == k
&& mode_lib->vba.WritebackEnable[j]
== true) {
mode_lib->vba.WritebackDelay[i][k] =
dml_max(
mode_lib->vba.WritebackDelay[i][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.RequiredDISPCLK[i]);
}
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
if (mode_lib->vba.BlendingAndTiming[k] == j) {
mode_lib->vba.WritebackDelay[i][k] =
mode_lib->vba.WritebackDelay[i][j];
}
}
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.MaximumVStartup[k] =
mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
- dml_max(
1.0,
dml_ceil(
mode_lib->vba.WritebackDelay[i][k]
/ (mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]),
1.0));
}
mode_lib->vba.TWait = CalculateTWait(
mode_lib->vba.PrefetchMode,
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],
mode_lib->vba.SwathWidthYPerState[i][k],
dml_ceil(
mode_lib->vba.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][k] =
CalculatePrefetchSchedule(
mode_lib,
mode_lib->vba.RequiredDPPCLK[i][k],
mode_lib->vba.RequiredDISPCLK[i],
mode_lib->vba.PixelClock[k],
mode_lib->vba.ProjectedDCFCLKDeepSleep,
mode_lib->vba.DSCDelayPerState[i][k],
mode_lib->vba.NoOfDPP[i][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][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[k],
mode_lib->vba.MaxPageTableLevels,
mode_lib->vba.VirtualMemoryEnable,
mode_lib->vba.DynamicMetadataEnable[k],
mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
mode_lib->vba.DynamicMetadataTransmittedBytes[k],
mode_lib->vba.DCCEnable[k],
mode_lib->vba.UrgentLatency,
mode_lib->vba.ExtraLatency,
mode_lib->vba.TimeCalc,
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
mode_lib->vba.MetaRowBytes[k],
mode_lib->vba.DPTEBytesPerRow[k],
mode_lib->vba.PrefetchLinesY[k],
mode_lib->vba.SwathWidthYPerState[i][k],
mode_lib->vba.BytePerPixelInDETY[k],
mode_lib->vba.PrefillY[k],
mode_lib->vba.MaxNumSwY[k],
mode_lib->vba.PrefetchLinesC[k],
mode_lib->vba.BytePerPixelInDETC[k],
mode_lib->vba.PrefillC[k],
mode_lib->vba.MaxNumSwC[k],
mode_lib->vba.SwathHeightYPerState[i][k],
mode_lib->vba.SwathHeightCPerState[i][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][k],
&mode_lib->vba.VRatioPreC[i][k],
&mode_lib->vba.RequiredPrefetchPixelDataBW[i][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]);
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k]
* mode_lib->vba.CursorWidth[k][0]
* mode_lib->vba.CursorBPP[k][0] / 8.0
/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
* mode_lib->vba.VRatio[k];
}
mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
mode_lib->vba.prefetch_vm_bw_valid = true;
mode_lib->vba.prefetch_row_bw_valid = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] == 0.0) {
mode_lib->vba.prefetch_vm_bw[k] = 0.0;
} else if (mode_lib->vba.LinesForMetaPTE[k] > 0.0) {
mode_lib->vba.prefetch_vm_bw[k] =
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
/ (mode_lib->vba.LinesForMetaPTE[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
} else {
mode_lib->vba.prefetch_vm_bw[k] = 0.0;
mode_lib->vba.prefetch_vm_bw_valid = false;
}
if (mode_lib->vba.MetaRowBytes[k] + mode_lib->vba.DPTEBytesPerRow[k]
== 0.0) {
mode_lib->vba.prefetch_row_bw[k] = 0.0;
} else if (mode_lib->vba.LinesForMetaAndDPTERow[k] > 0.0) {
mode_lib->vba.prefetch_row_bw[k] = (mode_lib->vba.MetaRowBytes[k]
+ mode_lib->vba.DPTEBytesPerRow[k])
/ (mode_lib->vba.LinesForMetaAndDPTERow[k]
* mode_lib->vba.HTotal[k]
/ mode_lib->vba.PixelClock[k]);
} else {
mode_lib->vba.prefetch_row_bw[k] = 0.0;
mode_lib->vba.prefetch_row_bw_valid = false;
}
mode_lib->vba.MaximumReadBandwidthWithPrefetch =
mode_lib->vba.MaximumReadBandwidthWithPrefetch
+ mode_lib->vba.cursor_bw[k]
+ dml_max4(
mode_lib->vba.prefetch_vm_bw[k],
mode_lib->vba.prefetch_row_bw[k],
mode_lib->vba.ReadBandwidth[k],
mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]);
}
mode_lib->vba.PrefetchSupported[i] = true;
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch
> mode_lib->vba.ReturnBWPerState[i]
|| mode_lib->vba.prefetch_vm_bw_valid == false
|| mode_lib->vba.prefetch_row_bw_valid == false) {
mode_lib->vba.PrefetchSupported[i] = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.LineTimesForPrefetch[k] < 2.0
|| mode_lib->vba.LinesForMetaPTE[k] >= 8.0
|| mode_lib->vba.LinesForMetaAndDPTERow[k] >= 16.0
|| mode_lib->vba.IsErrorResult[i][k] == true) {
mode_lib->vba.PrefetchSupported[i] = false;
}
}
mode_lib->vba.VRatioInPrefetchSupported[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.VRatioPreY[i][k] > 4.0
|| mode_lib->vba.VRatioPreC[i][k] > 4.0
|| mode_lib->vba.IsErrorResult[i][k] == true) {
mode_lib->vba.VRatioInPrefetchSupported[i] = false;
}
}
if (mode_lib->vba.PrefetchSupported[i] == true
&& mode_lib->vba.VRatioInPrefetchSupported[i] == true) {
mode_lib->vba.BandwidthAvailableForImmediateFlip =
mode_lib->vba.ReturnBWPerState[i];
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.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[k]
+ mode_lib->vba.MetaRowBytes[k]
+ mode_lib->vba.DPTEBytesPerRow[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.UrgentLatency,
mode_lib->vba.MaxPageTableLevels,
mode_lib->vba.VirtualMemoryEnable,
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[k],
mode_lib->vba.MetaRowBytes[k],
mode_lib->vba.DPTEBytesPerRow[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.RequiredPrefetchPixelDataBW[i][k]));
}
mode_lib->vba.ImmediateFlipSupportedForState[i] = true;
if (mode_lib->vba.total_dcn_read_bw_with_flip
> mode_lib->vba.ReturnBWPerState[i]) {
mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
}
}
} else {
mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
}
}
/*PTE Buffer Size Check*/
for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
mode_lib->vba.PTEBufferSizeNotExceeded[i] = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.PTEBufferSizeNotExceededY[i][k] == false
|| mode_lib->vba.PTEBufferSizeNotExceededC[i][k] == false) {
mode_lib->vba.PTEBufferSizeNotExceeded[i] = false;
}
}
}
/*Cursor Support Check*/
mode_lib->vba.CursorSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.CursorWidth[k][0] > 0.0) {
if (dml_floor(
dml_floor(
mode_lib->vba.CursorBufferSize
- mode_lib->vba.CursorChunkSize,
mode_lib->vba.CursorChunkSize) * 1024.0
/ (mode_lib->vba.CursorWidth[k][0]
* mode_lib->vba.CursorBPP[k][0]
/ 8.0),
1.0)
* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
/ mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatency
|| (mode_lib->vba.CursorBPP[k][0] == 64.0
&& mode_lib->vba.Cursor64BppSupport == false)) {
mode_lib->vba.CursorSupport = false;
}
}
}
/*Valid Pitch Check*/
mode_lib->vba.PitchSupport = true;
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.AlignedYPitch[k] = dml_ceil(
dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
mode_lib->vba.MacroTileWidthY[k]);
if (mode_lib->vba.AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
mode_lib->vba.PitchSupport = false;
}
if (mode_lib->vba.DCCEnable[k] == true) {
mode_lib->vba.AlignedDCCMetaPitch[k] = dml_ceil(
dml_max(
mode_lib->vba.DCCMetaPitchY[k],
mode_lib->vba.ViewportWidth[k]),
64.0 * mode_lib->vba.Read256BlockWidthY[k]);
} else {
mode_lib->vba.AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
}
if (mode_lib->vba.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) {
mode_lib->vba.AlignedCPitch[k] = dml_ceil(
dml_max(
mode_lib->vba.PitchC[k],
mode_lib->vba.ViewportWidth[k] / 2.0),
mode_lib->vba.MacroTileWidthC[k]);
} else {
mode_lib->vba.AlignedCPitch[k] = mode_lib->vba.PitchC[k];
}
if (mode_lib->vba.AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
mode_lib->vba.PitchSupport = false;
}
}
/*Mode Support, Voltage State and SOC Configuration*/
for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
if (mode_lib->vba.ScaleRatioAndTapsSupport == true
&& mode_lib->vba.SourceFormatPixelAndScanSupport == true
&& mode_lib->vba.ViewportSizeSupport[i] == true
&& mode_lib->vba.BandwidthSupport[i] == true
&& mode_lib->vba.DIOSupport[i] == true
&& mode_lib->vba.NotEnoughDSCUnits[i] == false
&& mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] == false
&& mode_lib->vba.UrgentLatencySupport[i] == true
&& mode_lib->vba.ROBSupport[i] == true
&& mode_lib->vba.DISPCLK_DPPCLK_Support[i] == true
&& mode_lib->vba.TotalAvailablePipesSupport[i] == true
&& mode_lib->vba.NumberOfOTGSupport == true
&& mode_lib->vba.WritebackModeSupport == true
&& mode_lib->vba.WritebackLatencySupport == true
&& mode_lib->vba.WritebackScaleRatioAndTapsSupport == true
&& mode_lib->vba.CursorSupport == true
&& mode_lib->vba.PitchSupport == true
&& mode_lib->vba.PrefetchSupported[i] == true
&& mode_lib->vba.VRatioInPrefetchSupported[i] == true
&& mode_lib->vba.PTEBufferSizeNotExceeded[i] == true
&& mode_lib->vba.NonsupportedDSCInputBPC == false) {
mode_lib->vba.ModeSupport[i] = true;
} else {
mode_lib->vba.ModeSupport[i] = false;
}
}
for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
if (i == DC__VOLTAGE_STATES || mode_lib->vba.ModeSupport[i] == true) {
mode_lib->vba.VoltageLevel = i;
}
}
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.FabricAndDRAMBandwidth =
mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
mode_lib->vba.ImmediateFlipSupport =
mode_lib->vba.ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel];
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
mode_lib->vba.DPPPerPlane[k] = mode_lib->vba.NoOfDPP[mode_lib->vba.VoltageLevel][k];
}
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
if (mode_lib->vba.BlendingAndTiming[k] == k) {
mode_lib->vba.ODMCombineEnabled[k] =
mode_lib->vba.ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
} else {
mode_lib->vba.ODMCombineEnabled[k] = 0;
}
mode_lib->vba.DSCEnabled[k] =
mode_lib->vba.RequiresDSC[mode_lib->vba.VoltageLevel][k];
mode_lib->vba.OutputBpp[k] =
mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k];
}
}