cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

display_mode_vba.c (46308B)


      1/*
      2 * Copyright 2017 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26
     27#include "display_mode_lib.h"
     28#include "display_mode_vba.h"
     29#include "dml_inline_defs.h"
     30
     31/*
     32 * NOTE:
     33 *   This file is gcc-parsable HW gospel, coming straight from HW engineers.
     34 *
     35 * It doesn't adhere to Linux kernel style and sometimes will do things in odd
     36 * ways. Unless there is something clearly wrong with it the code should
     37 * remain as-is as it provides us with a guarantee from HW that it is correct.
     38 */
     39
     40
     41static void fetch_socbb_params(struct display_mode_lib *mode_lib);
     42static void fetch_ip_params(struct display_mode_lib *mode_lib);
     43static void fetch_pipe_params(struct display_mode_lib *mode_lib);
     44static void recalculate_params(
     45		struct display_mode_lib *mode_lib,
     46		const display_e2e_pipe_params_st *pipes,
     47		unsigned int num_pipes);
     48
     49static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
     50static void cache_debug_params(struct display_mode_lib *mode_lib);
     51
     52unsigned int dml_get_voltage_level(
     53		struct display_mode_lib *mode_lib,
     54		const display_e2e_pipe_params_st *pipes,
     55		unsigned int num_pipes)
     56{
     57	bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
     58			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
     59			|| num_pipes != mode_lib->vba.cache_num_pipes
     60			|| memcmp(pipes, mode_lib->vba.cache_pipes,
     61					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
     62
     63	mode_lib->vba.soc = mode_lib->soc;
     64	mode_lib->vba.ip = mode_lib->ip;
     65	memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
     66	mode_lib->vba.cache_num_pipes = num_pipes;
     67
     68	if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
     69		mode_lib->funcs.recalculate(mode_lib);
     70	else {
     71		fetch_socbb_params(mode_lib);
     72		fetch_ip_params(mode_lib);
     73		fetch_pipe_params(mode_lib);
     74		PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
     75	}
     76	mode_lib->funcs.validate(mode_lib);
     77	cache_debug_params(mode_lib);
     78
     79	return mode_lib->vba.VoltageLevel;
     80}
     81
     82#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) \
     83{ \
     84	recalculate_params(mode_lib, pipes, num_pipes); \
     85	return var; \
     86}
     87
     88dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFCLKDeepSleep);
     89dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
     90dml_get_attr_func(wm_memory_trip, mode_lib->vba.UrgentLatency);
     91dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
     92dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
     93dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
     94dml_get_attr_func(wm_z8_stutter_exit, mode_lib->vba.Z8StutterExitWatermark);
     95dml_get_attr_func(wm_z8_stutter_enter_exit, mode_lib->vba.Z8StutterEnterPlusExitWatermark);
     96dml_get_attr_func(stutter_efficiency_z8, mode_lib->vba.Z8StutterEfficiency);
     97dml_get_attr_func(stutter_num_bursts_z8, mode_lib->vba.Z8NumberOfStutterBurstsPerFrame);
     98dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
     99dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
    100dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
    101dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
    102dml_get_attr_func(stutter_period, mode_lib->vba.StutterPeriod);
    103dml_get_attr_func(urgent_latency, mode_lib->vba.UrgentLatency);
    104dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
    105dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
    106dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
    107dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
    108dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
    109dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
    110dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
    111dml_get_attr_func(fraction_of_urgent_bandwidth, mode_lib->vba.FractionOfUrgentBandwidth);
    112dml_get_attr_func(fraction_of_urgent_bandwidth_imm_flip, mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip);
    113
    114#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) \
    115{\
    116	unsigned int which_plane; \
    117	recalculate_params(mode_lib, pipes, num_pipes); \
    118	which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
    119	return var[which_plane]; \
    120}
    121
    122dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
    123dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
    124dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
    125dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
    126dml_get_pipe_attr_func(min_ttu_vblank_in_us, mode_lib->vba.MinTTUVBlank);
    127dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
    128dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
    129dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
    130dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
    131dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
    132dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
    133dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
    134dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
    135dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
    136dml_get_pipe_attr_func(refcyc_per_vm_group_vblank, mode_lib->vba.TimePerVMGroupVBlank);
    137dml_get_pipe_attr_func(refcyc_per_vm_group_flip, mode_lib->vba.TimePerVMGroupFlip);
    138dml_get_pipe_attr_func(refcyc_per_vm_req_vblank, mode_lib->vba.TimePerVMRequestVBlank);
    139dml_get_pipe_attr_func(refcyc_per_vm_req_flip, mode_lib->vba.TimePerVMRequestFlip);
    140dml_get_pipe_attr_func(refcyc_per_vm_group_vblank_in_us, mode_lib->vba.TimePerVMGroupVBlank);
    141dml_get_pipe_attr_func(refcyc_per_vm_group_flip_in_us, mode_lib->vba.TimePerVMGroupFlip);
    142dml_get_pipe_attr_func(refcyc_per_vm_req_vblank_in_us, mode_lib->vba.TimePerVMRequestVBlank);
    143dml_get_pipe_attr_func(refcyc_per_vm_req_flip_in_us, mode_lib->vba.TimePerVMRequestFlip);
    144dml_get_pipe_attr_func(refcyc_per_vm_dmdata_in_us, mode_lib->vba.Tdmdl_vm);
    145dml_get_pipe_attr_func(dmdata_dl_delta_in_us, mode_lib->vba.Tdmdl);
    146dml_get_pipe_attr_func(refcyc_per_line_delivery_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLuma);
    147dml_get_pipe_attr_func(refcyc_per_line_delivery_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChroma);
    148dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch);
    149dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch);
    150dml_get_pipe_attr_func(refcyc_per_req_delivery_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLuma);
    151dml_get_pipe_attr_func(refcyc_per_req_delivery_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChroma);
    152dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLumaPrefetch);
    153dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChromaPrefetch);
    154dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_in_us, mode_lib->vba.CursorRequestDeliveryTime);
    155dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_pre_in_us, mode_lib->vba.CursorRequestDeliveryTimePrefetch);
    156dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_l_in_us, mode_lib->vba.TimePerMetaChunkNominal);
    157dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_c_in_us, mode_lib->vba.TimePerChromaMetaChunkNominal);
    158dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_l_in_us, mode_lib->vba.TimePerMetaChunkVBlank);
    159dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_c_in_us, mode_lib->vba.TimePerChromaMetaChunkVBlank);
    160dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_l_in_us, mode_lib->vba.TimePerMetaChunkFlip);
    161dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_c_in_us, mode_lib->vba.TimePerChromaMetaChunkFlip);
    162dml_get_pipe_attr_func(vstartup, mode_lib->vba.VStartup);
    163dml_get_pipe_attr_func(vupdate_offset, mode_lib->vba.VUpdateOffsetPix);
    164dml_get_pipe_attr_func(vupdate_width, mode_lib->vba.VUpdateWidthPix);
    165dml_get_pipe_attr_func(vready_offset, mode_lib->vba.VReadyOffsetPix);
    166dml_get_pipe_attr_func(vready_at_or_after_vsync, mode_lib->vba.VREADY_AT_OR_AFTER_VSYNC);
    167dml_get_pipe_attr_func(min_dst_y_next_start, mode_lib->vba.MIN_DST_Y_NEXT_START);
    168
    169double get_total_immediate_flip_bytes(
    170		struct display_mode_lib *mode_lib,
    171		const display_e2e_pipe_params_st *pipes,
    172		unsigned int num_pipes)
    173{
    174	recalculate_params(mode_lib, pipes, num_pipes);
    175	return mode_lib->vba.TotImmediateFlipBytes;
    176}
    177
    178double get_total_immediate_flip_bw(
    179		struct display_mode_lib *mode_lib,
    180		const display_e2e_pipe_params_st *pipes,
    181		unsigned int num_pipes)
    182{
    183	unsigned int k;
    184	double immediate_flip_bw = 0.0;
    185	recalculate_params(mode_lib, pipes, num_pipes);
    186	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
    187		immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k];
    188	return immediate_flip_bw;
    189}
    190
    191double get_total_prefetch_bw(
    192		struct display_mode_lib *mode_lib,
    193		const display_e2e_pipe_params_st *pipes,
    194		unsigned int num_pipes)
    195{
    196	unsigned int k;
    197	double total_prefetch_bw = 0.0;
    198
    199	recalculate_params(mode_lib, pipes, num_pipes);
    200	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
    201		total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
    202	return total_prefetch_bw;
    203}
    204
    205static void fetch_socbb_params(struct display_mode_lib *mode_lib)
    206{
    207	soc_bounding_box_st *soc = &mode_lib->vba.soc;
    208	int i;
    209
    210	// SOC Bounding Box Parameters
    211	mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
    212	mode_lib->vba.NumberOfChannels = soc->num_chans;
    213	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly =
    214			soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only; // there's always that one bastard variable that's so long it throws everything out of alignment!
    215	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData =
    216			soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
    217	mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly =
    218			soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
    219	mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation =
    220			soc->max_avg_sdp_bw_use_normal_percent;
    221	mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation =
    222			soc->max_avg_dram_bw_use_normal_percent;
    223	mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us;
    224	mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us;
    225	mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us;
    226	mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
    227	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly =
    228			soc->urgent_out_of_order_return_per_channel_pixel_only_bytes;
    229	mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData =
    230			soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
    231	mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly =
    232			soc->urgent_out_of_order_return_per_channel_vm_only_bytes;
    233	mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
    234	mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
    235	mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
    236	mode_lib->vba.PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = soc->pct_ideal_sdp_bw_after_urgent;
    237	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
    238	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only;
    239	mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
    240	mode_lib->vba.MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation =
    241			soc->max_avg_sdp_bw_use_normal_percent;
    242	mode_lib->vba.SRExitZ8Time = soc->sr_exit_z8_time_us;
    243	mode_lib->vba.SREnterPlusExitZ8Time = soc->sr_enter_plus_exit_z8_time_us;
    244	mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
    245	mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
    246	mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
    247			mode_lib->vba.DummyPStateCheck;
    248	mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive;
    249	mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank =
    250		soc->allow_dram_self_refresh_or_dram_clock_change_in_vblank;
    251
    252	mode_lib->vba.Downspreading = soc->downspread_percent;
    253	mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes;   // new!
    254	mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
    255	mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent;   // new
    256	mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz;   // new
    257	mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
    258	mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024;
    259	mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024;
    260	// Set the voltage scaling clocks as the defaults. Most of these will
    261	// be set to different values by the test
    262	for (i = 0; i < mode_lib->vba.soc.num_states; i++)
    263		if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
    264			break;
    265
    266	mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
    267	mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
    268	mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts;
    269	mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
    270
    271	mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
    272	mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
    273	mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw;
    274
    275	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
    276	mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
    277	mode_lib->vba.MaxHSCLRatio = 4;
    278	mode_lib->vba.MaxVSCLRatio = 4;
    279	mode_lib->vba.Cursor64BppSupport = true;
    280	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
    281		mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
    282		mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
    283		mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
    284		mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
    285		mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz;
    286		mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
    287		mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
    288		mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts;
    289		//mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
    290		mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
    291		mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz;
    292	}
    293
    294	mode_lib->vba.DoUrgentLatencyAdjustment =
    295		soc->do_urgent_latency_adjustment;
    296	mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent =
    297		soc->urgent_latency_adjustment_fabric_clock_component_us;
    298	mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
    299		soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
    300}
    301
    302static void fetch_ip_params(struct display_mode_lib *mode_lib)
    303{
    304	ip_params_st *ip = &mode_lib->vba.ip;
    305
    306	// IP Parameters
    307	mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
    308	mode_lib->vba.ClampMinDCFCLK = ip->clamp_min_dcfclk;
    309	mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
    310	mode_lib->vba.MaxNumOTG = ip->max_num_otg;
    311	mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
    312	mode_lib->vba.MaxNumWriteback = ip->max_num_wb;
    313	mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
    314	mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
    315
    316	mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
    317	mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
    318	mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
    319	mode_lib->vba.DETBufferSizeInKByte[0] = ip->det_buffer_size_kbytes;
    320	mode_lib->vba.ConfigReturnBufferSizeInKByte = ip->config_return_buffer_size_in_kbytes;
    321	mode_lib->vba.CompressedBufferSegmentSizeInkByte = ip->compressed_buffer_segment_size_in_kbytes;
    322	mode_lib->vba.MetaFIFOSizeInKEntries = ip->meta_fifo_size_in_kentries;
    323	mode_lib->vba.ZeroSizeBufferEntries = ip->zero_size_buffer_entries;
    324	mode_lib->vba.COMPBUF_RESERVED_SPACE_64B = ip->compbuf_reserved_space_64b;
    325	mode_lib->vba.COMPBUF_RESERVED_SPACE_ZS = ip->compbuf_reserved_space_zs;
    326	mode_lib->vba.MaximumDSCBitsPerComponent = ip->maximum_dsc_bits_per_component;
    327	mode_lib->vba.DSC422NativeSupport = ip->dsc422_native_support;
    328
    329	mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
    330	mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
    331	mode_lib->vba.MinMetaChunkSizeBytes = ip->min_meta_chunk_size_bytes;
    332	mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
    333	mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
    334	mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
    335	mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma;
    336	mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma;
    337	mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
    338	mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
    339	mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio;
    340	mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio;
    341	mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024;
    342	mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024;
    343
    344	mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes;
    345	mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size;
    346
    347	mode_lib->vba.WritebackChromaLineBufferWidth =
    348			ip->writeback_chroma_line_buffer_width_pixels;
    349	mode_lib->vba.WritebackLineBufferLumaBufferSize =
    350			ip->writeback_line_buffer_luma_buffer_size;
    351	mode_lib->vba.WritebackLineBufferChromaBufferSize =
    352			ip->writeback_line_buffer_chroma_buffer_size;
    353	mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported;
    354	mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio;
    355	mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio;
    356	mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio;
    357	mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio;
    358	mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps;
    359	mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps;
    360	mode_lib->vba.WritebackConfiguration = dm_normal;
    361	mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels;
    362	mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels;
    363	mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels;
    364	mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels;
    365	mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
    366	mode_lib->vba.NumberOfDSC = ip->num_dsc;
    367	mode_lib->vba.ODMCapability = ip->odm_capable;
    368	mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
    369
    370	mode_lib->vba.XFCSupported = ip->xfc_supported;
    371	mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
    372	mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
    373	mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
    374	mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
    375	mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
    376	mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
    377	mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
    378	mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
    379	mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled;
    380	mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported;
    381	mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
    382	mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
    383	mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes;
    384	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported;
    385}
    386
    387static void fetch_pipe_params(struct display_mode_lib *mode_lib)
    388{
    389	display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
    390	ip_params_st *ip = &mode_lib->vba.ip;
    391
    392	unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
    393	unsigned int j, k;
    394	bool PlaneVisited[DC__NUM_DPP__MAX];
    395	bool visited[DC__NUM_DPP__MAX];
    396
    397	// Convert Pipes to Planes
    398	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
    399		visited[k] = false;
    400
    401	mode_lib->vba.NumberOfActivePlanes = 0;
    402	mode_lib->vba.ImmediateFlipSupport = false;
    403	for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
    404		display_pipe_source_params_st *src = &pipes[j].pipe.src;
    405		display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
    406		scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
    407		scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
    408		display_output_params_st *dout = &pipes[j].dout;
    409		display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
    410
    411		if (visited[j])
    412			continue;
    413		visited[j] = true;
    414
    415		mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_not_required;
    416		mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
    417		mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
    418		mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
    419				(enum scan_direction_class) (src->source_scan);
    420		mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
    421				src->viewport_width;
    422		mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] =
    423				src->viewport_width_c;
    424		mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
    425				src->viewport_height;
    426		mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] =
    427				src->viewport_height_c;
    428		mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
    429				src->viewport_y_y;
    430		mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
    431				src->viewport_y_c;
    432		mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
    433		mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_y;
    434		mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_y;
    435		mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
    436		mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_c;
    437		mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_c;
    438		mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
    439		mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c;
    440		mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
    441		mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c;
    442		mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
    443		mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c;
    444		mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
    445		mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
    446		if (dst->interlaced && !ip->ptoi_supported) {
    447			mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
    448			mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
    449		}
    450		mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
    451		mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
    452		mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
    453		mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
    454		mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
    455		mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
    456		mode_lib->vba.VFrontPorch[mode_lib->vba.NumberOfActivePlanes] = dst->vfront_porch;
    457		mode_lib->vba.DCCFractionOfZeroSizeRequestsLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_luma;
    458		mode_lib->vba.DCCFractionOfZeroSizeRequestsChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_chroma;
    459		mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
    460				src->dcc_use_global ?
    461						ip->dcc_supported : src->dcc && ip->dcc_supported;
    462		mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
    463		/* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
    464		mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
    465		mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
    466		mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format);
    467		mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
    468		mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
    469		mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
    470				(enum dm_swizzle_mode) (src->sw_mode);
    471		mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
    472				dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
    473		mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
    474				dst->odm_combine;
    475		mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
    476				(enum output_format_class) (dout->output_format);
    477		mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
    478				dout->output_bpp;
    479		mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
    480				(enum output_encoder_class) (dout->output_type);
    481		mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
    482				dout->is_virtual;
    483
    484		if (!dout->dsc_enable)
    485			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
    486		else
    487			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
    488
    489		mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
    490				dout->dp_lanes;
    491		/* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
    492		mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
    493			dout->max_audio_sample_rate;
    494		mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
    495			1;
    496		mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
    497		mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
    498		mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
    499		mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
    500				dout->dsc_slices;
    501		if (!dout->dsc_input_bpc) {
    502			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
    503				ip->maximum_dsc_bits_per_component;
    504		} else {
    505			mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
    506				dout->dsc_input_bpc;
    507		}
    508		mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
    509		mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
    510				dout->num_active_wb;
    511		mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
    512				dout->wb.wb_src_height;
    513		mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
    514				dout->wb.wb_src_width;
    515		mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
    516				dout->wb.wb_dst_width;
    517		mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
    518				dout->wb.wb_dst_height;
    519		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
    520				dout->wb.wb_hratio;
    521		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
    522				dout->wb.wb_vratio;
    523		mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
    524				(enum source_format_class) (dout->wb.wb_pixel_format);
    525		mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
    526				dout->wb.wb_htaps_luma;
    527		mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
    528				dout->wb.wb_vtaps_luma;
    529		mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
    530				dout->wb.wb_htaps_luma;
    531		mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
    532				dout->wb.wb_vtaps_luma;
    533		mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
    534				dout->wb.wb_htaps_chroma;
    535		mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
    536				dout->wb.wb_vtaps_chroma;
    537		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
    538				dout->wb.wb_hratio;
    539		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
    540				dout->wb.wb_vratio;
    541
    542		mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
    543				src->dynamic_metadata_enable;
    544		mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
    545				src->dynamic_metadata_lines_before_active;
    546		mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
    547				src->dynamic_metadata_xmit_bytes;
    548
    549		mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
    550				&& ip->xfc_supported;
    551		mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
    552		mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
    553		mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
    554		mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
    555		mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
    556		mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
    557		mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
    558		if (ip->is_line_buffer_bpp_fixed)
    559			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
    560					ip->line_buffer_fixed_bpp;
    561		else {
    562			unsigned int lb_depth;
    563
    564			switch (scl->lb_depth) {
    565			case dm_lb_6:
    566				lb_depth = 18;
    567				break;
    568			case dm_lb_8:
    569				lb_depth = 24;
    570				break;
    571			case dm_lb_10:
    572				lb_depth = 30;
    573				break;
    574			case dm_lb_12:
    575				lb_depth = 36;
    576				break;
    577			case dm_lb_16:
    578				lb_depth = 48;
    579				break;
    580			case dm_lb_19:
    581				lb_depth = 57;
    582				break;
    583			default:
    584				lb_depth = 36;
    585			}
    586			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
    587		}
    588		mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
    589		// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
    590		// calculate things a little more accurately
    591		for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
    592			switch (k) {
    593			case 0:
    594				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
    595						CursorBppEnumToBits(
    596								(enum cursor_bpp) (src->cur0_bpp));
    597				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
    598						src->cur0_src_width;
    599				if (src->cur0_src_width > 0)
    600					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
    601				break;
    602			case 1:
    603				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
    604						CursorBppEnumToBits(
    605								(enum cursor_bpp) (src->cur1_bpp));
    606				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
    607						src->cur1_src_width;
    608				if (src->cur1_src_width > 0)
    609					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
    610				break;
    611			default:
    612				dml_print(
    613						"ERROR: Number of cursors specified exceeds supported maximum\n")
    614				;
    615			}
    616		}
    617
    618		OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
    619
    620		if (j == 0)
    621			mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
    622		else
    623			mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
    624									|| dst->use_maximum_vstartup;
    625
    626		if (dst->odm_combine && !src->is_hsplit)
    627			dml_print(
    628					"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
    629					j);
    630
    631		if (src->is_hsplit) {
    632			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
    633				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
    634				display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
    635
    636				if (src_k->is_hsplit && !visited[k]
    637						&& src->hsplit_grp == src_k->hsplit_grp) {
    638					mode_lib->vba.pipe_plane[k] =
    639							mode_lib->vba.NumberOfActivePlanes;
    640					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
    641					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
    642							== dm_horz) {
    643						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
    644								src_k->viewport_width;
    645						mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
    646								src_k->viewport_width_c;
    647						mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
    648								dst_k->recout_width;
    649					} else {
    650						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
    651								src_k->viewport_height;
    652						mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
    653								src_k->viewport_height_c;
    654					}
    655
    656					visited[k] = true;
    657				}
    658			}
    659		}
    660		if (src->viewport_width_max) {
    661			int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
    662			int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
    663
    664			if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
    665				mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
    666			if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
    667				mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
    668			if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
    669				mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
    670			if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
    671				mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
    672		}
    673
    674		if (pipes[j].pipe.src.immediate_flip) {
    675			mode_lib->vba.ImmediateFlipSupport = true;
    676			mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_required;
    677		}
    678
    679		mode_lib->vba.NumberOfActivePlanes++;
    680	}
    681
    682	// handle overlays through BlendingAndTiming
    683	// BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
    684
    685	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
    686		PlaneVisited[j] = false;
    687
    688	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
    689		for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
    690			if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
    691				// doesn't matter, so choose the smaller one
    692				mode_lib->vba.BlendingAndTiming[j] = j;
    693				PlaneVisited[j] = true;
    694				mode_lib->vba.BlendingAndTiming[k] = j;
    695				PlaneVisited[k] = true;
    696			}
    697		}
    698
    699		if (!PlaneVisited[j]) {
    700			mode_lib->vba.BlendingAndTiming[j] = j;
    701			PlaneVisited[j] = true;
    702		}
    703	}
    704
    705	mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting;
    706	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
    707		if (pipes[k].pipe.src.unbounded_req_mode == 0)
    708			mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting_disable;
    709	}
    710	// TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
    711	// Do we want the dscclk to automatically be halved? Guess not since the value is specified
    712	mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
    713	for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
    714		ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
    715	}
    716
    717	mode_lib->vba.GPUVMEnable = false;
    718	mode_lib->vba.HostVMEnable = false;
    719	mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
    720	mode_lib->vba.OverrideHostVMPageTableLevels = 0;
    721
    722	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
    723		mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
    724		mode_lib->vba.OverrideGPUVMPageTableLevels =
    725				(pipes[k].pipe.src.gpuvm_levels_force_en
    726						&& mode_lib->vba.OverrideGPUVMPageTableLevels
    727								< pipes[k].pipe.src.gpuvm_levels_force) ?
    728						pipes[k].pipe.src.gpuvm_levels_force :
    729						mode_lib->vba.OverrideGPUVMPageTableLevels;
    730
    731		mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
    732		mode_lib->vba.OverrideHostVMPageTableLevels =
    733				(pipes[k].pipe.src.hostvm_levels_force_en
    734						&& mode_lib->vba.OverrideHostVMPageTableLevels
    735								< pipes[k].pipe.src.hostvm_levels_force) ?
    736						pipes[k].pipe.src.hostvm_levels_force :
    737						mode_lib->vba.OverrideHostVMPageTableLevels;
    738	}
    739
    740	if (mode_lib->vba.OverrideGPUVMPageTableLevels)
    741		mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
    742
    743	if (mode_lib->vba.OverrideHostVMPageTableLevels)
    744		mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
    745
    746	mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
    747	mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
    748}
    749
    750/**
    751 * ********************************************************************************************
    752 * cache_debug_params: Cache any params that needed to be maintained from the initial validation
    753 * for debug purposes.
    754 *
    755 * The DML getters can modify some of the VBA params that we are interested in (for example when
    756 * calculating with dummy p-state latency), so cache any params here that we want for debugging
    757 *
    758 * @param [in] mode_lib: mode_lib input/output of validate call
    759 *
    760 * @return: void
    761 *
    762 * ********************************************************************************************
    763 */
    764static void cache_debug_params(struct display_mode_lib *mode_lib)
    765{
    766	int k = 0;
    767
    768	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
    769		mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
    770}
    771
    772// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
    773// rather than working them out as in recalculate_ms
    774static void recalculate_params(
    775		struct display_mode_lib *mode_lib,
    776		const display_e2e_pipe_params_st *pipes,
    777		unsigned int num_pipes)
    778{
    779	// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
    780	if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
    781			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
    782			|| num_pipes != mode_lib->vba.cache_num_pipes
    783			|| memcmp(
    784					pipes,
    785					mode_lib->vba.cache_pipes,
    786					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
    787		mode_lib->vba.soc = mode_lib->soc;
    788		mode_lib->vba.ip = mode_lib->ip;
    789		memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
    790		mode_lib->vba.cache_num_pipes = num_pipes;
    791		mode_lib->funcs.recalculate(mode_lib);
    792	}
    793}
    794
    795bool Calculate256BBlockSizes(
    796		enum source_format_class SourcePixelFormat,
    797		enum dm_swizzle_mode SurfaceTiling,
    798		unsigned int BytePerPixelY,
    799		unsigned int BytePerPixelC,
    800		unsigned int *BlockHeight256BytesY,
    801		unsigned int *BlockHeight256BytesC,
    802		unsigned int *BlockWidth256BytesY,
    803		unsigned int *BlockWidth256BytesC)
    804{
    805	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
    806			|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
    807		if (SurfaceTiling == dm_sw_linear) {
    808			*BlockHeight256BytesY = 1;
    809		} else if (SourcePixelFormat == dm_444_64) {
    810			*BlockHeight256BytesY = 4;
    811		} else if (SourcePixelFormat == dm_444_8) {
    812			*BlockHeight256BytesY = 16;
    813		} else {
    814			*BlockHeight256BytesY = 8;
    815		}
    816		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
    817		*BlockHeight256BytesC = 0;
    818		*BlockWidth256BytesC = 0;
    819	} else {
    820		if (SurfaceTiling == dm_sw_linear) {
    821			*BlockHeight256BytesY = 1;
    822			*BlockHeight256BytesC = 1;
    823		} else if (SourcePixelFormat == dm_420_8) {
    824			*BlockHeight256BytesY = 16;
    825			*BlockHeight256BytesC = 8;
    826		} else {
    827			*BlockHeight256BytesY = 8;
    828			*BlockHeight256BytesC = 8;
    829		}
    830		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
    831		*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
    832	}
    833	return true;
    834}
    835
    836bool CalculateMinAndMaxPrefetchMode(
    837		enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
    838		unsigned int *MinPrefetchMode,
    839		unsigned int *MaxPrefetchMode)
    840{
    841	if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
    842			== dm_neither_self_refresh_nor_mclk_switch) {
    843		*MinPrefetchMode = 2;
    844		*MaxPrefetchMode = 2;
    845		return false;
    846	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
    847		*MinPrefetchMode = 1;
    848		*MaxPrefetchMode = 1;
    849		return false;
    850	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
    851			== dm_allow_self_refresh_and_mclk_switch) {
    852		*MinPrefetchMode = 0;
    853		*MaxPrefetchMode = 0;
    854		return false;
    855	} else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
    856			== dm_try_to_allow_self_refresh_and_mclk_switch) {
    857		*MinPrefetchMode = 0;
    858		*MaxPrefetchMode = 2;
    859		return false;
    860	}
    861	*MinPrefetchMode = 0;
    862	*MaxPrefetchMode = 2;
    863	return true;
    864}
    865
    866void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
    867{
    868	unsigned int k;
    869
    870	//Progressive To Interlace Unit Effect
    871	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
    872		mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
    873		if (mode_lib->vba.Interlace[k] == 1
    874				&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
    875			mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
    876		}
    877	}
    878}
    879
    880static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
    881{
    882	switch (ebpp) {
    883	case dm_cur_2bit:
    884		return 2;
    885	case dm_cur_32bit:
    886		return 32;
    887	case dm_cur_64bit:
    888		return 64;
    889	default:
    890		return 0;
    891	}
    892}
    893
    894void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
    895{
    896	soc_bounding_box_st *soc = &mode_lib->vba.soc;
    897	unsigned int k;
    898	unsigned int total_pipes = 0;
    899
    900	mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
    901	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
    902	if (mode_lib->vba.ReturnBW == 0)
    903		mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
    904	mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
    905
    906	fetch_socbb_params(mode_lib);
    907	fetch_ip_params(mode_lib);
    908	fetch_pipe_params(mode_lib);
    909
    910	mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
    911	mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
    912	if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
    913		mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
    914	else
    915		mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
    916
    917	// Total Available Pipes Support Check
    918	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
    919		total_pipes += mode_lib->vba.DPPPerPlane[k];
    920	}
    921	ASSERT(total_pipes <= DC__NUM_DPP__MAX);
    922}
    923
    924double CalculateWriteBackDISPCLK(
    925		enum source_format_class WritebackPixelFormat,
    926		double PixelClock,
    927		double WritebackHRatio,
    928		double WritebackVRatio,
    929		unsigned int WritebackLumaHTaps,
    930		unsigned int WritebackLumaVTaps,
    931		unsigned int WritebackChromaHTaps,
    932		unsigned int WritebackChromaVTaps,
    933		double WritebackDestinationWidth,
    934		unsigned int HTotal,
    935		unsigned int WritebackChromaLineBufferWidth)
    936{
    937	double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
    938		dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
    939		dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
    940			+ dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
    941			* (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
    942			dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
    943	if (WritebackPixelFormat != dm_444_32) {
    944		CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
    945			dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
    946			dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
    947				+ dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
    948				+ dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
    949				dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
    950	}
    951	return CalculateWriteBackDISPCLK;
    952}
    953