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