Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2017 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 
0027 #include "display_mode_lib.h"
0028 #include "display_mode_vba.h"
0029 #include "dml_inline_defs.h"
0030 
0031 /*
0032  * NOTE:
0033  *   This file is gcc-parsable HW gospel, coming straight from HW engineers.
0034  *
0035  * It doesn't adhere to Linux kernel style and sometimes will do things in odd
0036  * ways. Unless there is something clearly wrong with it the code should
0037  * remain as-is as it provides us with a guarantee from HW that it is correct.
0038  */
0039 
0040 
0041 static void fetch_socbb_params(struct display_mode_lib *mode_lib);
0042 static void fetch_ip_params(struct display_mode_lib *mode_lib);
0043 static void fetch_pipe_params(struct display_mode_lib *mode_lib);
0044 static void recalculate_params(
0045         struct display_mode_lib *mode_lib,
0046         const display_e2e_pipe_params_st *pipes,
0047         unsigned int num_pipes);
0048 
0049 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
0050 static void cache_debug_params(struct display_mode_lib *mode_lib);
0051 
0052 unsigned int dml_get_voltage_level(
0053         struct display_mode_lib *mode_lib,
0054         const display_e2e_pipe_params_st *pipes,
0055         unsigned int num_pipes)
0056 {
0057     bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
0058             || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
0059             || num_pipes != mode_lib->vba.cache_num_pipes
0060             || memcmp(pipes, mode_lib->vba.cache_pipes,
0061                     sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
0062 
0063     mode_lib->vba.soc = mode_lib->soc;
0064     mode_lib->vba.ip = mode_lib->ip;
0065     memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
0066     mode_lib->vba.cache_num_pipes = num_pipes;
0067 
0068     if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
0069         mode_lib->funcs.recalculate(mode_lib);
0070     else {
0071         fetch_socbb_params(mode_lib);
0072         fetch_ip_params(mode_lib);
0073         fetch_pipe_params(mode_lib);
0074         PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
0075     }
0076     mode_lib->funcs.validate(mode_lib);
0077     cache_debug_params(mode_lib);
0078 
0079     return mode_lib->vba.VoltageLevel;
0080 }
0081 
0082 #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) \
0083 { \
0084     recalculate_params(mode_lib, pipes, num_pipes); \
0085     return var; \
0086 }
0087 
0088 dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFCLKDeepSleep);
0089 dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
0090 dml_get_attr_func(wm_memory_trip, mode_lib->vba.UrgentLatency);
0091 dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
0092 dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
0093 dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
0094 dml_get_attr_func(wm_z8_stutter_exit, mode_lib->vba.Z8StutterExitWatermark);
0095 dml_get_attr_func(wm_z8_stutter_enter_exit, mode_lib->vba.Z8StutterEnterPlusExitWatermark);
0096 dml_get_attr_func(stutter_efficiency_z8, mode_lib->vba.Z8StutterEfficiency);
0097 dml_get_attr_func(stutter_num_bursts_z8, mode_lib->vba.Z8NumberOfStutterBurstsPerFrame);
0098 dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
0099 dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
0100 dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
0101 dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
0102 dml_get_attr_func(stutter_period, mode_lib->vba.StutterPeriod);
0103 dml_get_attr_func(urgent_latency, mode_lib->vba.UrgentLatency);
0104 dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
0105 dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
0106 dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
0107 dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
0108 dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
0109 dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
0110 dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
0111 dml_get_attr_func(fraction_of_urgent_bandwidth, mode_lib->vba.FractionOfUrgentBandwidth);
0112 dml_get_attr_func(fraction_of_urgent_bandwidth_imm_flip, mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip);
0113 
0114 
0115 dml_get_attr_func(cstate_max_cap_mode, mode_lib->vba.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE);
0116 dml_get_attr_func(comp_buffer_size_kbytes, mode_lib->vba.CompressedBufferSizeInkByte);
0117 dml_get_attr_func(pixel_chunk_size_in_kbyte, mode_lib->vba.PixelChunkSizeInKByte);
0118 dml_get_attr_func(alpha_pixel_chunk_size_in_kbyte, mode_lib->vba.AlphaPixelChunkSizeInKByte);
0119 dml_get_attr_func(meta_chunk_size_in_kbyte, mode_lib->vba.MetaChunkSize);
0120 dml_get_attr_func(min_pixel_chunk_size_in_byte, mode_lib->vba.MinPixelChunkSizeBytes);
0121 dml_get_attr_func(min_meta_chunk_size_in_byte, mode_lib->vba.MinMetaChunkSizeBytes);
0122 dml_get_attr_func(fclk_watermark, mode_lib->vba.Watermark.FCLKChangeWatermark);
0123 dml_get_attr_func(usr_retraining_watermark, mode_lib->vba.Watermark.USRRetrainingWatermark);
0124 
0125 dml_get_attr_func(comp_buffer_reserved_space_kbytes, mode_lib->vba.CompBufReservedSpaceKBytes);
0126 dml_get_attr_func(comp_buffer_reserved_space_64bytes, mode_lib->vba.CompBufReservedSpace64B);
0127 dml_get_attr_func(comp_buffer_reserved_space_zs, mode_lib->vba.CompBufReservedSpaceZs);
0128 dml_get_attr_func(unbounded_request_enabled, mode_lib->vba.UnboundedRequestEnabled);
0129 
0130 #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) \
0131 {\
0132     unsigned int which_plane; \
0133     recalculate_params(mode_lib, pipes, num_pipes); \
0134     which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
0135     return var[which_plane]; \
0136 }
0137 
0138 dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
0139 dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
0140 dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
0141 dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
0142 dml_get_pipe_attr_func(min_ttu_vblank_in_us, mode_lib->vba.MinTTUVBlank);
0143 dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
0144 dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
0145 dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
0146 dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
0147 dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
0148 dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
0149 dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
0150 dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
0151 dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
0152 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank, mode_lib->vba.TimePerVMGroupVBlank);
0153 dml_get_pipe_attr_func(refcyc_per_vm_group_flip, mode_lib->vba.TimePerVMGroupFlip);
0154 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank, mode_lib->vba.TimePerVMRequestVBlank);
0155 dml_get_pipe_attr_func(refcyc_per_vm_req_flip, mode_lib->vba.TimePerVMRequestFlip);
0156 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank_in_us, mode_lib->vba.TimePerVMGroupVBlank);
0157 dml_get_pipe_attr_func(refcyc_per_vm_group_flip_in_us, mode_lib->vba.TimePerVMGroupFlip);
0158 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank_in_us, mode_lib->vba.TimePerVMRequestVBlank);
0159 dml_get_pipe_attr_func(refcyc_per_vm_req_flip_in_us, mode_lib->vba.TimePerVMRequestFlip);
0160 dml_get_pipe_attr_func(refcyc_per_vm_dmdata_in_us, mode_lib->vba.Tdmdl_vm);
0161 dml_get_pipe_attr_func(dmdata_dl_delta_in_us, mode_lib->vba.Tdmdl);
0162 dml_get_pipe_attr_func(refcyc_per_line_delivery_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLuma);
0163 dml_get_pipe_attr_func(refcyc_per_line_delivery_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChroma);
0164 dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch);
0165 dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch);
0166 dml_get_pipe_attr_func(refcyc_per_req_delivery_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLuma);
0167 dml_get_pipe_attr_func(refcyc_per_req_delivery_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChroma);
0168 dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLumaPrefetch);
0169 dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChromaPrefetch);
0170 dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_in_us, mode_lib->vba.CursorRequestDeliveryTime);
0171 dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_pre_in_us, mode_lib->vba.CursorRequestDeliveryTimePrefetch);
0172 dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_l_in_us, mode_lib->vba.TimePerMetaChunkNominal);
0173 dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_c_in_us, mode_lib->vba.TimePerChromaMetaChunkNominal);
0174 dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_l_in_us, mode_lib->vba.TimePerMetaChunkVBlank);
0175 dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_c_in_us, mode_lib->vba.TimePerChromaMetaChunkVBlank);
0176 dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_l_in_us, mode_lib->vba.TimePerMetaChunkFlip);
0177 dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_c_in_us, mode_lib->vba.TimePerChromaMetaChunkFlip);
0178 dml_get_pipe_attr_func(vstartup, mode_lib->vba.VStartup);
0179 dml_get_pipe_attr_func(vupdate_offset, mode_lib->vba.VUpdateOffsetPix);
0180 dml_get_pipe_attr_func(vupdate_width, mode_lib->vba.VUpdateWidthPix);
0181 dml_get_pipe_attr_func(vready_offset, mode_lib->vba.VReadyOffsetPix);
0182 dml_get_pipe_attr_func(vready_at_or_after_vsync, mode_lib->vba.VREADY_AT_OR_AFTER_VSYNC);
0183 dml_get_pipe_attr_func(min_dst_y_next_start, mode_lib->vba.MIN_DST_Y_NEXT_START);
0184 dml_get_pipe_attr_func(dst_y_per_pte_row_nom_l, mode_lib->vba.DST_Y_PER_PTE_ROW_NOM_L);
0185 dml_get_pipe_attr_func(dst_y_per_pte_row_nom_c, mode_lib->vba.DST_Y_PER_PTE_ROW_NOM_C);
0186 dml_get_pipe_attr_func(dst_y_per_meta_row_nom_l, mode_lib->vba.DST_Y_PER_META_ROW_NOM_L);
0187 dml_get_pipe_attr_func(dst_y_per_meta_row_nom_c, mode_lib->vba.DST_Y_PER_META_ROW_NOM_C);
0188 dml_get_pipe_attr_func(refcyc_per_pte_group_nom_l_in_us, mode_lib->vba.time_per_pte_group_nom_luma);
0189 dml_get_pipe_attr_func(refcyc_per_pte_group_nom_c_in_us, mode_lib->vba.time_per_pte_group_nom_chroma);
0190 dml_get_pipe_attr_func(refcyc_per_pte_group_vblank_l_in_us, mode_lib->vba.time_per_pte_group_vblank_luma);
0191 dml_get_pipe_attr_func(refcyc_per_pte_group_vblank_c_in_us, mode_lib->vba.time_per_pte_group_vblank_chroma);
0192 dml_get_pipe_attr_func(refcyc_per_pte_group_flip_l_in_us, mode_lib->vba.time_per_pte_group_flip_luma);
0193 dml_get_pipe_attr_func(refcyc_per_pte_group_flip_c_in_us, mode_lib->vba.time_per_pte_group_flip_chroma);
0194 dml_get_pipe_attr_func(vstartup_calculated, mode_lib->vba.VStartup);
0195 dml_get_pipe_attr_func(dpte_row_height_linear_c, mode_lib->vba.dpte_row_height_linear_chroma);
0196 dml_get_pipe_attr_func(swath_height_l, mode_lib->vba.SwathHeightY);
0197 dml_get_pipe_attr_func(swath_height_c, mode_lib->vba.SwathHeightC);
0198 dml_get_pipe_attr_func(det_stored_buffer_size_l_bytes, mode_lib->vba.DETBufferSizeY);
0199 dml_get_pipe_attr_func(det_stored_buffer_size_c_bytes, mode_lib->vba.DETBufferSizeC);
0200 dml_get_pipe_attr_func(dpte_group_size_in_bytes, mode_lib->vba.dpte_group_bytes);
0201 dml_get_pipe_attr_func(vm_group_size_in_bytes, mode_lib->vba.vm_group_bytes);
0202 dml_get_pipe_attr_func(dpte_row_height_linear_l, mode_lib->vba.dpte_row_height_linear);
0203 dml_get_pipe_attr_func(pte_buffer_mode, mode_lib->vba.PTE_BUFFER_MODE);
0204 dml_get_pipe_attr_func(subviewport_lines_needed_in_mall, mode_lib->vba.SubViewportLinesNeededInMALL);
0205 
0206 double get_total_immediate_flip_bytes(
0207         struct display_mode_lib *mode_lib,
0208         const display_e2e_pipe_params_st *pipes,
0209         unsigned int num_pipes)
0210 {
0211     recalculate_params(mode_lib, pipes, num_pipes);
0212     return mode_lib->vba.TotImmediateFlipBytes;
0213 }
0214 
0215 double get_total_immediate_flip_bw(
0216         struct display_mode_lib *mode_lib,
0217         const display_e2e_pipe_params_st *pipes,
0218         unsigned int num_pipes)
0219 {
0220     unsigned int k;
0221     double immediate_flip_bw = 0.0;
0222     recalculate_params(mode_lib, pipes, num_pipes);
0223     for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
0224         immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k];
0225     return immediate_flip_bw;
0226 }
0227 
0228 double get_total_prefetch_bw(
0229         struct display_mode_lib *mode_lib,
0230         const display_e2e_pipe_params_st *pipes,
0231         unsigned int num_pipes)
0232 {
0233     unsigned int k;
0234     double total_prefetch_bw = 0.0;
0235 
0236     recalculate_params(mode_lib, pipes, num_pipes);
0237     for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
0238         total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
0239     return total_prefetch_bw;
0240 }
0241 
0242 unsigned int get_total_surface_size_in_mall_bytes(
0243         struct display_mode_lib *mode_lib,
0244         const display_e2e_pipe_params_st *pipes,
0245         unsigned int num_pipes)
0246 {
0247     unsigned int k;
0248     unsigned int size = 0.0;
0249     recalculate_params(mode_lib, pipes, num_pipes);
0250     for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k)
0251         size += mode_lib->vba.SurfaceSizeInMALL[k];
0252     return size;
0253 }
0254 
0255 static unsigned int get_pipe_idx(struct display_mode_lib *mode_lib, unsigned int plane_idx)
0256 {
0257     int pipe_idx = -1;
0258     int i;
0259 
0260     ASSERT(plane_idx < DC__NUM_DPP__MAX);
0261 
0262     for (i = 0; i < DC__NUM_DPP__MAX ; i++) {
0263         if (plane_idx == mode_lib->vba.pipe_plane[i]) {
0264             pipe_idx = i;
0265             break;
0266         }
0267     }
0268     ASSERT(pipe_idx >= 0);
0269 
0270     return pipe_idx;
0271 }
0272 
0273 
0274 double get_det_buffer_size_kbytes(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes,
0275         unsigned int num_pipes, unsigned int pipe_idx)
0276 {
0277     unsigned int plane_idx;
0278     double det_buf_size_kbytes;
0279 
0280     recalculate_params(mode_lib, pipes, num_pipes);
0281     plane_idx = mode_lib->vba.pipe_plane[pipe_idx];
0282 
0283     dml_print("DML::%s: num_pipes=%d pipe_idx=%d plane_idx=%0d\n", __func__, num_pipes, pipe_idx, plane_idx);
0284     det_buf_size_kbytes = mode_lib->vba.DETBufferSizeInKByte[plane_idx]; // per hubp DET buffer size
0285 
0286     dml_print("DML::%s: det_buf_size_kbytes=%3.2f\n", __func__, det_buf_size_kbytes);
0287 
0288     return det_buf_size_kbytes;
0289 }
0290 
0291 bool get_is_phantom_pipe(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes,
0292         unsigned int num_pipes, unsigned int pipe_idx)
0293 {
0294     unsigned int plane_idx;
0295 
0296     recalculate_params(mode_lib, pipes, num_pipes);
0297     plane_idx = mode_lib->vba.pipe_plane[pipe_idx];
0298     dml_print("DML::%s: num_pipes=%d pipe_idx=%d UseMALLForPStateChange=%0d\n", __func__, num_pipes, pipe_idx,
0299             mode_lib->vba.UsesMALLForPStateChange[plane_idx]);
0300     return (mode_lib->vba.UsesMALLForPStateChange[plane_idx] == dm_use_mall_pstate_change_phantom_pipe);
0301 }
0302 
0303 static void fetch_socbb_params(struct display_mode_lib *mode_lib)
0304 {
0305     soc_bounding_box_st *soc = &mode_lib->vba.soc;
0306     int i;
0307 
0308     // SOC Bounding Box Parameters
0309     mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
0310     mode_lib->vba.NumberOfChannels = soc->num_chans;
0311     mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly =
0312             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!
0313     mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData =
0314             soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
0315     mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly =
0316             soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
0317     mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation =
0318             soc->max_avg_sdp_bw_use_normal_percent;
0319     mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation =
0320             soc->max_avg_dram_bw_use_normal_percent;
0321     mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us;
0322     mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us;
0323     mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us;
0324     mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
0325     mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly =
0326             soc->urgent_out_of_order_return_per_channel_pixel_only_bytes;
0327     mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData =
0328             soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
0329     mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly =
0330             soc->urgent_out_of_order_return_per_channel_vm_only_bytes;
0331     mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
0332     mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
0333     mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
0334     mode_lib->vba.PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = soc->pct_ideal_sdp_bw_after_urgent;
0335     mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
0336     mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only;
0337     mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
0338     mode_lib->vba.MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation =
0339             soc->max_avg_sdp_bw_use_normal_percent;
0340     mode_lib->vba.SRExitZ8Time = soc->sr_exit_z8_time_us;
0341     mode_lib->vba.SREnterPlusExitZ8Time = soc->sr_enter_plus_exit_z8_time_us;
0342     mode_lib->vba.FCLKChangeLatency = soc->fclk_change_latency_us;
0343     mode_lib->vba.USRRetrainingLatency = soc->usr_retraining_latency_us;
0344     mode_lib->vba.SMNLatency = soc->smn_latency_us;
0345     mode_lib->vba.MALLAllocatedForDCNFinal = soc->mall_allocated_for_dcn_mbytes;
0346 
0347     mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencySTROBE = soc->pct_ideal_dram_bw_after_urgent_strobe;
0348     mode_lib->vba.MaxAveragePercentOfIdealFabricBWDisplayCanUseInNormalSystemOperation =
0349             soc->max_avg_fabric_bw_use_normal_percent;
0350     mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperationSTROBE =
0351             soc->max_avg_dram_bw_use_normal_strobe_percent;
0352 
0353     mode_lib->vba.DRAMClockChangeRequirementFinal = soc->dram_clock_change_requirement_final;
0354     mode_lib->vba.FCLKChangeRequirementFinal = 1;
0355     mode_lib->vba.USRRetrainingRequiredFinal = 1;
0356     mode_lib->vba.AllowForPStateChangeOrStutterInVBlankFinal = soc->allow_for_pstate_or_stutter_in_vblank_final;
0357     mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
0358     mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
0359     mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
0360             mode_lib->vba.DummyPStateCheck;
0361     mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive;
0362     mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank =
0363         soc->allow_dram_self_refresh_or_dram_clock_change_in_vblank;
0364 
0365     mode_lib->vba.Downspreading = soc->downspread_percent;
0366     mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes;   // new!
0367     mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
0368     mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent;   // new
0369     mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz;   // new
0370     mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
0371     mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024;
0372     mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024;
0373     // Set the voltage scaling clocks as the defaults. Most of these will
0374     // be set to different values by the test
0375     for (i = 0; i < mode_lib->vba.soc.num_states; i++)
0376         if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
0377             break;
0378 
0379     mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
0380     mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
0381     mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts;
0382     mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
0383 
0384     mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
0385     mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
0386     mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw;
0387 
0388     mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
0389     mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
0390     mode_lib->vba.MaxHSCLRatio = 4;
0391     mode_lib->vba.MaxVSCLRatio = 4;
0392     mode_lib->vba.Cursor64BppSupport = true;
0393     for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
0394         mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
0395         mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
0396         mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
0397         mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
0398         mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz;
0399         mode_lib->vba.PHYCLKD32PerState[i] = soc->clock_limits[i].phyclk_d32_mhz;
0400         mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
0401         mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
0402         mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts;
0403         //mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
0404         mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
0405         mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz;
0406     }
0407 
0408     mode_lib->vba.DoUrgentLatencyAdjustment =
0409         soc->do_urgent_latency_adjustment;
0410     mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent =
0411         soc->urgent_latency_adjustment_fabric_clock_component_us;
0412     mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
0413         soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
0414 }
0415 
0416 static void fetch_ip_params(struct display_mode_lib *mode_lib)
0417 {
0418     ip_params_st *ip = &mode_lib->vba.ip;
0419 
0420     // IP Parameters
0421     mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
0422     mode_lib->vba.ClampMinDCFCLK = ip->clamp_min_dcfclk;
0423     mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
0424     mode_lib->vba.MaxNumOTG = ip->max_num_otg;
0425     mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
0426     mode_lib->vba.MaxNumWriteback = ip->max_num_wb;
0427     mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
0428     mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
0429 
0430     mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
0431     mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
0432     mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
0433     mode_lib->vba.DETBufferSizeInKByte[0] = ip->det_buffer_size_kbytes;
0434     mode_lib->vba.ConfigReturnBufferSizeInKByte = ip->config_return_buffer_size_in_kbytes;
0435     mode_lib->vba.CompressedBufferSegmentSizeInkByte = ip->compressed_buffer_segment_size_in_kbytes;
0436     mode_lib->vba.MetaFIFOSizeInKEntries = ip->meta_fifo_size_in_kentries;
0437     mode_lib->vba.ZeroSizeBufferEntries = ip->zero_size_buffer_entries;
0438     mode_lib->vba.COMPBUF_RESERVED_SPACE_64B = ip->compbuf_reserved_space_64b;
0439     mode_lib->vba.COMPBUF_RESERVED_SPACE_ZS = ip->compbuf_reserved_space_zs;
0440     mode_lib->vba.MaximumDSCBitsPerComponent = ip->maximum_dsc_bits_per_component;
0441     mode_lib->vba.DSC422NativeSupport = ip->dsc422_native_support;
0442     /* In DCN3.2, nomDETInKByte should be initialized correctly. */
0443     mode_lib->vba.nomDETInKByte = ip->det_buffer_size_kbytes;
0444     mode_lib->vba.CompbufReservedSpace64B  = ip->compbuf_reserved_space_64b;
0445     mode_lib->vba.CompbufReservedSpaceZs = ip->compbuf_reserved_space_zs;
0446     mode_lib->vba.CompressedBufferSegmentSizeInkByteFinal = ip->compressed_buffer_segment_size_in_kbytes;
0447     mode_lib->vba.LineBufferSizeFinal = ip->line_buffer_size_bits;
0448     mode_lib->vba.AlphaPixelChunkSizeInKByte = ip->alpha_pixel_chunk_size_kbytes; // not ysed
0449     mode_lib->vba.MinPixelChunkSizeBytes = ip->min_pixel_chunk_size_bytes; // not used
0450     mode_lib->vba.MaximumPixelsPerLinePerDSCUnit = ip->maximum_pixels_per_line_per_dsc_unit;
0451     mode_lib->vba.MaxNumDP2p0Outputs = ip->max_num_dp2p0_outputs;
0452     mode_lib->vba.MaxNumDP2p0Streams = ip->max_num_dp2p0_streams;
0453     mode_lib->vba.DCCMetaBufferSizeBytes = ip->dcc_meta_buffer_size_bytes;
0454 
0455     mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
0456     mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
0457     mode_lib->vba.MinMetaChunkSizeBytes = ip->min_meta_chunk_size_bytes;
0458     mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
0459     mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
0460     mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
0461     mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma;
0462     mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma;
0463     mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
0464     mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
0465     mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio;
0466     mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio;
0467     mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024;
0468     mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024;
0469 
0470     mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes;
0471     mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size;
0472 
0473     mode_lib->vba.WritebackChromaLineBufferWidth =
0474             ip->writeback_chroma_line_buffer_width_pixels;
0475     mode_lib->vba.WritebackLineBufferLumaBufferSize =
0476             ip->writeback_line_buffer_luma_buffer_size;
0477     mode_lib->vba.WritebackLineBufferChromaBufferSize =
0478             ip->writeback_line_buffer_chroma_buffer_size;
0479     mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported;
0480     mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio;
0481     mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio;
0482     mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio;
0483     mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio;
0484     mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps;
0485     mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps;
0486     mode_lib->vba.WritebackConfiguration = dm_normal;
0487     mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels;
0488     mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels;
0489     mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels;
0490     mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels;
0491     mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
0492     mode_lib->vba.NumberOfDSC = ip->num_dsc;
0493     mode_lib->vba.ODMCapability = ip->odm_capable;
0494     mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
0495 
0496     mode_lib->vba.XFCSupported = ip->xfc_supported;
0497     mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
0498     mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
0499     mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
0500     mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
0501     mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
0502     mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
0503     mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
0504     mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
0505     mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled;
0506     mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported;
0507     mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
0508     mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
0509     mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes;
0510     mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported;
0511 }
0512 
0513 static void fetch_pipe_params(struct display_mode_lib *mode_lib)
0514 {
0515     display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
0516     ip_params_st *ip = &mode_lib->vba.ip;
0517 
0518     unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
0519     unsigned int j, k;
0520     bool PlaneVisited[DC__NUM_DPP__MAX];
0521     bool visited[DC__NUM_DPP__MAX];
0522 
0523     // Convert Pipes to Planes
0524     for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
0525         visited[k] = false;
0526 
0527     mode_lib->vba.NumberOfActivePlanes = 0;
0528     mode_lib->vba.NumberOfActiveSurfaces = 0;
0529     mode_lib->vba.ImmediateFlipSupport = false;
0530     for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
0531         display_pipe_source_params_st *src = &pipes[j].pipe.src;
0532         display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
0533         scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
0534         scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
0535         display_output_params_st *dout = &pipes[j].dout;
0536         display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
0537 
0538         if (visited[j])
0539             continue;
0540         visited[j] = true;
0541 
0542         mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_not_required;
0543         mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
0544         mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
0545         mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
0546                 (enum scan_direction_class) (src->source_scan);
0547         mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
0548                 src->viewport_width;
0549         mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] =
0550                 src->viewport_width_c;
0551         mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
0552                 src->viewport_height;
0553         mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] =
0554                 src->viewport_height_c;
0555         mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
0556                 src->viewport_y_y;
0557         mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
0558                 src->viewport_y_c;
0559         mode_lib->vba.SourceRotation[mode_lib->vba.NumberOfActiveSurfaces] = src->source_rotation;
0560         mode_lib->vba.ViewportXStartY[mode_lib->vba.NumberOfActiveSurfaces] = src->viewport_x_y;
0561         mode_lib->vba.ViewportXStartC[mode_lib->vba.NumberOfActiveSurfaces] = src->viewport_x_c;
0562         // TODO: Assign correct value to viewport_stationary
0563         mode_lib->vba.ViewportStationary[mode_lib->vba.NumberOfActivePlanes] =
0564                 src->viewport_stationary;
0565         mode_lib->vba.UsesMALLForPStateChange[mode_lib->vba.NumberOfActivePlanes] = src->use_mall_for_pstate_change;
0566         mode_lib->vba.UseMALLForStaticScreen[mode_lib->vba.NumberOfActivePlanes] = src->use_mall_for_static_screen;
0567         mode_lib->vba.GPUVMMinPageSizeKBytes[mode_lib->vba.NumberOfActivePlanes] = src->gpuvm_min_page_size_kbytes;
0568         mode_lib->vba.RefreshRate[mode_lib->vba.NumberOfActivePlanes] = dst->refresh_rate; //todo remove this
0569         mode_lib->vba.OutputLinkDPRate[mode_lib->vba.NumberOfActivePlanes] = dout->dp_rate;
0570         mode_lib->vba.ODMUse[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine_policy;
0571         mode_lib->vba.DETSizeOverride[mode_lib->vba.NumberOfActivePlanes] = src->det_size_override;
0572         //TODO: Need to assign correct values to dp_multistream vars
0573         mode_lib->vba.OutputMultistreamEn[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_en;
0574         mode_lib->vba.OutputMultistreamId[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_id;
0575         mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
0576         mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_y;
0577         mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_y;
0578         mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
0579         mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_c;
0580         mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_c;
0581         mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
0582         mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c;
0583         mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
0584         mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c;
0585         mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
0586         mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c;
0587         mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
0588         mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
0589         if (dst->interlaced && !ip->ptoi_supported) {
0590             mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
0591             mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
0592         }
0593         mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
0594         mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
0595         mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
0596         mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
0597         mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
0598         mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
0599         mode_lib->vba.VFrontPorch[mode_lib->vba.NumberOfActivePlanes] = dst->vfront_porch;
0600         mode_lib->vba.DCCFractionOfZeroSizeRequestsLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_luma;
0601         mode_lib->vba.DCCFractionOfZeroSizeRequestsChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_chroma;
0602         mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
0603                 src->dcc_use_global ?
0604                         ip->dcc_supported : src->dcc && ip->dcc_supported;
0605         mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
0606         /* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
0607         mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
0608         mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
0609         mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format);
0610         mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
0611         mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
0612         mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
0613                 (enum dm_swizzle_mode) (src->sw_mode);
0614         mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
0615                 dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
0616         mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
0617                 dst->odm_combine;
0618         mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
0619                 (enum output_format_class) (dout->output_format);
0620         mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
0621                 dout->output_bpp;
0622         mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
0623                 (enum output_encoder_class) (dout->output_type);
0624         mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
0625                 dout->is_virtual;
0626 
0627         if (!dout->dsc_enable)
0628             mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
0629         else
0630             mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
0631 
0632         mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
0633                 dout->dp_lanes;
0634         /* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
0635         mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
0636             dout->max_audio_sample_rate;
0637         mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
0638             1;
0639         mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
0640         mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
0641         mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
0642         mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
0643                 dout->dsc_slices;
0644         if (!dout->dsc_input_bpc) {
0645             mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
0646                 ip->maximum_dsc_bits_per_component;
0647         } else {
0648             mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
0649                 dout->dsc_input_bpc;
0650         }
0651         mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
0652         mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
0653                 dout->num_active_wb;
0654         mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
0655                 dout->wb.wb_src_height;
0656         mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
0657                 dout->wb.wb_src_width;
0658         mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
0659                 dout->wb.wb_dst_width;
0660         mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
0661                 dout->wb.wb_dst_height;
0662         mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
0663                 dout->wb.wb_hratio;
0664         mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
0665                 dout->wb.wb_vratio;
0666         mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
0667                 (enum source_format_class) (dout->wb.wb_pixel_format);
0668         mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
0669                 dout->wb.wb_htaps_luma;
0670         mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
0671                 dout->wb.wb_vtaps_luma;
0672         mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
0673                 dout->wb.wb_htaps_luma;
0674         mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
0675                 dout->wb.wb_vtaps_luma;
0676         mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
0677                 dout->wb.wb_htaps_chroma;
0678         mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
0679                 dout->wb.wb_vtaps_chroma;
0680         mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
0681                 dout->wb.wb_hratio;
0682         mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
0683                 dout->wb.wb_vratio;
0684 
0685         mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
0686                 src->dynamic_metadata_enable;
0687         mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
0688                 src->dynamic_metadata_lines_before_active;
0689         mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
0690                 src->dynamic_metadata_xmit_bytes;
0691 
0692         mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
0693                 && ip->xfc_supported;
0694         mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
0695         mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
0696         mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
0697         mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
0698         mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
0699         mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
0700         mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
0701         mode_lib->vba.DRRDisplay[mode_lib->vba.NumberOfActiveSurfaces] = dst->drr_display;
0702         if (ip->is_line_buffer_bpp_fixed)
0703             mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
0704                     ip->line_buffer_fixed_bpp;
0705         else {
0706             unsigned int lb_depth;
0707 
0708             switch (scl->lb_depth) {
0709             case dm_lb_6:
0710                 lb_depth = 18;
0711                 break;
0712             case dm_lb_8:
0713                 lb_depth = 24;
0714                 break;
0715             case dm_lb_10:
0716                 lb_depth = 30;
0717                 break;
0718             case dm_lb_12:
0719                 lb_depth = 36;
0720                 break;
0721             case dm_lb_16:
0722                 lb_depth = 48;
0723                 break;
0724             case dm_lb_19:
0725                 lb_depth = 57;
0726                 break;
0727             default:
0728                 lb_depth = 36;
0729             }
0730             mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
0731         }
0732         mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
0733         // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
0734         // calculate things a little more accurately
0735         for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
0736             switch (k) {
0737             case 0:
0738                 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
0739                         CursorBppEnumToBits(
0740                                 (enum cursor_bpp) (src->cur0_bpp));
0741                 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
0742                         src->cur0_src_width;
0743                 if (src->cur0_src_width > 0)
0744                     mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
0745                 break;
0746             case 1:
0747                 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
0748                         CursorBppEnumToBits(
0749                                 (enum cursor_bpp) (src->cur1_bpp));
0750                 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
0751                         src->cur1_src_width;
0752                 if (src->cur1_src_width > 0)
0753                     mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
0754                 break;
0755             default:
0756                 dml_print(
0757                         "ERROR: Number of cursors specified exceeds supported maximum\n")
0758                 ;
0759             }
0760         }
0761 
0762         OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
0763 
0764         if (j == 0)
0765             mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
0766         else
0767             mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
0768                                     || dst->use_maximum_vstartup;
0769 
0770         if (dst->odm_combine && !src->is_hsplit)
0771             dml_print(
0772                     "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
0773                     j);
0774 
0775         if (src->is_hsplit) {
0776             for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
0777                 display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
0778                 display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
0779 
0780                 if (src_k->is_hsplit && !visited[k]
0781                         && src->hsplit_grp == src_k->hsplit_grp) {
0782                     mode_lib->vba.pipe_plane[k] =
0783                             mode_lib->vba.NumberOfActivePlanes;
0784                     mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
0785                     if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
0786                             == dm_horz) {
0787                         mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
0788                                 src_k->viewport_width;
0789                         mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
0790                                 src_k->viewport_width_c;
0791                         mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
0792                                 dst_k->recout_width;
0793                     } else {
0794                         mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
0795                                 src_k->viewport_height;
0796                         mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
0797                                 src_k->viewport_height_c;
0798                     }
0799 
0800                     visited[k] = true;
0801                 }
0802             }
0803         }
0804         if (src->viewport_width_max) {
0805             int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
0806             int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
0807 
0808             if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
0809                 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
0810             if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
0811                 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
0812             if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
0813                 mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
0814             if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
0815                 mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
0816         }
0817 
0818         if (pipes[j].pipe.src.immediate_flip) {
0819             mode_lib->vba.ImmediateFlipSupport = true;
0820             mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_required;
0821         }
0822 
0823         mode_lib->vba.NumberOfActivePlanes++;
0824         mode_lib->vba.NumberOfActiveSurfaces++;
0825     }
0826 
0827     // handle overlays through BlendingAndTiming
0828     // BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
0829 
0830     for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
0831         PlaneVisited[j] = false;
0832 
0833     for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
0834         for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
0835             if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
0836                 // doesn't matter, so choose the smaller one
0837                 mode_lib->vba.BlendingAndTiming[j] = j;
0838                 PlaneVisited[j] = true;
0839                 mode_lib->vba.BlendingAndTiming[k] = j;
0840                 PlaneVisited[k] = true;
0841             }
0842         }
0843 
0844         if (!PlaneVisited[j]) {
0845             mode_lib->vba.BlendingAndTiming[j] = j;
0846             PlaneVisited[j] = true;
0847         }
0848     }
0849 
0850     mode_lib->vba.SynchronizeTimingsFinal = pipes[0].pipe.dest.synchronize_timings;
0851     mode_lib->vba.DCCProgrammingAssumesScanDirectionUnknownFinal = false;
0852 
0853     mode_lib->vba.DisableUnboundRequestIfCompBufReservedSpaceNeedAdjustment = 0;
0854 
0855     mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting;
0856     for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
0857         if (pipes[k].pipe.src.unbounded_req_mode == 0)
0858             mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting_disable;
0859     }
0860     // TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
0861     // Do we want the dscclk to automatically be halved? Guess not since the value is specified
0862     mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
0863     for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
0864         ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
0865     }
0866 
0867     mode_lib->vba.GPUVMEnable = false;
0868     mode_lib->vba.HostVMEnable = false;
0869     mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
0870     mode_lib->vba.OverrideHostVMPageTableLevels = 0;
0871 
0872     for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
0873         mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
0874         mode_lib->vba.OverrideGPUVMPageTableLevels =
0875                 (pipes[k].pipe.src.gpuvm_levels_force_en
0876                         && mode_lib->vba.OverrideGPUVMPageTableLevels
0877                                 < pipes[k].pipe.src.gpuvm_levels_force) ?
0878                         pipes[k].pipe.src.gpuvm_levels_force :
0879                         mode_lib->vba.OverrideGPUVMPageTableLevels;
0880 
0881         mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
0882         mode_lib->vba.OverrideHostVMPageTableLevels =
0883                 (pipes[k].pipe.src.hostvm_levels_force_en
0884                         && mode_lib->vba.OverrideHostVMPageTableLevels
0885                                 < pipes[k].pipe.src.hostvm_levels_force) ?
0886                         pipes[k].pipe.src.hostvm_levels_force :
0887                         mode_lib->vba.OverrideHostVMPageTableLevels;
0888     }
0889 
0890     if (mode_lib->vba.OverrideGPUVMPageTableLevels)
0891         mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
0892 
0893     if (mode_lib->vba.OverrideHostVMPageTableLevels)
0894         mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
0895 
0896     mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
0897     mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
0898 
0899     for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
0900         mode_lib->vba.ForceOneRowForFrame[k] = pipes[k].pipe.src.force_one_row_for_frame;
0901         mode_lib->vba.PteBufferMode[k] = pipes[k].pipe.src.pte_buffer_mode;
0902 
0903         if (mode_lib->vba.PteBufferMode[k] == 0 && mode_lib->vba.GPUVMEnable) {
0904             if (mode_lib->vba.ForceOneRowForFrame[k] ||
0905                 (mode_lib->vba.GPUVMMinPageSizeKBytes[k] > 64*1024) ||
0906                 (mode_lib->vba.UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_disable) ||
0907                 (mode_lib->vba.UseMALLForStaticScreen[k] != dm_use_mall_static_screen_disable)) {
0908 #ifdef __DML_VBA_DEBUG__
0909                 dml_print("DML::%s: ERROR: Invalid PteBufferMode=%d for plane %0d!\n",
0910                         __func__, mode_lib->vba.PteBufferMode[k], k);
0911                 dml_print("DML::%s:  -  ForceOneRowForFrame     = %d\n",
0912                         __func__, mode_lib->vba.ForceOneRowForFrame[k]);
0913                 dml_print("DML::%s:  -  GPUVMMinPageSizeKBytes  = %d\n",
0914                         __func__, mode_lib->vba.GPUVMMinPageSizeKBytes[k]);
0915                 dml_print("DML::%s:  -  UseMALLForPStateChange  = %d\n",
0916                         __func__, (int) mode_lib->vba.UsesMALLForPStateChange[k]);
0917                 dml_print("DML::%s:  -  UseMALLForStaticScreen  = %d\n",
0918                         __func__, (int) mode_lib->vba.UseMALLForStaticScreen[k]);
0919 #endif
0920                 ASSERT(0);
0921             }
0922         }
0923     }
0924 }
0925 
0926 /**
0927  * ********************************************************************************************
0928  * cache_debug_params: Cache any params that needed to be maintained from the initial validation
0929  * for debug purposes.
0930  *
0931  * The DML getters can modify some of the VBA params that we are interested in (for example when
0932  * calculating with dummy p-state latency), so cache any params here that we want for debugging
0933  *
0934  * @param [in] mode_lib: mode_lib input/output of validate call
0935  *
0936  * @return: void
0937  *
0938  * ********************************************************************************************
0939  */
0940 static void cache_debug_params(struct display_mode_lib *mode_lib)
0941 {
0942     int k = 0;
0943 
0944     for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
0945         mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
0946 }
0947 
0948 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
0949 // rather than working them out as in recalculate_ms
0950 static void recalculate_params(
0951         struct display_mode_lib *mode_lib,
0952         const display_e2e_pipe_params_st *pipes,
0953         unsigned int num_pipes)
0954 {
0955     // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
0956     if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
0957             || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
0958             || num_pipes != mode_lib->vba.cache_num_pipes
0959             || memcmp(
0960                     pipes,
0961                     mode_lib->vba.cache_pipes,
0962                     sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
0963         mode_lib->vba.soc = mode_lib->soc;
0964         mode_lib->vba.ip = mode_lib->ip;
0965         memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
0966         mode_lib->vba.cache_num_pipes = num_pipes;
0967         mode_lib->funcs.recalculate(mode_lib);
0968     }
0969 }
0970 
0971 void Calculate256BBlockSizes(
0972         enum source_format_class SourcePixelFormat,
0973         enum dm_swizzle_mode SurfaceTiling,
0974         unsigned int BytePerPixelY,
0975         unsigned int BytePerPixelC,
0976         unsigned int *BlockHeight256BytesY,
0977         unsigned int *BlockHeight256BytesC,
0978         unsigned int *BlockWidth256BytesY,
0979         unsigned int *BlockWidth256BytesC)
0980 {
0981     if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
0982             || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
0983         if (SurfaceTiling == dm_sw_linear) {
0984             *BlockHeight256BytesY = 1;
0985         } else if (SourcePixelFormat == dm_444_64) {
0986             *BlockHeight256BytesY = 4;
0987         } else if (SourcePixelFormat == dm_444_8) {
0988             *BlockHeight256BytesY = 16;
0989         } else {
0990             *BlockHeight256BytesY = 8;
0991         }
0992         *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
0993         *BlockHeight256BytesC = 0;
0994         *BlockWidth256BytesC = 0;
0995     } else {
0996         if (SurfaceTiling == dm_sw_linear) {
0997             *BlockHeight256BytesY = 1;
0998             *BlockHeight256BytesC = 1;
0999         } else if (SourcePixelFormat == dm_420_8) {
1000             *BlockHeight256BytesY = 16;
1001             *BlockHeight256BytesC = 8;
1002         } else {
1003             *BlockHeight256BytesY = 8;
1004             *BlockHeight256BytesC = 8;
1005         }
1006         *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
1007         *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
1008     }
1009 }
1010 
1011 bool CalculateMinAndMaxPrefetchMode(
1012         enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
1013         unsigned int *MinPrefetchMode,
1014         unsigned int *MaxPrefetchMode)
1015 {
1016     if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1017             == dm_neither_self_refresh_nor_mclk_switch) {
1018         *MinPrefetchMode = 2;
1019         *MaxPrefetchMode = 2;
1020         return false;
1021     } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
1022         *MinPrefetchMode = 1;
1023         *MaxPrefetchMode = 1;
1024         return false;
1025     } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1026             == dm_allow_self_refresh_and_mclk_switch) {
1027         *MinPrefetchMode = 0;
1028         *MaxPrefetchMode = 0;
1029         return false;
1030     } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
1031             == dm_try_to_allow_self_refresh_and_mclk_switch) {
1032         *MinPrefetchMode = 0;
1033         *MaxPrefetchMode = 2;
1034         return false;
1035     }
1036     *MinPrefetchMode = 0;
1037     *MaxPrefetchMode = 2;
1038     return true;
1039 }
1040 
1041 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
1042 {
1043     unsigned int k;
1044 
1045     //Progressive To Interlace Unit Effect
1046     for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1047         mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
1048         if (mode_lib->vba.Interlace[k] == 1
1049                 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
1050             mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
1051         }
1052     }
1053 }
1054 
1055 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
1056 {
1057     switch (ebpp) {
1058     case dm_cur_2bit:
1059         return 2;
1060     case dm_cur_32bit:
1061         return 32;
1062     case dm_cur_64bit:
1063         return 64;
1064     default:
1065         return 0;
1066     }
1067 }
1068 
1069 void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
1070 {
1071     soc_bounding_box_st *soc = &mode_lib->vba.soc;
1072     unsigned int k;
1073     unsigned int total_pipes = 0;
1074     unsigned int pipe_idx = 0;
1075 
1076     mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
1077     mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
1078     if (mode_lib->vba.ReturnBW == 0)
1079         mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
1080     mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
1081 
1082     fetch_socbb_params(mode_lib);
1083     fetch_ip_params(mode_lib);
1084     fetch_pipe_params(mode_lib);
1085 
1086     mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
1087     mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
1088     if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
1089         mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
1090     else
1091         mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
1092 
1093     // Total Available Pipes Support Check
1094     for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1095         total_pipes += mode_lib->vba.DPPPerPlane[k];
1096         pipe_idx = get_pipe_idx(mode_lib, k);
1097         if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0)
1098             mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz;
1099         else
1100             mode_lib->vba.DPPCLK[k] = soc->clock_limits[mode_lib->vba.VoltageLevel].dppclk_mhz;
1101     }
1102     ASSERT(total_pipes <= DC__NUM_DPP__MAX);
1103 }
1104 
1105 double CalculateWriteBackDISPCLK(
1106         enum source_format_class WritebackPixelFormat,
1107         double PixelClock,
1108         double WritebackHRatio,
1109         double WritebackVRatio,
1110         unsigned int WritebackLumaHTaps,
1111         unsigned int WritebackLumaVTaps,
1112         unsigned int WritebackChromaHTaps,
1113         unsigned int WritebackChromaVTaps,
1114         double WritebackDestinationWidth,
1115         unsigned int HTotal,
1116         unsigned int WritebackChromaLineBufferWidth)
1117 {
1118     double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
1119         dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
1120         dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
1121             + dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
1122             * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
1123             dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
1124     if (WritebackPixelFormat != dm_444_32) {
1125         CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
1126             dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
1127             dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
1128                 + dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
1129                 + dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
1130                 dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
1131     }
1132     return CalculateWriteBackDISPCLK;
1133 }
1134