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
);
455 if (!dout
->dsc_enable
)
456 mode_lib
->vba
.ForcedOutputLinkBPP
[mode_lib
->vba
.NumberOfActivePlanes
] = dout
->output_bpp
;
458 mode_lib
->vba
.ForcedOutputLinkBPP
[mode_lib
->vba
.NumberOfActivePlanes
] = 0.0;
460 mode_lib
->vba
.OutputLinkDPLanes
[mode_lib
->vba
.NumberOfActivePlanes
] =
462 /* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */
463 mode_lib
->vba
.AudioSampleRate
[mode_lib
->vba
.NumberOfActivePlanes
] =
464 dout
->max_audio_sample_rate
;
465 mode_lib
->vba
.AudioSampleLayout
[mode_lib
->vba
.NumberOfActivePlanes
] =
467 mode_lib
->vba
.DRAMClockChangeLatencyOverride
= 0.0;
468 mode_lib
->vba
.DSCEnabled
[mode_lib
->vba
.NumberOfActivePlanes
] = dout
->dsc_enable
;
469 mode_lib
->vba
.DSCEnable
[mode_lib
->vba
.NumberOfActivePlanes
] = dout
->dsc_enable
;
470 mode_lib
->vba
.NumberOfDSCSlices
[mode_lib
->vba
.NumberOfActivePlanes
] =
472 mode_lib
->vba
.DSCInputBitPerComponent
[mode_lib
->vba
.NumberOfActivePlanes
] = dout
->output_bpc
;
473 mode_lib
->vba
.WritebackEnable
[mode_lib
->vba
.NumberOfActivePlanes
] = dout
->wb_enable
;
474 mode_lib
->vba
.ActiveWritebacksPerPlane
[mode_lib
->vba
.NumberOfActivePlanes
] =
476 mode_lib
->vba
.WritebackSourceHeight
[mode_lib
->vba
.NumberOfActivePlanes
] =
477 dout
->wb
.wb_src_height
;
478 mode_lib
->vba
.WritebackSourceWidth
[mode_lib
->vba
.NumberOfActivePlanes
] =
479 dout
->wb
.wb_src_width
;
480 mode_lib
->vba
.WritebackDestinationWidth
[mode_lib
->vba
.NumberOfActivePlanes
] =
481 dout
->wb
.wb_dst_width
;
482 mode_lib
->vba
.WritebackDestinationHeight
[mode_lib
->vba
.NumberOfActivePlanes
] =
483 dout
->wb
.wb_dst_height
;
484 mode_lib
->vba
.WritebackHRatio
[mode_lib
->vba
.NumberOfActivePlanes
] =
486 mode_lib
->vba
.WritebackVRatio
[mode_lib
->vba
.NumberOfActivePlanes
] =
488 mode_lib
->vba
.WritebackPixelFormat
[mode_lib
->vba
.NumberOfActivePlanes
] =
489 (enum source_format_class
) (dout
->wb
.wb_pixel_format
);
490 mode_lib
->vba
.WritebackHTaps
[mode_lib
->vba
.NumberOfActivePlanes
] =
491 dout
->wb
.wb_htaps_luma
;
492 mode_lib
->vba
.WritebackVTaps
[mode_lib
->vba
.NumberOfActivePlanes
] =
493 dout
->wb
.wb_vtaps_luma
;
494 mode_lib
->vba
.WritebackLumaHTaps
[mode_lib
->vba
.NumberOfActivePlanes
] =
495 dout
->wb
.wb_htaps_luma
;
496 mode_lib
->vba
.WritebackLumaVTaps
[mode_lib
->vba
.NumberOfActivePlanes
] =
497 dout
->wb
.wb_vtaps_luma
;
498 mode_lib
->vba
.WritebackChromaHTaps
[mode_lib
->vba
.NumberOfActivePlanes
] =
499 dout
->wb
.wb_htaps_chroma
;
500 mode_lib
->vba
.WritebackChromaVTaps
[mode_lib
->vba
.NumberOfActivePlanes
] =
501 dout
->wb
.wb_vtaps_chroma
;
502 mode_lib
->vba
.WritebackHRatio
[mode_lib
->vba
.NumberOfActivePlanes
] =
504 mode_lib
->vba
.WritebackVRatio
[mode_lib
->vba
.NumberOfActivePlanes
] =
507 mode_lib
->vba
.DynamicMetadataEnable
[mode_lib
->vba
.NumberOfActivePlanes
] =
508 src
->dynamic_metadata_enable
;
509 mode_lib
->vba
.DynamicMetadataLinesBeforeActiveRequired
[mode_lib
->vba
.NumberOfActivePlanes
] =
510 src
->dynamic_metadata_lines_before_active
;
511 mode_lib
->vba
.DynamicMetadataTransmittedBytes
[mode_lib
->vba
.NumberOfActivePlanes
] =
512 src
->dynamic_metadata_xmit_bytes
;
514 mode_lib
->vba
.XFCEnabled
[mode_lib
->vba
.NumberOfActivePlanes
] = src
->xfc_enable
515 && ip
->xfc_supported
;
516 mode_lib
->vba
.XFCSlvChunkSize
= src
->xfc_params
.xfc_slv_chunk_size_bytes
;
517 mode_lib
->vba
.XFCTSlvVupdateOffset
= src
->xfc_params
.xfc_tslv_vupdate_offset_us
;
518 mode_lib
->vba
.XFCTSlvVupdateWidth
= src
->xfc_params
.xfc_tslv_vupdate_width_us
;
519 mode_lib
->vba
.XFCTSlvVreadyOffset
= src
->xfc_params
.xfc_tslv_vready_offset_us
;
520 mode_lib
->vba
.PixelClock
[mode_lib
->vba
.NumberOfActivePlanes
] = dst
->pixel_rate_mhz
;
521 mode_lib
->vba
.PixelClockBackEnd
[mode_lib
->vba
.NumberOfActivePlanes
] = dst
->pixel_rate_mhz
;
522 mode_lib
->vba
.DPPCLK
[mode_lib
->vba
.NumberOfActivePlanes
] = clks
->dppclk_mhz
;
523 if (ip
->is_line_buffer_bpp_fixed
)
524 mode_lib
->vba
.LBBitPerPixel
[mode_lib
->vba
.NumberOfActivePlanes
] =
525 ip
->line_buffer_fixed_bpp
;
527 unsigned int lb_depth
;
529 switch (scl
->lb_depth
) {
551 mode_lib
->vba
.LBBitPerPixel
[mode_lib
->vba
.NumberOfActivePlanes
] = lb_depth
;
553 mode_lib
->vba
.NumberOfCursors
[mode_lib
->vba
.NumberOfActivePlanes
] = 0;
554 // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
555 // calculate things a little more accurately
556 for (k
= 0; k
< DC__NUM_CURSOR__MAX
; ++k
) {
559 mode_lib
->vba
.CursorBPP
[mode_lib
->vba
.NumberOfActivePlanes
][0] =
561 (enum cursor_bpp
) (src
->cur0_bpp
));
562 mode_lib
->vba
.CursorWidth
[mode_lib
->vba
.NumberOfActivePlanes
][0] =
564 if (src
->cur0_src_width
> 0)
565 mode_lib
->vba
.NumberOfCursors
[mode_lib
->vba
.NumberOfActivePlanes
]++;
568 mode_lib
->vba
.CursorBPP
[mode_lib
->vba
.NumberOfActivePlanes
][1] =
570 (enum cursor_bpp
) (src
->cur1_bpp
));
571 mode_lib
->vba
.CursorWidth
[mode_lib
->vba
.NumberOfActivePlanes
][1] =
573 if (src
->cur1_src_width
> 0)
574 mode_lib
->vba
.NumberOfCursors
[mode_lib
->vba
.NumberOfActivePlanes
]++;
578 "ERROR: Number of cursors specified exceeds supported maximum\n")
583 OTGInstPlane
[mode_lib
->vba
.NumberOfActivePlanes
] = dst
->otg_inst
;
586 mode_lib
->vba
.UseMaximumVStartup
= dst
->use_maximum_vstartup
;
588 mode_lib
->vba
.UseMaximumVStartup
= mode_lib
->vba
.UseMaximumVStartup
589 || dst
->use_maximum_vstartup
;
591 if (dst
->odm_combine
&& !src
->is_hsplit
)
593 "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
596 if (src
->is_hsplit
) {
597 for (k
= j
+ 1; k
< mode_lib
->vba
.cache_num_pipes
; ++k
) {
598 display_pipe_source_params_st
*src_k
= &pipes
[k
].pipe
.src
;
599 display_pipe_dest_params_st
*dst_k
= &pipes
[k
].pipe
.dest
;
600 display_output_params_st
*dout_k
= &pipes
[j
].dout
;
602 if (src_k
->is_hsplit
&& !visited
[k
]
603 && src
->hsplit_grp
== src_k
->hsplit_grp
) {
604 mode_lib
->vba
.pipe_plane
[k
] =
605 mode_lib
->vba
.NumberOfActivePlanes
;
606 mode_lib
->vba
.DPPPerPlane
[mode_lib
->vba
.NumberOfActivePlanes
]++;
607 if (mode_lib
->vba
.SourceScan
[mode_lib
->vba
.NumberOfActivePlanes
]
609 mode_lib
->vba
.ViewportWidth
[mode_lib
->vba
.NumberOfActivePlanes
] +=
610 src_k
->viewport_width
;
611 mode_lib
->vba
.ViewportWidthChroma
[mode_lib
->vba
.NumberOfActivePlanes
] +=
612 src_k
->viewport_width_c
;
613 mode_lib
->vba
.ScalerRecoutWidth
[mode_lib
->vba
.NumberOfActivePlanes
] +=
616 mode_lib
->vba
.ViewportHeight
[mode_lib
->vba
.NumberOfActivePlanes
] +=
617 src_k
->viewport_height
;
618 mode_lib
->vba
.ViewportHeightChroma
[mode_lib
->vba
.NumberOfActivePlanes
] +=
619 src_k
->viewport_height_c
;
621 mode_lib
->vba
.NumberOfDSCSlices
[mode_lib
->vba
.NumberOfActivePlanes
] +=
629 if (pipes
[k
].pipe
.src
.immediate_flip
) {
630 mode_lib
->vba
.ImmediateFlipSupport
= true;
631 mode_lib
->vba
.ImmediateFlipRequirement
= dm_immediate_flip_required
;
634 mode_lib
->vba
.NumberOfActivePlanes
++;
637 // handle overlays through BlendingAndTiming
638 // BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
640 for (j
= 0; j
< mode_lib
->vba
.NumberOfActivePlanes
; ++j
)
641 PlaneVisited
[j
] = false;
643 for (j
= 0; j
< mode_lib
->vba
.NumberOfActivePlanes
; ++j
) {
644 for (k
= j
+ 1; k
< mode_lib
->vba
.NumberOfActivePlanes
; ++k
) {
645 if (!PlaneVisited
[k
] && OTGInstPlane
[j
] == OTGInstPlane
[k
]) {
646 // doesn't matter, so choose the smaller one
647 mode_lib
->vba
.BlendingAndTiming
[j
] = j
;
648 PlaneVisited
[j
] = true;
649 mode_lib
->vba
.BlendingAndTiming
[k
] = j
;
650 PlaneVisited
[k
] = true;
654 if (!PlaneVisited
[j
]) {
655 mode_lib
->vba
.BlendingAndTiming
[j
] = j
;
656 PlaneVisited
[j
] = true;
660 // TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
661 // Do we want the dscclk to automatically be halved? Guess not since the value is specified
662 mode_lib
->vba
.SynchronizedVBlank
= pipes
[0].pipe
.dest
.synchronized_vblank_all_planes
;
663 for (k
= 1; k
< mode_lib
->vba
.cache_num_pipes
; ++k
) {
664 ASSERT(mode_lib
->vba
.SynchronizedVBlank
== pipes
[k
].pipe
.dest
.synchronized_vblank_all_planes
);
667 mode_lib
->vba
.GPUVMEnable
= false;
668 mode_lib
->vba
.HostVMEnable
= false;
669 mode_lib
->vba
.OverrideGPUVMPageTableLevels
= 0;
670 mode_lib
->vba
.OverrideHostVMPageTableLevels
= 0;
672 for (k
= 0; k
< mode_lib
->vba
.cache_num_pipes
; ++k
) {
673 mode_lib
->vba
.GPUVMEnable
= mode_lib
->vba
.GPUVMEnable
|| !!pipes
[k
].pipe
.src
.gpuvm
|| !!pipes
[k
].pipe
.src
.vm
;
674 mode_lib
->vba
.OverrideGPUVMPageTableLevels
=
675 (pipes
[k
].pipe
.src
.gpuvm_levels_force_en
676 && mode_lib
->vba
.OverrideGPUVMPageTableLevels
677 < pipes
[k
].pipe
.src
.gpuvm_levels_force
) ?
678 pipes
[k
].pipe
.src
.gpuvm_levels_force
:
679 mode_lib
->vba
.OverrideGPUVMPageTableLevels
;
681 mode_lib
->vba
.HostVMEnable
= mode_lib
->vba
.HostVMEnable
|| !!pipes
[k
].pipe
.src
.hostvm
|| !!pipes
[k
].pipe
.src
.vm
;
682 mode_lib
->vba
.OverrideHostVMPageTableLevels
=
683 (pipes
[k
].pipe
.src
.hostvm_levels_force_en
684 && mode_lib
->vba
.OverrideHostVMPageTableLevels
685 < pipes
[k
].pipe
.src
.hostvm_levels_force
) ?
686 pipes
[k
].pipe
.src
.hostvm_levels_force
:
687 mode_lib
->vba
.OverrideHostVMPageTableLevels
;
690 mode_lib
->vba
.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
= dm_try_to_allow_self_refresh_and_mclk_switch
;
692 if (mode_lib
->vba
.OverrideGPUVMPageTableLevels
)
693 mode_lib
->vba
.GPUVMMaxPageTableLevels
= mode_lib
->vba
.OverrideGPUVMPageTableLevels
;
695 if (mode_lib
->vba
.OverrideHostVMPageTableLevels
)
696 mode_lib
->vba
.HostVMMaxPageTableLevels
= mode_lib
->vba
.OverrideHostVMPageTableLevels
;
698 mode_lib
->vba
.GPUVMEnable
= mode_lib
->vba
.GPUVMEnable
&& !!ip
->gpuvm_enable
;
699 mode_lib
->vba
.HostVMEnable
= mode_lib
->vba
.HostVMEnable
&& !!ip
->hostvm_enable
;
702 // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
703 // rather than working them out as in recalculate_ms
704 static void recalculate_params(
705 struct display_mode_lib
*mode_lib
,
706 const display_e2e_pipe_params_st
*pipes
,
707 unsigned int num_pipes
)
709 // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
710 if (memcmp(&mode_lib
->soc
, &mode_lib
->vba
.soc
, sizeof(mode_lib
->vba
.soc
)) != 0
711 || memcmp(&mode_lib
->ip
, &mode_lib
->vba
.ip
, sizeof(mode_lib
->vba
.ip
)) != 0
712 || num_pipes
!= mode_lib
->vba
.cache_num_pipes
715 mode_lib
->vba
.cache_pipes
,
716 sizeof(display_e2e_pipe_params_st
) * num_pipes
) != 0) {
717 mode_lib
->vba
.soc
= mode_lib
->soc
;
718 mode_lib
->vba
.ip
= mode_lib
->ip
;
719 memcpy(mode_lib
->vba
.cache_pipes
, pipes
, sizeof(*pipes
) * num_pipes
);
720 mode_lib
->vba
.cache_num_pipes
= num_pipes
;
721 mode_lib
->funcs
.recalculate(mode_lib
);
725 bool Calculate256BBlockSizes(
726 enum source_format_class SourcePixelFormat
,
727 enum dm_swizzle_mode SurfaceTiling
,
728 unsigned int BytePerPixelY
,
729 unsigned int BytePerPixelC
,
730 unsigned int *BlockHeight256BytesY
,
731 unsigned int *BlockHeight256BytesC
,
732 unsigned int *BlockWidth256BytesY
,
733 unsigned int *BlockWidth256BytesC
)
735 if ((SourcePixelFormat
== dm_444_64
|| SourcePixelFormat
== dm_444_32
736 || SourcePixelFormat
== dm_444_16
|| SourcePixelFormat
== dm_444_8
)) {
737 if (SurfaceTiling
== dm_sw_linear
) {
738 *BlockHeight256BytesY
= 1;
739 } else if (SourcePixelFormat
== dm_444_64
) {
740 *BlockHeight256BytesY
= 4;
741 } else if (SourcePixelFormat
== dm_444_8
) {
742 *BlockHeight256BytesY
= 16;
744 *BlockHeight256BytesY
= 8;
746 *BlockWidth256BytesY
= 256 / BytePerPixelY
/ *BlockHeight256BytesY
;
747 *BlockHeight256BytesC
= 0;
748 *BlockWidth256BytesC
= 0;
750 if (SurfaceTiling
== dm_sw_linear
) {
751 *BlockHeight256BytesY
= 1;
752 *BlockHeight256BytesC
= 1;
753 } else if (SourcePixelFormat
== dm_420_8
) {
754 *BlockHeight256BytesY
= 16;
755 *BlockHeight256BytesC
= 8;
757 *BlockHeight256BytesY
= 8;
758 *BlockHeight256BytesC
= 8;
760 *BlockWidth256BytesY
= 256 / BytePerPixelY
/ *BlockHeight256BytesY
;
761 *BlockWidth256BytesC
= 256 / BytePerPixelC
/ *BlockHeight256BytesC
;
766 bool CalculateMinAndMaxPrefetchMode(
767 enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
,
768 unsigned int *MinPrefetchMode
,
769 unsigned int *MaxPrefetchMode
)
771 if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
772 == dm_neither_self_refresh_nor_mclk_switch
) {
773 *MinPrefetchMode
= 2;
774 *MaxPrefetchMode
= 2;
776 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
== dm_allow_self_refresh
) {
777 *MinPrefetchMode
= 1;
778 *MaxPrefetchMode
= 1;
780 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
781 == dm_allow_self_refresh_and_mclk_switch
) {
782 *MinPrefetchMode
= 0;
783 *MaxPrefetchMode
= 0;
785 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank
786 == dm_try_to_allow_self_refresh_and_mclk_switch
) {
787 *MinPrefetchMode
= 0;
788 *MaxPrefetchMode
= 2;
791 *MinPrefetchMode
= 0;
792 *MaxPrefetchMode
= 2;
796 void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib
*mode_lib
)
800 //Progressive To Interlace Unit Effect
801 for (k
= 0; k
< mode_lib
->vba
.NumberOfActivePlanes
; ++k
) {
802 if (mode_lib
->vba
.Interlace
[k
] == 1
803 && mode_lib
->vba
.ProgressiveToInterlaceUnitInOPP
== true) {
804 mode_lib
->vba
.PixelClock
[k
] = 2 * mode_lib
->vba
.PixelClockBackEnd
[k
];
809 static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp
)
823 void ModeSupportAndSystemConfiguration(struct display_mode_lib
*mode_lib
)
825 soc_bounding_box_st
*soc
= &mode_lib
->vba
.soc
;
827 unsigned int total_pipes
= 0;
829 mode_lib
->vba
.VoltageLevel
= mode_lib
->vba
.cache_pipes
[0].clks_cfg
.voltage
;
830 mode_lib
->vba
.ReturnBW
= mode_lib
->vba
.ReturnBWPerState
[mode_lib
->vba
.VoltageLevel
][mode_lib
->vba
.maxMpcComb
];
831 if (mode_lib
->vba
.ReturnBW
== 0)
832 mode_lib
->vba
.ReturnBW
= mode_lib
->vba
.ReturnBWPerState
[mode_lib
->vba
.VoltageLevel
][0];
833 mode_lib
->vba
.FabricAndDRAMBandwidth
= mode_lib
->vba
.FabricAndDRAMBandwidthPerState
[mode_lib
->vba
.VoltageLevel
];
835 fetch_socbb_params(mode_lib
);
836 fetch_ip_params(mode_lib
);
837 fetch_pipe_params(mode_lib
);
839 mode_lib
->vba
.DCFCLK
= mode_lib
->vba
.cache_pipes
[0].clks_cfg
.dcfclk_mhz
;
840 mode_lib
->vba
.SOCCLK
= mode_lib
->vba
.cache_pipes
[0].clks_cfg
.socclk_mhz
;
841 if (mode_lib
->vba
.cache_pipes
[0].clks_cfg
.dispclk_mhz
> 0.0)
842 mode_lib
->vba
.DISPCLK
= mode_lib
->vba
.cache_pipes
[0].clks_cfg
.dispclk_mhz
;
844 mode_lib
->vba
.DISPCLK
= soc
->clock_limits
[mode_lib
->vba
.VoltageLevel
].dispclk_mhz
;
846 // Total Available Pipes Support Check
847 for (k
= 0; k
< mode_lib
->vba
.NumberOfActivePlanes
; ++k
)
848 total_pipes
+= mode_lib
->vba
.DPPPerPlane
[k
];
849 ASSERT(total_pipes
<= DC__NUM_DPP__MAX
);
852 double CalculateWriteBackDISPCLK(
853 enum source_format_class WritebackPixelFormat
,
855 double WritebackHRatio
,
856 double WritebackVRatio
,
857 unsigned int WritebackLumaHTaps
,
858 unsigned int WritebackLumaVTaps
,
859 unsigned int WritebackChromaHTaps
,
860 unsigned int WritebackChromaVTaps
,
861 double WritebackDestinationWidth
,
863 unsigned int WritebackChromaLineBufferWidth
)
865 double CalculateWriteBackDISPCLK
= 1.01 * PixelClock
* dml_max(
866 dml_ceil(WritebackLumaHTaps
/ 4.0, 1) / WritebackHRatio
,
867 dml_max((WritebackLumaVTaps
* dml_ceil(1.0 / WritebackVRatio
, 1) * dml_ceil(WritebackDestinationWidth
/ 4.0, 1)
868 + dml_ceil(WritebackDestinationWidth
/ 4.0, 1)) / (double) HTotal
+ dml_ceil(1.0 / WritebackVRatio
, 1)
869 * (dml_ceil(WritebackLumaVTaps
/ 4.0, 1) + 4.0) / (double) HTotal
,
870 dml_ceil(1.0 / WritebackVRatio
, 1) * WritebackDestinationWidth
/ (double) HTotal
));
871 if (WritebackPixelFormat
!= dm_444_32
) {
872 CalculateWriteBackDISPCLK
= dml_max(CalculateWriteBackDISPCLK
, 1.01 * PixelClock
* dml_max(
873 dml_ceil(WritebackChromaHTaps
/ 2.0, 1) / (2 * WritebackHRatio
),
874 dml_max((WritebackChromaVTaps
* dml_ceil(1 / (2 * WritebackVRatio
), 1) * dml_ceil(WritebackDestinationWidth
/ 2.0 / 2.0, 1)
875 + dml_ceil(WritebackDestinationWidth
/ 2.0 / WritebackChromaLineBufferWidth
, 1)) / HTotal
876 + dml_ceil(1 / (2 * WritebackVRatio
), 1) * (dml_ceil(WritebackChromaVTaps
/ 4.0, 1) + 4) / HTotal
,
877 dml_ceil(1.0 / (2 * WritebackVRatio
), 1) * WritebackDestinationWidth
/ 2.0 / HTotal
)));
879 return CalculateWriteBackDISPCLK
;