2 * Copyright 2017 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
27 #include "display_mode_lib.h"
28 #include "display_mode_vba.h"
29 #include "dml_inline_defs.h"
33 * This file is gcc-parsable HW gospel, coming straight from HW engineers.
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.
41 static void fetch_socbb_params(struct display_mode_lib *mode_lib);
42 static void fetch_ip_params(struct display_mode_lib *mode_lib);
43 static void fetch_pipe_params(struct display_mode_lib *mode_lib);
44 static void recalculate_params(
45 struct display_mode_lib *mode_lib,
46 const display_e2e_pipe_params_st *pipes,
47 unsigned int num_pipes);
49 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
51 unsigned 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)
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;
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;
67 if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
68 mode_lib->funcs.recalculate(mode_lib);
70 fetch_socbb_params(mode_lib);
71 fetch_ip_params(mode_lib);
72 fetch_pipe_params(mode_lib);
73 PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
75 mode_lib->funcs.validate(mode_lib);
77 return mode_lib->vba.VoltageLevel;
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) \
82 recalculate_params(mode_lib, pipes, num_pipes); \
86 dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFCLKDeepSleep);
87 dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
88 dml_get_attr_func(wm_memory_trip, mode_lib->vba.UrgentLatency);
89 dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
90 dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
91 dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
92 dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
93 dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
94 dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
95 dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
96 dml_get_attr_func(stutter_period, mode_lib->vba.StutterPeriod);
97 dml_get_attr_func(urgent_latency, mode_lib->vba.UrgentLatency);
98 dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
99 dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
100 dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
101 dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
102 dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
103 dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
104 dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
105 dml_get_attr_func(fraction_of_urgent_bandwidth, mode_lib->vba.FractionOfUrgentBandwidth);
106 dml_get_attr_func(fraction_of_urgent_bandwidth_imm_flip, mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip);
108 #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) \
110 unsigned int which_plane; \
111 recalculate_params(mode_lib, pipes, num_pipes); \
112 which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
113 return var[which_plane]; \
116 dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
117 dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
118 dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
119 dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
120 dml_get_pipe_attr_func(min_ttu_vblank_in_us, mode_lib->vba.MinTTUVBlank);
121 dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
122 dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
123 dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
124 dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
125 dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
126 dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
127 dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
128 dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
129 dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
130 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank, mode_lib->vba.TimePerVMGroupVBlank);
131 dml_get_pipe_attr_func(refcyc_per_vm_group_flip, mode_lib->vba.TimePerVMGroupFlip);
132 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank, mode_lib->vba.TimePerVMRequestVBlank);
133 dml_get_pipe_attr_func(refcyc_per_vm_req_flip, mode_lib->vba.TimePerVMRequestFlip);
134 dml_get_pipe_attr_func(refcyc_per_vm_group_vblank_in_us, mode_lib->vba.TimePerVMGroupVBlank);
135 dml_get_pipe_attr_func(refcyc_per_vm_group_flip_in_us, mode_lib->vba.TimePerVMGroupFlip);
136 dml_get_pipe_attr_func(refcyc_per_vm_req_vblank_in_us, mode_lib->vba.TimePerVMRequestVBlank);
137 dml_get_pipe_attr_func(refcyc_per_vm_req_flip_in_us, mode_lib->vba.TimePerVMRequestFlip);
138 dml_get_pipe_attr_func(refcyc_per_vm_dmdata_in_us, mode_lib->vba.Tdmdl_vm);
139 dml_get_pipe_attr_func(dmdata_dl_delta_in_us, mode_lib->vba.Tdmdl);
140 dml_get_pipe_attr_func(refcyc_per_line_delivery_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLuma);
141 dml_get_pipe_attr_func(refcyc_per_line_delivery_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChroma);
142 dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch);
143 dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch);
144 dml_get_pipe_attr_func(refcyc_per_req_delivery_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLuma);
145 dml_get_pipe_attr_func(refcyc_per_req_delivery_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChroma);
146 dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLumaPrefetch);
147 dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChromaPrefetch);
148 dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_in_us, mode_lib->vba.CursorRequestDeliveryTime);
149 dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_pre_in_us, mode_lib->vba.CursorRequestDeliveryTimePrefetch);
150 dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_l_in_us, mode_lib->vba.TimePerMetaChunkNominal);
151 dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_c_in_us, mode_lib->vba.TimePerChromaMetaChunkNominal);
152 dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_l_in_us, mode_lib->vba.TimePerMetaChunkVBlank);
153 dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_c_in_us, mode_lib->vba.TimePerChromaMetaChunkVBlank);
154 dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_l_in_us, mode_lib->vba.TimePerMetaChunkFlip);
155 dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_c_in_us, mode_lib->vba.TimePerChromaMetaChunkFlip);
157 dml_get_pipe_attr_func(vstartup, mode_lib->vba.VStartup);
158 dml_get_pipe_attr_func(vupdate_offset, mode_lib->vba.VUpdateOffsetPix);
159 dml_get_pipe_attr_func(vupdate_width, mode_lib->vba.VUpdateWidthPix);
160 dml_get_pipe_attr_func(vready_offset, mode_lib->vba.VReadyOffsetPix);
162 double get_total_immediate_flip_bytes(
163 struct display_mode_lib *mode_lib,
164 const display_e2e_pipe_params_st *pipes,
165 unsigned int num_pipes)
167 recalculate_params(mode_lib, pipes, num_pipes);
168 return mode_lib->vba.TotImmediateFlipBytes;
171 double get_total_immediate_flip_bw(
172 struct display_mode_lib *mode_lib,
173 const display_e2e_pipe_params_st *pipes,
174 unsigned int num_pipes)
177 double immediate_flip_bw = 0.0;
178 recalculate_params(mode_lib, pipes, num_pipes);
179 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
180 immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k];
181 return immediate_flip_bw;
184 double get_total_prefetch_bw(
185 struct display_mode_lib *mode_lib,
186 const display_e2e_pipe_params_st *pipes,
187 unsigned int num_pipes)
190 double total_prefetch_bw = 0.0;
192 recalculate_params(mode_lib, pipes, num_pipes);
193 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
194 total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
195 return total_prefetch_bw;
198 static void fetch_socbb_params(struct display_mode_lib *mode_lib)
200 soc_bounding_box_st *soc = &mode_lib->vba.soc;
203 // SOC Bounding Box Parameters
204 mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
205 mode_lib->vba.NumberOfChannels = soc->num_chans;
206 mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly =
207 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!
208 mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData =
209 soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
210 mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly =
211 soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only;
212 mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation =
213 soc->max_avg_sdp_bw_use_normal_percent;
214 mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation =
215 soc->max_avg_dram_bw_use_normal_percent;
216 mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us;
217 mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us;
218 mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us;
219 mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
220 mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly =
221 soc->urgent_out_of_order_return_per_channel_pixel_only_bytes;
222 mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData =
223 soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
224 mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly =
225 soc->urgent_out_of_order_return_per_channel_vm_only_bytes;
226 mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
227 mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
228 mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
229 mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
230 mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
231 mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
232 mode_lib->vba.DummyPStateCheck;
233 mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive;
235 mode_lib->vba.Downspreading = soc->downspread_percent;
236 mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new!
237 mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
238 mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new
239 mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new
240 mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
241 mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024;
242 mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024;
243 // Set the voltage scaling clocks as the defaults. Most of these will
244 // be set to different values by the test
245 for (i = 0; i < mode_lib->vba.soc.num_states; i++)
246 if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
249 mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
250 mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
251 mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts;
252 mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
254 mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
255 mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
256 mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw;
258 mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
259 mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
260 mode_lib->vba.MaxHSCLRatio = 4;
261 mode_lib->vba.MaxVSCLRatio = 4;
262 mode_lib->vba.Cursor64BppSupport = true;
263 for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
264 mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
265 mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
266 mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
267 mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
268 mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz;
269 mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
270 mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
271 mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts;
272 //mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
273 mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
274 mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz;
277 mode_lib->vba.DoUrgentLatencyAdjustment =
278 soc->do_urgent_latency_adjustment;
279 mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent =
280 soc->urgent_latency_adjustment_fabric_clock_component_us;
281 mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
282 soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
285 static void fetch_ip_params(struct display_mode_lib *mode_lib)
287 ip_params_st *ip = &mode_lib->vba.ip;
290 mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
291 mode_lib->vba.ClampMinDCFCLK = ip->clamp_min_dcfclk;
292 mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
293 mode_lib->vba.MaxNumOTG = ip->max_num_otg;
294 mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
295 mode_lib->vba.MaxNumWriteback = ip->max_num_wb;
296 mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
297 mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
299 mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
300 mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
301 mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
302 mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
304 mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
305 mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
306 mode_lib->vba.MinMetaChunkSizeBytes = ip->min_meta_chunk_size_bytes;
307 mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
308 mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
309 mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
310 mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma;
311 mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma;
312 mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
313 mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
314 mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio;
315 mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio;
316 mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024;
317 mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024;
319 mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes;
320 mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size;
322 mode_lib->vba.WritebackChromaLineBufferWidth =
323 ip->writeback_chroma_line_buffer_width_pixels;
324 mode_lib->vba.WritebackLineBufferLumaBufferSize =
325 ip->writeback_line_buffer_luma_buffer_size;
326 mode_lib->vba.WritebackLineBufferChromaBufferSize =
327 ip->writeback_line_buffer_chroma_buffer_size;
328 mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported;
329 mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio;
330 mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio;
331 mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio;
332 mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio;
333 mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps;
334 mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps;
335 mode_lib->vba.WritebackConfiguration = dm_normal;
336 mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels;
337 mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels;
338 mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels;
339 mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels;
340 mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
341 mode_lib->vba.NumberOfDSC = ip->num_dsc;
342 mode_lib->vba.ODMCapability = ip->odm_capable;
343 mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
345 mode_lib->vba.XFCSupported = ip->xfc_supported;
346 mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
347 mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
348 mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
349 mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
350 mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
351 mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
352 mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
353 mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
354 mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled;
355 mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported;
356 mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
357 mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
358 mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes;
359 mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported;
362 static void fetch_pipe_params(struct display_mode_lib *mode_lib)
364 display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
365 ip_params_st *ip = &mode_lib->vba.ip;
367 unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
369 bool PlaneVisited[DC__NUM_DPP__MAX];
370 bool visited[DC__NUM_DPP__MAX];
372 // Convert Pipes to Planes
373 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
376 mode_lib->vba.NumberOfActivePlanes = 0;
377 mode_lib->vba.ImmediateFlipSupport = false;
378 mode_lib->vba.ImmediateFlipRequirement = dm_immediate_flip_not_required;
379 for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
380 display_pipe_source_params_st *src = &pipes[j].pipe.src;
381 display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
382 scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
383 scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
384 display_output_params_st *dout = &pipes[j].dout;
385 display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
391 mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
393 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
394 mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
395 (enum scan_direction_class) (src->source_scan);
396 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
398 mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] =
399 src->viewport_width_c;
400 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
401 src->viewport_height;
402 mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] =
403 src->viewport_height_c;
404 mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
406 mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
408 mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
409 mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_y;
410 mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_y;
411 mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
412 mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_c;
413 mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_c;
414 mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
415 mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c;
416 mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
417 mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c;
418 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
419 mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c;
420 mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
421 mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
422 if (dst->interlaced && !ip->ptoi_supported) {
423 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
424 mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
426 mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
427 mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
428 mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
429 mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
430 mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
431 mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
432 mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
433 src->dcc_use_global ?
434 ip->dcc_supported : src->dcc && ip->dcc_supported;
435 mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
436 /* TODO: Needs to be set based on src->dcc_rate_luma/chroma */
437 mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
438 mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma;
439 mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format);
440 mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
441 mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
442 mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
443 (enum dm_swizzle_mode) (src->sw_mode);
444 mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
445 dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
446 mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
448 mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
449 (enum output_format_class) (dout->output_format);
450 mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
452 mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
453 (enum output_encoder_class) (dout->output_type);
454 mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
457 if (!dout->dsc_enable)
458 mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
460 mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
462 mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
464 /* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
465 mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] =
466 dout->max_audio_sample_rate;
467 mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] =
469 mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0;
470 mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
471 mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
472 mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
474 if (!dout->dsc_input_bpc) {
475 mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
476 ip->maximum_dsc_bits_per_component;
478 mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
481 mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
482 mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
484 mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
485 dout->wb.wb_src_height;
486 mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] =
487 dout->wb.wb_src_width;
488 mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
489 dout->wb.wb_dst_width;
490 mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
491 dout->wb.wb_dst_height;
492 mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
494 mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
496 mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
497 (enum source_format_class) (dout->wb.wb_pixel_format);
498 mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] =
499 dout->wb.wb_htaps_luma;
500 mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] =
501 dout->wb.wb_vtaps_luma;
502 mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
503 dout->wb.wb_htaps_luma;
504 mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
505 dout->wb.wb_vtaps_luma;
506 mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
507 dout->wb.wb_htaps_chroma;
508 mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
509 dout->wb.wb_vtaps_chroma;
510 mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
512 mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
515 mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
516 src->dynamic_metadata_enable;
517 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
518 src->dynamic_metadata_lines_before_active;
519 mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
520 src->dynamic_metadata_xmit_bytes;
522 mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
523 && ip->xfc_supported;
524 mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
525 mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
526 mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
527 mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
528 mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
529 mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
530 mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
531 if (ip->is_line_buffer_bpp_fixed)
532 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
533 ip->line_buffer_fixed_bpp;
535 unsigned int lb_depth;
537 switch (scl->lb_depth) {
559 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
561 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
562 // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
563 // calculate things a little more accurately
564 for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
567 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
569 (enum cursor_bpp) (src->cur0_bpp));
570 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
572 if (src->cur0_src_width > 0)
573 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
576 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
578 (enum cursor_bpp) (src->cur1_bpp));
579 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
581 if (src->cur1_src_width > 0)
582 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
586 "ERROR: Number of cursors specified exceeds supported maximum\n")
591 OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
594 mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup;
596 mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup
597 || dst->use_maximum_vstartup;
599 if (dst->odm_combine && !src->is_hsplit)
601 "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
604 if (src->is_hsplit) {
605 for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
606 display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
607 display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
609 if (src_k->is_hsplit && !visited[k]
610 && src->hsplit_grp == src_k->hsplit_grp) {
611 mode_lib->vba.pipe_plane[k] =
612 mode_lib->vba.NumberOfActivePlanes;
613 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
614 if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
616 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
617 src_k->viewport_width;
618 mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] +=
619 src_k->viewport_width_c;
620 mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
623 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
624 src_k->viewport_height;
625 mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] +=
626 src_k->viewport_height_c;
634 if (pipes[k].pipe.src.immediate_flip) {
635 mode_lib->vba.ImmediateFlipSupport = true;
636 mode_lib->vba.ImmediateFlipRequirement = dm_immediate_flip_required;
639 mode_lib->vba.NumberOfActivePlanes++;
642 // handle overlays through BlendingAndTiming
643 // BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
645 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
646 PlaneVisited[j] = false;
648 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
649 for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
650 if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
651 // doesn't matter, so choose the smaller one
652 mode_lib->vba.BlendingAndTiming[j] = j;
653 PlaneVisited[j] = true;
654 mode_lib->vba.BlendingAndTiming[k] = j;
655 PlaneVisited[k] = true;
659 if (!PlaneVisited[j]) {
660 mode_lib->vba.BlendingAndTiming[j] = j;
661 PlaneVisited[j] = true;
665 // TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
666 // Do we want the dscclk to automatically be halved? Guess not since the value is specified
667 mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
668 for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
669 ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
672 mode_lib->vba.GPUVMEnable = false;
673 mode_lib->vba.HostVMEnable = false;
674 mode_lib->vba.OverrideGPUVMPageTableLevels = 0;
675 mode_lib->vba.OverrideHostVMPageTableLevels = 0;
677 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
678 mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm;
679 mode_lib->vba.OverrideGPUVMPageTableLevels =
680 (pipes[k].pipe.src.gpuvm_levels_force_en
681 && mode_lib->vba.OverrideGPUVMPageTableLevels
682 < pipes[k].pipe.src.gpuvm_levels_force) ?
683 pipes[k].pipe.src.gpuvm_levels_force :
684 mode_lib->vba.OverrideGPUVMPageTableLevels;
686 mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm;
687 mode_lib->vba.OverrideHostVMPageTableLevels =
688 (pipes[k].pipe.src.hostvm_levels_force_en
689 && mode_lib->vba.OverrideHostVMPageTableLevels
690 < pipes[k].pipe.src.hostvm_levels_force) ?
691 pipes[k].pipe.src.hostvm_levels_force :
692 mode_lib->vba.OverrideHostVMPageTableLevels;
695 mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank = dm_try_to_allow_self_refresh_and_mclk_switch;
697 if (mode_lib->vba.OverrideGPUVMPageTableLevels)
698 mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels;
700 if (mode_lib->vba.OverrideHostVMPageTableLevels)
701 mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels;
703 mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable;
704 mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
707 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
708 // rather than working them out as in recalculate_ms
709 static void recalculate_params(
710 struct display_mode_lib *mode_lib,
711 const display_e2e_pipe_params_st *pipes,
712 unsigned int num_pipes)
714 // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
715 if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
716 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
717 || num_pipes != mode_lib->vba.cache_num_pipes
720 mode_lib->vba.cache_pipes,
721 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
722 mode_lib->vba.soc = mode_lib->soc;
723 mode_lib->vba.ip = mode_lib->ip;
724 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
725 mode_lib->vba.cache_num_pipes = num_pipes;
726 mode_lib->funcs.recalculate(mode_lib);
730 bool Calculate256BBlockSizes(
731 enum source_format_class SourcePixelFormat,
732 enum dm_swizzle_mode SurfaceTiling,
733 unsigned int BytePerPixelY,
734 unsigned int BytePerPixelC,
735 unsigned int *BlockHeight256BytesY,
736 unsigned int *BlockHeight256BytesC,
737 unsigned int *BlockWidth256BytesY,
738 unsigned int *BlockWidth256BytesC)
740 if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
741 || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) {
742 if (SurfaceTiling == dm_sw_linear) {
743 *BlockHeight256BytesY = 1;
744 } else if (SourcePixelFormat == dm_444_64) {
745 *BlockHeight256BytesY = 4;
746 } else if (SourcePixelFormat == dm_444_8) {
747 *BlockHeight256BytesY = 16;
749 *BlockHeight256BytesY = 8;
751 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
752 *BlockHeight256BytesC = 0;
753 *BlockWidth256BytesC = 0;
755 if (SurfaceTiling == dm_sw_linear) {
756 *BlockHeight256BytesY = 1;
757 *BlockHeight256BytesC = 1;
758 } else if (SourcePixelFormat == dm_420_8) {
759 *BlockHeight256BytesY = 16;
760 *BlockHeight256BytesC = 8;
762 *BlockHeight256BytesY = 8;
763 *BlockHeight256BytesC = 8;
765 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
766 *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
771 bool CalculateMinAndMaxPrefetchMode(
772 enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
773 unsigned int *MinPrefetchMode,
774 unsigned int *MaxPrefetchMode)
776 if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
777 == dm_neither_self_refresh_nor_mclk_switch) {
778 *MinPrefetchMode = 2;
779 *MaxPrefetchMode = 2;
781 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) {
782 *MinPrefetchMode = 1;
783 *MaxPrefetchMode = 1;
785 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
786 == dm_allow_self_refresh_and_mclk_switch) {
787 *MinPrefetchMode = 0;
788 *MaxPrefetchMode = 0;
790 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
791 == dm_try_to_allow_self_refresh_and_mclk_switch) {
792 *MinPrefetchMode = 0;
793 *MaxPrefetchMode = 2;
796 *MinPrefetchMode = 0;
797 *MaxPrefetchMode = 2;
801 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
805 //Progressive To Interlace Unit Effect
806 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
807 if (mode_lib->vba.Interlace[k] == 1
808 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
809 mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClockBackEnd[k];
814 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
828 void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
830 soc_bounding_box_st *soc = &mode_lib->vba.soc;
832 unsigned int total_pipes = 0;
834 mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
835 mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb];
836 if (mode_lib->vba.ReturnBW == 0)
837 mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
838 mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
840 fetch_socbb_params(mode_lib);
841 fetch_ip_params(mode_lib);
842 fetch_pipe_params(mode_lib);
844 mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
845 mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
846 if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
847 mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
849 mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
851 // Total Available Pipes Support Check
852 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
853 total_pipes += mode_lib->vba.DPPPerPlane[k];
854 ASSERT(total_pipes <= DC__NUM_DPP__MAX);
857 double CalculateWriteBackDISPCLK(
858 enum source_format_class WritebackPixelFormat,
860 double WritebackHRatio,
861 double WritebackVRatio,
862 unsigned int WritebackLumaHTaps,
863 unsigned int WritebackLumaVTaps,
864 unsigned int WritebackChromaHTaps,
865 unsigned int WritebackChromaVTaps,
866 double WritebackDestinationWidth,
868 unsigned int WritebackChromaLineBufferWidth)
870 double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max(
871 dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
872 dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1)
873 + dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1)
874 * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal,
875 dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal));
876 if (WritebackPixelFormat != dm_444_32) {
877 CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max(
878 dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio),
879 dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1)
880 + dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal
881 + dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal,
882 dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal)));
884 return CalculateWriteBackDISPCLK;