1 | /* |
2 | * Copyright 2019-2021 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 | #include "resource.h" |
27 | #include "clk_mgr.h" |
28 | #include "dcn31/dcn31_resource.h" |
29 | #include "dcn315/dcn315_resource.h" |
30 | #include "dcn316/dcn316_resource.h" |
31 | |
32 | #include "dml/dcn20/dcn20_fpu.h" |
33 | #include "dcn31_fpu.h" |
34 | |
35 | /** |
36 | * DOC: DCN31x FPU manipulation Overview |
37 | * |
38 | * The DCN architecture relies on FPU operations, which require special |
39 | * compilation flags and the use of kernel_fpu_begin/end functions; ideally, we |
40 | * want to avoid spreading FPU access across multiple files. With this idea in |
41 | * mind, this file aims to centralize all DCN3.1.x functions that require FPU |
42 | * access in a single place. Code in this file follows the following code |
43 | * pattern: |
44 | * |
45 | * 1. Functions that use FPU operations should be isolated in static functions. |
46 | * 2. The FPU functions should have the noinline attribute to ensure anything |
47 | * that deals with FP register is contained within this call. |
48 | * 3. All function that needs to be accessed outside this file requires a |
49 | * public interface that not uses any FPU reference. |
50 | * 4. Developers **must not** use DC_FP_START/END in this file, but they need |
51 | * to ensure that the caller invokes it before access any function available |
52 | * in this file. For this reason, public functions in this file must invoke |
53 | * dc_assert_fp_enabled(); |
54 | */ |
55 | |
56 | struct _vcs_dpi_ip_params_st dcn3_1_ip = { |
57 | .gpuvm_enable = 1, |
58 | .gpuvm_max_page_table_levels = 1, |
59 | .hostvm_enable = 1, |
60 | .hostvm_max_page_table_levels = 2, |
61 | .rob_buffer_size_kbytes = 64, |
62 | .det_buffer_size_kbytes = DCN3_1_DEFAULT_DET_SIZE, |
63 | .config_return_buffer_size_in_kbytes = 1792, |
64 | .compressed_buffer_segment_size_in_kbytes = 64, |
65 | .meta_fifo_size_in_kentries = 32, |
66 | .zero_size_buffer_entries = 512, |
67 | .compbuf_reserved_space_64b = 256, |
68 | .compbuf_reserved_space_zs = 64, |
69 | .dpp_output_buffer_pixels = 2560, |
70 | .opp_output_buffer_lines = 1, |
71 | .pixel_chunk_size_kbytes = 8, |
72 | .meta_chunk_size_kbytes = 2, |
73 | .min_meta_chunk_size_bytes = 256, |
74 | .writeback_chunk_size_kbytes = 8, |
75 | .ptoi_supported = false, |
76 | .num_dsc = 3, |
77 | .maximum_dsc_bits_per_component = 10, |
78 | .dsc422_native_support = false, |
79 | .is_line_buffer_bpp_fixed = true, |
80 | .line_buffer_fixed_bpp = 48, |
81 | .line_buffer_size_bits = 789504, |
82 | .max_line_buffer_lines = 12, |
83 | .writeback_interface_buffer_size_kbytes = 90, |
84 | .max_num_dpp = 4, |
85 | .max_num_otg = 4, |
86 | .max_num_hdmi_frl_outputs = 1, |
87 | .max_num_wb = 1, |
88 | .max_dchub_pscl_bw_pix_per_clk = 4, |
89 | .max_pscl_lb_bw_pix_per_clk = 2, |
90 | .max_lb_vscl_bw_pix_per_clk = 4, |
91 | .max_vscl_hscl_bw_pix_per_clk = 4, |
92 | .max_hscl_ratio = 6, |
93 | .max_vscl_ratio = 6, |
94 | .max_hscl_taps = 8, |
95 | .max_vscl_taps = 8, |
96 | .dpte_buffer_size_in_pte_reqs_luma = 64, |
97 | .dpte_buffer_size_in_pte_reqs_chroma = 34, |
98 | .dispclk_ramp_margin_percent = 1, |
99 | .max_inter_dcn_tile_repeaters = 8, |
100 | .cursor_buffer_size = 16, |
101 | .cursor_chunk_size = 2, |
102 | .writeback_line_buffer_buffer_size = 0, |
103 | .writeback_min_hscl_ratio = 1, |
104 | .writeback_min_vscl_ratio = 1, |
105 | .writeback_max_hscl_ratio = 1, |
106 | .writeback_max_vscl_ratio = 1, |
107 | .writeback_max_hscl_taps = 1, |
108 | .writeback_max_vscl_taps = 1, |
109 | .dppclk_delay_subtotal = 46, |
110 | .dppclk_delay_scl = 50, |
111 | .dppclk_delay_scl_lb_only = 16, |
112 | .dppclk_delay_cnvc_formatter = 27, |
113 | .dppclk_delay_cnvc_cursor = 6, |
114 | .dispclk_delay_subtotal = 119, |
115 | .dynamic_metadata_vm_enabled = false, |
116 | .odm_combine_4to1_supported = false, |
117 | .dcc_supported = true, |
118 | }; |
119 | |
120 | static struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { |
121 | /*TODO: correct dispclk/dppclk voltage level determination*/ |
122 | .clock_limits = { |
123 | { |
124 | .state = 0, |
125 | .dispclk_mhz = 1200.0, |
126 | .dppclk_mhz = 1200.0, |
127 | .phyclk_mhz = 600.0, |
128 | .phyclk_d18_mhz = 667.0, |
129 | .dscclk_mhz = 186.0, |
130 | .dtbclk_mhz = 625.0, |
131 | }, |
132 | { |
133 | .state = 1, |
134 | .dispclk_mhz = 1200.0, |
135 | .dppclk_mhz = 1200.0, |
136 | .phyclk_mhz = 810.0, |
137 | .phyclk_d18_mhz = 667.0, |
138 | .dscclk_mhz = 209.0, |
139 | .dtbclk_mhz = 625.0, |
140 | }, |
141 | { |
142 | .state = 2, |
143 | .dispclk_mhz = 1200.0, |
144 | .dppclk_mhz = 1200.0, |
145 | .phyclk_mhz = 810.0, |
146 | .phyclk_d18_mhz = 667.0, |
147 | .dscclk_mhz = 209.0, |
148 | .dtbclk_mhz = 625.0, |
149 | }, |
150 | { |
151 | .state = 3, |
152 | .dispclk_mhz = 1200.0, |
153 | .dppclk_mhz = 1200.0, |
154 | .phyclk_mhz = 810.0, |
155 | .phyclk_d18_mhz = 667.0, |
156 | .dscclk_mhz = 371.0, |
157 | .dtbclk_mhz = 625.0, |
158 | }, |
159 | { |
160 | .state = 4, |
161 | .dispclk_mhz = 1200.0, |
162 | .dppclk_mhz = 1200.0, |
163 | .phyclk_mhz = 810.0, |
164 | .phyclk_d18_mhz = 667.0, |
165 | .dscclk_mhz = 417.0, |
166 | .dtbclk_mhz = 625.0, |
167 | }, |
168 | }, |
169 | .num_states = 5, |
170 | .sr_exit_time_us = 9.0, |
171 | .sr_enter_plus_exit_time_us = 11.0, |
172 | .sr_exit_z8_time_us = 442.0, |
173 | .sr_enter_plus_exit_z8_time_us = 560.0, |
174 | .writeback_latency_us = 12.0, |
175 | .dram_channel_width_bytes = 4, |
176 | .round_trip_ping_latency_dcfclk_cycles = 106, |
177 | .urgent_latency_pixel_data_only_us = 4.0, |
178 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
179 | .urgent_latency_vm_data_only_us = 4.0, |
180 | .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, |
181 | .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, |
182 | .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, |
183 | .pct_ideal_sdp_bw_after_urgent = 80.0, |
184 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0, |
185 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, |
186 | .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0, |
187 | .max_avg_sdp_bw_use_normal_percent = 60.0, |
188 | .max_avg_dram_bw_use_normal_percent = 60.0, |
189 | .fabric_datapath_to_dcn_data_return_bytes = 32, |
190 | .return_bus_width_bytes = 64, |
191 | .downspread_percent = 0.38, |
192 | .dcn_downspread_percent = 0.5, |
193 | .gpuvm_min_page_size_bytes = 4096, |
194 | .hostvm_min_page_size_bytes = 4096, |
195 | .do_urgent_latency_adjustment = false, |
196 | .urgent_latency_adjustment_fabric_clock_component_us = 0, |
197 | .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, |
198 | }; |
199 | |
200 | struct _vcs_dpi_ip_params_st dcn3_15_ip = { |
201 | .gpuvm_enable = 1, |
202 | .gpuvm_max_page_table_levels = 1, |
203 | .hostvm_enable = 1, |
204 | .hostvm_max_page_table_levels = 2, |
205 | .rob_buffer_size_kbytes = 64, |
206 | .det_buffer_size_kbytes = DCN3_15_DEFAULT_DET_SIZE, |
207 | .min_comp_buffer_size_kbytes = 64, |
208 | .config_return_buffer_size_in_kbytes = 1024, |
209 | .compressed_buffer_segment_size_in_kbytes = 64, |
210 | .meta_fifo_size_in_kentries = 32, |
211 | .zero_size_buffer_entries = 512, |
212 | .compbuf_reserved_space_64b = 256, |
213 | .compbuf_reserved_space_zs = 64, |
214 | .dpp_output_buffer_pixels = 2560, |
215 | .opp_output_buffer_lines = 1, |
216 | .pixel_chunk_size_kbytes = 8, |
217 | .meta_chunk_size_kbytes = 2, |
218 | .min_meta_chunk_size_bytes = 256, |
219 | .writeback_chunk_size_kbytes = 8, |
220 | .ptoi_supported = false, |
221 | .num_dsc = 3, |
222 | .maximum_dsc_bits_per_component = 10, |
223 | .dsc422_native_support = false, |
224 | .is_line_buffer_bpp_fixed = true, |
225 | .line_buffer_fixed_bpp = 48, |
226 | .line_buffer_size_bits = 789504, |
227 | .max_line_buffer_lines = 12, |
228 | .writeback_interface_buffer_size_kbytes = 90, |
229 | .max_num_dpp = 4, |
230 | .max_num_otg = 4, |
231 | .max_num_hdmi_frl_outputs = 1, |
232 | .max_num_wb = 1, |
233 | .max_dchub_pscl_bw_pix_per_clk = 4, |
234 | .max_pscl_lb_bw_pix_per_clk = 2, |
235 | .max_lb_vscl_bw_pix_per_clk = 4, |
236 | .max_vscl_hscl_bw_pix_per_clk = 4, |
237 | .max_hscl_ratio = 6, |
238 | .max_vscl_ratio = 6, |
239 | .max_hscl_taps = 8, |
240 | .max_vscl_taps = 8, |
241 | .dpte_buffer_size_in_pte_reqs_luma = 64, |
242 | .dpte_buffer_size_in_pte_reqs_chroma = 34, |
243 | .dispclk_ramp_margin_percent = 1, |
244 | .max_inter_dcn_tile_repeaters = 9, |
245 | .cursor_buffer_size = 16, |
246 | .cursor_chunk_size = 2, |
247 | .writeback_line_buffer_buffer_size = 0, |
248 | .writeback_min_hscl_ratio = 1, |
249 | .writeback_min_vscl_ratio = 1, |
250 | .writeback_max_hscl_ratio = 1, |
251 | .writeback_max_vscl_ratio = 1, |
252 | .writeback_max_hscl_taps = 1, |
253 | .writeback_max_vscl_taps = 1, |
254 | .dppclk_delay_subtotal = 46, |
255 | .dppclk_delay_scl = 50, |
256 | .dppclk_delay_scl_lb_only = 16, |
257 | .dppclk_delay_cnvc_formatter = 27, |
258 | .dppclk_delay_cnvc_cursor = 6, |
259 | .dispclk_delay_subtotal = 119, |
260 | .dynamic_metadata_vm_enabled = false, |
261 | .odm_combine_4to1_supported = false, |
262 | .dcc_supported = true, |
263 | }; |
264 | |
265 | static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = { |
266 | .sr_exit_time_us = 9.0, |
267 | .sr_enter_plus_exit_time_us = 11.0, |
268 | .sr_exit_z8_time_us = 50.0, |
269 | .sr_enter_plus_exit_z8_time_us = 50.0, |
270 | .writeback_latency_us = 12.0, |
271 | .dram_channel_width_bytes = 4, |
272 | .round_trip_ping_latency_dcfclk_cycles = 106, |
273 | .urgent_latency_pixel_data_only_us = 4.0, |
274 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
275 | .urgent_latency_vm_data_only_us = 4.0, |
276 | .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, |
277 | .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, |
278 | .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, |
279 | .pct_ideal_sdp_bw_after_urgent = 80.0, |
280 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0, |
281 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, |
282 | .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0, |
283 | .max_avg_sdp_bw_use_normal_percent = 60.0, |
284 | .max_avg_dram_bw_use_normal_percent = 60.0, |
285 | .fabric_datapath_to_dcn_data_return_bytes = 32, |
286 | .return_bus_width_bytes = 64, |
287 | .downspread_percent = 0.38, |
288 | .dcn_downspread_percent = 0.38, |
289 | .gpuvm_min_page_size_bytes = 4096, |
290 | .hostvm_min_page_size_bytes = 4096, |
291 | .do_urgent_latency_adjustment = false, |
292 | .urgent_latency_adjustment_fabric_clock_component_us = 0, |
293 | .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, |
294 | .num_chans = 4, |
295 | .dummy_pstate_latency_us = 10.0 |
296 | }; |
297 | |
298 | struct _vcs_dpi_ip_params_st dcn3_16_ip = { |
299 | .gpuvm_enable = 1, |
300 | .gpuvm_max_page_table_levels = 1, |
301 | .hostvm_enable = 1, |
302 | .hostvm_max_page_table_levels = 2, |
303 | .rob_buffer_size_kbytes = 64, |
304 | .det_buffer_size_kbytes = DCN3_16_DEFAULT_DET_SIZE, |
305 | .min_comp_buffer_size_kbytes = 64, |
306 | .config_return_buffer_size_in_kbytes = 1024, |
307 | .compressed_buffer_segment_size_in_kbytes = 64, |
308 | .meta_fifo_size_in_kentries = 32, |
309 | .zero_size_buffer_entries = 512, |
310 | .compbuf_reserved_space_64b = 256, |
311 | .compbuf_reserved_space_zs = 64, |
312 | .dpp_output_buffer_pixels = 2560, |
313 | .opp_output_buffer_lines = 1, |
314 | .pixel_chunk_size_kbytes = 8, |
315 | .meta_chunk_size_kbytes = 2, |
316 | .min_meta_chunk_size_bytes = 256, |
317 | .writeback_chunk_size_kbytes = 8, |
318 | .ptoi_supported = false, |
319 | .num_dsc = 3, |
320 | .maximum_dsc_bits_per_component = 10, |
321 | .dsc422_native_support = false, |
322 | .is_line_buffer_bpp_fixed = true, |
323 | .line_buffer_fixed_bpp = 48, |
324 | .line_buffer_size_bits = 789504, |
325 | .max_line_buffer_lines = 12, |
326 | .writeback_interface_buffer_size_kbytes = 90, |
327 | .max_num_dpp = 4, |
328 | .max_num_otg = 4, |
329 | .max_num_hdmi_frl_outputs = 1, |
330 | .max_num_wb = 1, |
331 | .max_dchub_pscl_bw_pix_per_clk = 4, |
332 | .max_pscl_lb_bw_pix_per_clk = 2, |
333 | .max_lb_vscl_bw_pix_per_clk = 4, |
334 | .max_vscl_hscl_bw_pix_per_clk = 4, |
335 | .max_hscl_ratio = 6, |
336 | .max_vscl_ratio = 6, |
337 | .max_hscl_taps = 8, |
338 | .max_vscl_taps = 8, |
339 | .dpte_buffer_size_in_pte_reqs_luma = 64, |
340 | .dpte_buffer_size_in_pte_reqs_chroma = 34, |
341 | .dispclk_ramp_margin_percent = 1, |
342 | .max_inter_dcn_tile_repeaters = 8, |
343 | .cursor_buffer_size = 16, |
344 | .cursor_chunk_size = 2, |
345 | .writeback_line_buffer_buffer_size = 0, |
346 | .writeback_min_hscl_ratio = 1, |
347 | .writeback_min_vscl_ratio = 1, |
348 | .writeback_max_hscl_ratio = 1, |
349 | .writeback_max_vscl_ratio = 1, |
350 | .writeback_max_hscl_taps = 1, |
351 | .writeback_max_vscl_taps = 1, |
352 | .dppclk_delay_subtotal = 46, |
353 | .dppclk_delay_scl = 50, |
354 | .dppclk_delay_scl_lb_only = 16, |
355 | .dppclk_delay_cnvc_formatter = 27, |
356 | .dppclk_delay_cnvc_cursor = 6, |
357 | .dispclk_delay_subtotal = 119, |
358 | .dynamic_metadata_vm_enabled = false, |
359 | .odm_combine_4to1_supported = false, |
360 | .dcc_supported = true, |
361 | }; |
362 | |
363 | static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = { |
364 | /*TODO: correct dispclk/dppclk voltage level determination*/ |
365 | .clock_limits = { |
366 | { |
367 | .state = 0, |
368 | .dispclk_mhz = 556.0, |
369 | .dppclk_mhz = 556.0, |
370 | .phyclk_mhz = 600.0, |
371 | .phyclk_d18_mhz = 445.0, |
372 | .dscclk_mhz = 186.0, |
373 | .dtbclk_mhz = 625.0, |
374 | }, |
375 | { |
376 | .state = 1, |
377 | .dispclk_mhz = 625.0, |
378 | .dppclk_mhz = 625.0, |
379 | .phyclk_mhz = 810.0, |
380 | .phyclk_d18_mhz = 667.0, |
381 | .dscclk_mhz = 209.0, |
382 | .dtbclk_mhz = 625.0, |
383 | }, |
384 | { |
385 | .state = 2, |
386 | .dispclk_mhz = 625.0, |
387 | .dppclk_mhz = 625.0, |
388 | .phyclk_mhz = 810.0, |
389 | .phyclk_d18_mhz = 667.0, |
390 | .dscclk_mhz = 209.0, |
391 | .dtbclk_mhz = 625.0, |
392 | }, |
393 | { |
394 | .state = 3, |
395 | .dispclk_mhz = 1112.0, |
396 | .dppclk_mhz = 1112.0, |
397 | .phyclk_mhz = 810.0, |
398 | .phyclk_d18_mhz = 667.0, |
399 | .dscclk_mhz = 371.0, |
400 | .dtbclk_mhz = 625.0, |
401 | }, |
402 | { |
403 | .state = 4, |
404 | .dispclk_mhz = 1250.0, |
405 | .dppclk_mhz = 1250.0, |
406 | .phyclk_mhz = 810.0, |
407 | .phyclk_d18_mhz = 667.0, |
408 | .dscclk_mhz = 417.0, |
409 | .dtbclk_mhz = 625.0, |
410 | }, |
411 | }, |
412 | .num_states = 5, |
413 | .sr_exit_time_us = 9.0, |
414 | .sr_enter_plus_exit_time_us = 11.0, |
415 | .sr_exit_z8_time_us = 442.0, |
416 | .sr_enter_plus_exit_z8_time_us = 560.0, |
417 | .writeback_latency_us = 12.0, |
418 | .dram_channel_width_bytes = 4, |
419 | .round_trip_ping_latency_dcfclk_cycles = 106, |
420 | .urgent_latency_pixel_data_only_us = 4.0, |
421 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
422 | .urgent_latency_vm_data_only_us = 4.0, |
423 | .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, |
424 | .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, |
425 | .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, |
426 | .pct_ideal_sdp_bw_after_urgent = 80.0, |
427 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0, |
428 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, |
429 | .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0, |
430 | .max_avg_sdp_bw_use_normal_percent = 60.0, |
431 | .max_avg_dram_bw_use_normal_percent = 60.0, |
432 | .fabric_datapath_to_dcn_data_return_bytes = 32, |
433 | .return_bus_width_bytes = 64, |
434 | .downspread_percent = 0.38, |
435 | .dcn_downspread_percent = 0.5, |
436 | .gpuvm_min_page_size_bytes = 4096, |
437 | .hostvm_min_page_size_bytes = 4096, |
438 | .do_urgent_latency_adjustment = false, |
439 | .urgent_latency_adjustment_fabric_clock_component_us = 0, |
440 | .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, |
441 | }; |
442 | |
443 | void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes, |
444 | int pipe_cnt) |
445 | { |
446 | dc_assert_fp_enabled(); |
447 | |
448 | pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0; |
449 | pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0; |
450 | } |
451 | |
452 | void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) |
453 | { |
454 | dc_assert_fp_enabled(); |
455 | |
456 | if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) { |
457 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us; |
458 | context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_enter_plus_exit_time_us; |
459 | context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_exit_time_us; |
460 | } |
461 | } |
462 | |
463 | void dcn315_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) |
464 | { |
465 | dc_assert_fp_enabled(); |
466 | |
467 | if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) { |
468 | /* For 315 pstate change is only supported if possible in vactive */ |
469 | if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[context->bw_ctx.dml.vba.VoltageLevel][context->bw_ctx.dml.vba.maxMpcComb] != dm_dram_clock_change_vactive) |
470 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us; |
471 | else |
472 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us; |
473 | context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = |
474 | dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_enter_plus_exit_time_us; |
475 | context->bw_ctx.dml.soc.sr_exit_time_us = |
476 | dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_exit_time_us; |
477 | } |
478 | } |
479 | |
480 | void dcn31_calculate_wm_and_dlg_fp( |
481 | struct dc *dc, struct dc_state *context, |
482 | display_e2e_pipe_params_st *pipes, |
483 | int pipe_cnt, |
484 | int vlevel) |
485 | { |
486 | int i, pipe_idx, total_det = 0, active_hubp_count = 0; |
487 | double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; |
488 | |
489 | dc_assert_fp_enabled(); |
490 | |
491 | if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) |
492 | dcfclk = context->bw_ctx.dml.soc.min_dcfclk; |
493 | |
494 | /* We don't recalculate clocks for 0 pipe configs, which can block |
495 | * S0i3 as high clocks will block low power states |
496 | * Override any clocks that can block S0i3 to min here |
497 | */ |
498 | if (pipe_cnt == 0) { |
499 | context->bw_ctx.bw.dcn.clk.dcfclk_khz = dcfclk; // always should be vlevel 0 |
500 | return; |
501 | } |
502 | |
503 | pipes[0].clks_cfg.voltage = vlevel; |
504 | pipes[0].clks_cfg.dcfclk_mhz = dcfclk; |
505 | pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz; |
506 | |
507 | /* Set A: |
508 | * All clocks min required |
509 | * |
510 | * Set A calculated last so that following calculations are based on Set A |
511 | */ |
512 | dc->res_pool->funcs->update_soc_for_wm_a(dc, context); |
513 | context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
514 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
515 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
516 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
517 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns = get_wm_z8_stutter_enter_exit(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
518 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_z8_ns = get_wm_z8_stutter_exit(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
519 | context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
520 | context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
521 | context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
522 | context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt) * 1000; |
523 | context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a; |
524 | context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a; |
525 | context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; |
526 | |
527 | for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { |
528 | if (!context->res_ctx.pipe_ctx[i].stream) |
529 | continue; |
530 | |
531 | if (context->res_ctx.pipe_ctx[i].plane_state) |
532 | active_hubp_count++; |
533 | |
534 | pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt); |
535 | pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt, which_pipe: pipe_idx); |
536 | |
537 | if (dc->config.forced_clocks || dc->debug.max_disp_clk) { |
538 | pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; |
539 | pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; |
540 | } |
541 | if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) |
542 | pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; |
543 | if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) |
544 | pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; |
545 | |
546 | pipe_idx++; |
547 | } |
548 | |
549 | dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); |
550 | /* For 31x apu pstate change is only supported if possible in vactive*/ |
551 | context->bw_ctx.bw.dcn.clk.p_state_change_support = |
552 | context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_vactive; |
553 | /* If DCN isn't making memory requests we can allow pstate change and lower clocks */ |
554 | if (!active_hubp_count) { |
555 | context->bw_ctx.bw.dcn.clk.socclk_khz = 0; |
556 | context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; |
557 | context->bw_ctx.bw.dcn.clk.dcfclk_khz = 0; |
558 | context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = 0; |
559 | context->bw_ctx.bw.dcn.clk.dramclk_khz = 0; |
560 | context->bw_ctx.bw.dcn.clk.fclk_khz = 0; |
561 | context->bw_ctx.bw.dcn.clk.p_state_change_support = true; |
562 | for (i = 0; i < dc->res_pool->pipe_count; i++) |
563 | if (context->res_ctx.pipe_ctx[i].stream) |
564 | context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = 0; |
565 | } |
566 | for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { |
567 | if (!context->res_ctx.pipe_ctx[i].stream) |
568 | continue; |
569 | |
570 | context->res_ctx.pipe_ctx[i].det_buffer_size_kb = |
571 | get_det_buffer_size_kbytes(mode_lib: &context->bw_ctx.dml, pipes, num_pipes: pipe_cnt, which_pipe: pipe_idx); |
572 | if (context->res_ctx.pipe_ctx[i].det_buffer_size_kb > 384) |
573 | context->res_ctx.pipe_ctx[i].det_buffer_size_kb /= 2; |
574 | total_det += context->res_ctx.pipe_ctx[i].det_buffer_size_kb; |
575 | pipe_idx++; |
576 | } |
577 | context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - total_det; |
578 | } |
579 | |
580 | void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) |
581 | { |
582 | struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits; |
583 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
584 | unsigned int i, closest_clk_lvl; |
585 | int max_dispclk_mhz = 0, max_dppclk_mhz = 0; |
586 | int j; |
587 | |
588 | dc_assert_fp_enabled(); |
589 | |
590 | memcpy(s, dcn3_1_soc.clock_limits, sizeof(dcn3_1_soc.clock_limits)); |
591 | |
592 | // Default clock levels are used for diags, which may lead to overclocking. |
593 | dcn3_1_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator; |
594 | dcn3_1_ip.max_num_dpp = dc->res_pool->pipe_count; |
595 | dcn3_1_soc.num_chans = bw_params->num_channels; |
596 | |
597 | ASSERT(clk_table->num_entries); |
598 | |
599 | /* Prepass to find max clocks independent of voltage level. */ |
600 | for (i = 0; i < clk_table->num_entries; ++i) { |
601 | if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) |
602 | max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; |
603 | if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) |
604 | max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; |
605 | } |
606 | |
607 | for (i = 0; i < clk_table->num_entries; i++) { |
608 | /* loop backwards*/ |
609 | for (closest_clk_lvl = 0, j = dcn3_1_soc.num_states - 1; j >= 0; j--) { |
610 | if ((unsigned int) dcn3_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { |
611 | closest_clk_lvl = j; |
612 | break; |
613 | } |
614 | } |
615 | |
616 | s[i].state = i; |
617 | |
618 | /* Clocks dependent on voltage level. */ |
619 | s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; |
620 | s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; |
621 | s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; |
622 | s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * |
623 | 2 * clk_table->entries[i].wck_ratio; |
624 | |
625 | /* Clocks independent of voltage level. */ |
626 | s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : |
627 | dcn3_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; |
628 | |
629 | s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : |
630 | dcn3_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; |
631 | |
632 | s[i].dram_bw_per_chan_gbps = |
633 | dcn3_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; |
634 | s[i].dscclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; |
635 | s[i].dtbclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; |
636 | s[i].phyclk_d18_mhz = |
637 | dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; |
638 | s[i].phyclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; |
639 | } |
640 | if (clk_table->num_entries) { |
641 | dcn3_1_soc.num_states = clk_table->num_entries; |
642 | } |
643 | |
644 | memcpy(dcn3_1_soc.clock_limits, s, sizeof(dcn3_1_soc.clock_limits)); |
645 | |
646 | dcn3_1_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; |
647 | dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; |
648 | |
649 | if ((int)(dcn3_1_soc.dram_clock_change_latency_us * 1000) |
650 | != dc->debug.dram_clock_change_latency_ns |
651 | && dc->debug.dram_clock_change_latency_ns) { |
652 | dcn3_1_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000; |
653 | } |
654 | |
655 | dml_init_instance(lib: &dc->dml, soc_bb: &dcn3_1_soc, ip_params: &dcn3_1_ip, project: DML_PROJECT_DCN31); |
656 | } |
657 | |
658 | void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) |
659 | { |
660 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
661 | int i, max_dispclk_mhz = 0, max_dppclk_mhz = 0; |
662 | |
663 | dc_assert_fp_enabled(); |
664 | |
665 | dcn3_15_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator; |
666 | dcn3_15_ip.max_num_dpp = dc->res_pool->pipe_count; |
667 | |
668 | if (bw_params->num_channels > 0) |
669 | dcn3_15_soc.num_chans = bw_params->num_channels; |
670 | if (bw_params->dram_channel_width_bytes > 0) |
671 | dcn3_15_soc.dram_channel_width_bytes = bw_params->dram_channel_width_bytes; |
672 | |
673 | ASSERT(clk_table->num_entries); |
674 | |
675 | /* Setup soc to always use max dispclk/dppclk to avoid odm-to-lower-voltage */ |
676 | for (i = 0; i < clk_table->num_entries; ++i) { |
677 | if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) |
678 | max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; |
679 | if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) |
680 | max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; |
681 | } |
682 | |
683 | for (i = 0; i < clk_table->num_entries; i++) { |
684 | dcn3_15_soc.clock_limits[i].state = i; |
685 | |
686 | /* Clocks dependent on voltage level. */ |
687 | dcn3_15_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; |
688 | dcn3_15_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; |
689 | dcn3_15_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; |
690 | dcn3_15_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio; |
691 | |
692 | /* These aren't actually read from smu, but rather set in clk_mgr defaults */ |
693 | dcn3_15_soc.clock_limits[i].dtbclk_mhz = clk_table->entries[i].dtbclk_mhz; |
694 | dcn3_15_soc.clock_limits[i].phyclk_d18_mhz = clk_table->entries[i].phyclk_d18_mhz; |
695 | dcn3_15_soc.clock_limits[i].phyclk_mhz = clk_table->entries[i].phyclk_mhz; |
696 | |
697 | /* Clocks independent of voltage level. */ |
698 | dcn3_15_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; |
699 | dcn3_15_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; |
700 | dcn3_15_soc.clock_limits[i].dscclk_mhz = max_dispclk_mhz / 3.0; |
701 | } |
702 | dcn3_15_soc.num_states = clk_table->num_entries; |
703 | |
704 | |
705 | /* Set vco to max_dispclk * 2 to make sure the highest dispclk is always available for dml calcs, |
706 | * no impact outside of dml validation |
707 | */ |
708 | dcn3_15_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; |
709 | |
710 | if ((int)(dcn3_15_soc.dram_clock_change_latency_us * 1000) |
711 | != dc->debug.dram_clock_change_latency_ns |
712 | && dc->debug.dram_clock_change_latency_ns) { |
713 | dcn3_15_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000; |
714 | } |
715 | |
716 | dml_init_instance(lib: &dc->dml, soc_bb: &dcn3_15_soc, ip_params: &dcn3_15_ip, project: DML_PROJECT_DCN315); |
717 | } |
718 | |
719 | void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) |
720 | { |
721 | struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits; |
722 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
723 | unsigned int i, closest_clk_lvl; |
724 | int max_dispclk_mhz = 0, max_dppclk_mhz = 0; |
725 | int j; |
726 | |
727 | dc_assert_fp_enabled(); |
728 | |
729 | memcpy(s, dcn3_16_soc.clock_limits, sizeof(dcn3_16_soc.clock_limits)); |
730 | |
731 | // Default clock levels are used for diags, which may lead to overclocking. |
732 | dcn3_16_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator; |
733 | dcn3_16_ip.max_num_dpp = dc->res_pool->pipe_count; |
734 | dcn3_16_soc.num_chans = bw_params->num_channels; |
735 | |
736 | ASSERT(clk_table->num_entries); |
737 | |
738 | /* Prepass to find max clocks independent of voltage level. */ |
739 | for (i = 0; i < clk_table->num_entries; ++i) { |
740 | if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) |
741 | max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; |
742 | if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) |
743 | max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; |
744 | } |
745 | |
746 | for (i = 0; i < clk_table->num_entries; i++) { |
747 | /* loop backwards*/ |
748 | for (closest_clk_lvl = 0, j = dcn3_16_soc.num_states - 1; j >= 0; j--) { |
749 | if ((unsigned int) dcn3_16_soc.clock_limits[j].dcfclk_mhz <= |
750 | clk_table->entries[i].dcfclk_mhz) { |
751 | closest_clk_lvl = j; |
752 | break; |
753 | } |
754 | } |
755 | // Ported from DCN315 |
756 | if (clk_table->num_entries == 1) { |
757 | /*smu gives one DPM level, let's take the highest one*/ |
758 | closest_clk_lvl = dcn3_16_soc.num_states - 1; |
759 | } |
760 | |
761 | s[i].state = i; |
762 | |
763 | /* Clocks dependent on voltage level. */ |
764 | s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; |
765 | if (clk_table->num_entries == 1 && |
766 | s[i].dcfclk_mhz < |
767 | dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { |
768 | /*SMU fix not released yet*/ |
769 | s[i].dcfclk_mhz = |
770 | dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz; |
771 | } |
772 | s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; |
773 | s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; |
774 | s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * |
775 | 2 * clk_table->entries[i].wck_ratio; |
776 | |
777 | /* Clocks independent of voltage level. */ |
778 | s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : |
779 | dcn3_16_soc.clock_limits[closest_clk_lvl].dispclk_mhz; |
780 | |
781 | s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : |
782 | dcn3_16_soc.clock_limits[closest_clk_lvl].dppclk_mhz; |
783 | |
784 | s[i].dram_bw_per_chan_gbps = |
785 | dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; |
786 | s[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz; |
787 | s[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; |
788 | s[i].phyclk_d18_mhz = |
789 | dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; |
790 | s[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz; |
791 | } |
792 | if (clk_table->num_entries) { |
793 | dcn3_16_soc.num_states = clk_table->num_entries; |
794 | } |
795 | |
796 | memcpy(dcn3_16_soc.clock_limits, s, sizeof(dcn3_16_soc.clock_limits)); |
797 | |
798 | if (max_dispclk_mhz) { |
799 | dcn3_16_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; |
800 | dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; |
801 | } |
802 | if ((int)(dcn3_16_soc.dram_clock_change_latency_us * 1000) |
803 | != dc->debug.dram_clock_change_latency_ns |
804 | && dc->debug.dram_clock_change_latency_ns) { |
805 | dcn3_16_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000; |
806 | } |
807 | |
808 | dml_init_instance(lib: &dc->dml, soc_bb: &dcn3_16_soc, ip_params: &dcn3_16_ip, project: DML_PROJECT_DCN31); |
809 | } |
810 | |
811 | int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc) |
812 | { |
813 | return soc->clock_limits[0].dispclk_mhz * 10000.0 / (1.0 + soc->dcn_downspread_percent / 100.0); |
814 | } |
815 | |
816 | int dcn_get_approx_det_segs_required_for_pstate( |
817 | struct _vcs_dpi_soc_bounding_box_st *soc, |
818 | int pix_clk_100hz, int bpp, int seg_size_kb) |
819 | { |
820 | /* Roughly calculate required crb to hide latency. In practice there is slightly |
821 | * more buffer available for latency hiding |
822 | */ |
823 | return (int)(soc->dram_clock_change_latency_us * pix_clk_100hz * bpp |
824 | / 10240000 + seg_size_kb - 1) / seg_size_kb; |
825 | } |
826 | |