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