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