1 | /* |
2 | * Copyright 2017 Advanced Micro Devices, Inc. |
3 | * Copyright 2019 Raptor Engineering, LLC |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
12 | * The above copyright notice and this permission notice shall be included in |
13 | * all copies or substantial portions of the Software. |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * |
23 | * Authors: AMD |
24 | * |
25 | */ |
26 | |
27 | #include "dm_services.h" |
28 | #include "dc.h" |
29 | #include "dcn_calcs.h" |
30 | #include "dcn_calc_auto.h" |
31 | #include "dal_asic_id.h" |
32 | #include "resource.h" |
33 | #include "resource/dcn10/dcn10_resource.h" |
34 | #include "dcn10/dcn10_hubbub.h" |
35 | #include "dml/dml1_display_rq_dlg_calc.h" |
36 | |
37 | #include "dcn_calc_math.h" |
38 | |
39 | #define DC_LOGGER \ |
40 | dc->ctx->logger |
41 | |
42 | #define WM_SET_COUNT 4 |
43 | #define WM_A 0 |
44 | #define WM_B 1 |
45 | #define WM_C 2 |
46 | #define WM_D 3 |
47 | |
48 | /* |
49 | * NOTE: |
50 | * This file is gcc-parseable HW gospel, coming straight from HW engineers. |
51 | * |
52 | * It doesn't adhere to Linux kernel style and sometimes will do things in odd |
53 | * ways. Unless there is something clearly wrong with it the code should |
54 | * remain as-is as it provides us with a guarantee from HW that it is correct. |
55 | */ |
56 | |
57 | /* Defaults from spreadsheet rev#247. |
58 | * RV2 delta: dram_clock_change_latency, max_num_dpp |
59 | */ |
60 | const struct dcn_soc_bounding_box dcn10_soc_defaults = { |
61 | /* latencies */ |
62 | .sr_exit_time = 17, /*us*/ |
63 | .sr_enter_plus_exit_time = 19, /*us*/ |
64 | .urgent_latency = 4, /*us*/ |
65 | .dram_clock_change_latency = 17, /*us*/ |
66 | .write_back_latency = 12, /*us*/ |
67 | .percent_of_ideal_drambw_received_after_urg_latency = 80, /*%*/ |
68 | |
69 | /* below default clocks derived from STA target base on |
70 | * slow-slow corner + 10% margin with voltages aligned to FCLK. |
71 | * |
72 | * Use these value if fused value doesn't make sense as earlier |
73 | * part don't have correct value fused */ |
74 | /* default DCF CLK DPM on RV*/ |
75 | .dcfclkv_max0p9 = 655, /* MHz, = 3600/5.5 */ |
76 | .dcfclkv_nom0p8 = 626, /* MHz, = 3600/5.75 */ |
77 | .dcfclkv_mid0p72 = 600, /* MHz, = 3600/6, bypass */ |
78 | .dcfclkv_min0p65 = 300, /* MHz, = 3600/12, bypass */ |
79 | |
80 | /* default DISP CLK voltage state on RV */ |
81 | .max_dispclk_vmax0p9 = 1108, /* MHz, = 3600/3.25 */ |
82 | .max_dispclk_vnom0p8 = 1029, /* MHz, = 3600/3.5 */ |
83 | .max_dispclk_vmid0p72 = 960, /* MHz, = 3600/3.75 */ |
84 | .max_dispclk_vmin0p65 = 626, /* MHz, = 3600/5.75 */ |
85 | |
86 | /* default DPP CLK voltage state on RV */ |
87 | .max_dppclk_vmax0p9 = 720, /* MHz, = 3600/5 */ |
88 | .max_dppclk_vnom0p8 = 686, /* MHz, = 3600/5.25 */ |
89 | .max_dppclk_vmid0p72 = 626, /* MHz, = 3600/5.75 */ |
90 | .max_dppclk_vmin0p65 = 400, /* MHz, = 3600/9 */ |
91 | |
92 | /* default PHY CLK voltage state on RV */ |
93 | .phyclkv_max0p9 = 900, /*MHz*/ |
94 | .phyclkv_nom0p8 = 847, /*MHz*/ |
95 | .phyclkv_mid0p72 = 800, /*MHz*/ |
96 | .phyclkv_min0p65 = 600, /*MHz*/ |
97 | |
98 | /* BW depend on FCLK, MCLK, # of channels */ |
99 | /* dual channel BW */ |
100 | .fabric_and_dram_bandwidth_vmax0p9 = 38.4f, /*GB/s*/ |
101 | .fabric_and_dram_bandwidth_vnom0p8 = 34.133f, /*GB/s*/ |
102 | .fabric_and_dram_bandwidth_vmid0p72 = 29.866f, /*GB/s*/ |
103 | .fabric_and_dram_bandwidth_vmin0p65 = 12.8f, /*GB/s*/ |
104 | /* single channel BW |
105 | .fabric_and_dram_bandwidth_vmax0p9 = 19.2f, |
106 | .fabric_and_dram_bandwidth_vnom0p8 = 17.066f, |
107 | .fabric_and_dram_bandwidth_vmid0p72 = 14.933f, |
108 | .fabric_and_dram_bandwidth_vmin0p65 = 12.8f, |
109 | */ |
110 | |
111 | .number_of_channels = 2, |
112 | |
113 | .socclk = 208, /*MHz*/ |
114 | .downspreading = 0.5f, /*%*/ |
115 | .round_trip_ping_latency_cycles = 128, /*DCFCLK Cycles*/ |
116 | .urgent_out_of_order_return_per_channel = 256, /*bytes*/ |
117 | .vmm_page_size = 4096, /*bytes*/ |
118 | .return_bus_width = 64, /*bytes*/ |
119 | .max_request_size = 256, /*bytes*/ |
120 | |
121 | /* Depends on user class (client vs embedded, workstation, etc) */ |
122 | .percent_disp_bw_limit = 0.3f /*%*/ |
123 | }; |
124 | |
125 | const struct dcn_ip_params dcn10_ip_defaults = { |
126 | .rob_buffer_size_in_kbyte = 64, |
127 | .det_buffer_size_in_kbyte = 164, |
128 | .dpp_output_buffer_pixels = 2560, |
129 | .opp_output_buffer_lines = 1, |
130 | .pixel_chunk_size_in_kbyte = 8, |
131 | .pte_enable = dcn_bw_yes, |
132 | .pte_chunk_size = 2, /*kbytes*/ |
133 | .meta_chunk_size = 2, /*kbytes*/ |
134 | .writeback_chunk_size = 2, /*kbytes*/ |
135 | .odm_capability = dcn_bw_no, |
136 | .dsc_capability = dcn_bw_no, |
137 | .line_buffer_size = 589824, /*bit*/ |
138 | .max_line_buffer_lines = 12, |
139 | .is_line_buffer_bpp_fixed = dcn_bw_no, |
140 | .line_buffer_fixed_bpp = dcn_bw_na, |
141 | .writeback_luma_buffer_size = 12, /*kbytes*/ |
142 | .writeback_chroma_buffer_size = 8, /*kbytes*/ |
143 | .max_num_dpp = 4, |
144 | .max_num_writeback = 2, |
145 | .max_dchub_topscl_throughput = 4, /*pixels/dppclk*/ |
146 | .max_pscl_tolb_throughput = 2, /*pixels/dppclk*/ |
147 | .max_lb_tovscl_throughput = 4, /*pixels/dppclk*/ |
148 | .max_vscl_tohscl_throughput = 4, /*pixels/dppclk*/ |
149 | .max_hscl_ratio = 4, |
150 | .max_vscl_ratio = 4, |
151 | .max_hscl_taps = 8, |
152 | .max_vscl_taps = 8, |
153 | .pte_buffer_size_in_requests = 42, |
154 | .dispclk_ramping_margin = 1, /*%*/ |
155 | .under_scan_factor = 1.11f, |
156 | .max_inter_dcn_tile_repeaters = 8, |
157 | .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = dcn_bw_no, |
158 | .bug_forcing_luma_and_chroma_request_to_same_size_fixed = dcn_bw_no, |
159 | .dcfclk_cstate_latency = 10 /*TODO clone of something else? sr_enter_plus_exit_time?*/ |
160 | }; |
161 | |
162 | static enum dcn_bw_defs tl_sw_mode_to_bw_defs(enum swizzle_mode_values sw_mode) |
163 | { |
164 | switch (sw_mode) { |
165 | case DC_SW_LINEAR: |
166 | return dcn_bw_sw_linear; |
167 | case DC_SW_4KB_S: |
168 | return dcn_bw_sw_4_kb_s; |
169 | case DC_SW_4KB_D: |
170 | return dcn_bw_sw_4_kb_d; |
171 | case DC_SW_64KB_S: |
172 | return dcn_bw_sw_64_kb_s; |
173 | case DC_SW_64KB_D: |
174 | return dcn_bw_sw_64_kb_d; |
175 | case DC_SW_VAR_S: |
176 | return dcn_bw_sw_var_s; |
177 | case DC_SW_VAR_D: |
178 | return dcn_bw_sw_var_d; |
179 | case DC_SW_64KB_S_T: |
180 | return dcn_bw_sw_64_kb_s_t; |
181 | case DC_SW_64KB_D_T: |
182 | return dcn_bw_sw_64_kb_d_t; |
183 | case DC_SW_4KB_S_X: |
184 | return dcn_bw_sw_4_kb_s_x; |
185 | case DC_SW_4KB_D_X: |
186 | return dcn_bw_sw_4_kb_d_x; |
187 | case DC_SW_64KB_S_X: |
188 | return dcn_bw_sw_64_kb_s_x; |
189 | case DC_SW_64KB_D_X: |
190 | return dcn_bw_sw_64_kb_d_x; |
191 | case DC_SW_VAR_S_X: |
192 | return dcn_bw_sw_var_s_x; |
193 | case DC_SW_VAR_D_X: |
194 | return dcn_bw_sw_var_d_x; |
195 | case DC_SW_256B_S: |
196 | case DC_SW_256_D: |
197 | case DC_SW_256_R: |
198 | case DC_SW_4KB_R: |
199 | case DC_SW_64KB_R: |
200 | case DC_SW_VAR_R: |
201 | case DC_SW_4KB_R_X: |
202 | case DC_SW_64KB_R_X: |
203 | case DC_SW_VAR_R_X: |
204 | default: |
205 | BREAK_TO_DEBUGGER(); /*not in formula*/ |
206 | return dcn_bw_sw_4_kb_s; |
207 | } |
208 | } |
209 | |
210 | static int tl_lb_bpp_to_int(enum lb_pixel_depth depth) |
211 | { |
212 | switch (depth) { |
213 | case LB_PIXEL_DEPTH_18BPP: |
214 | return 18; |
215 | case LB_PIXEL_DEPTH_24BPP: |
216 | return 24; |
217 | case LB_PIXEL_DEPTH_30BPP: |
218 | return 30; |
219 | case LB_PIXEL_DEPTH_36BPP: |
220 | return 36; |
221 | default: |
222 | return 30; |
223 | } |
224 | } |
225 | |
226 | static enum dcn_bw_defs tl_pixel_format_to_bw_defs(enum surface_pixel_format format) |
227 | { |
228 | switch (format) { |
229 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: |
230 | case SURFACE_PIXEL_FORMAT_GRPH_RGB565: |
231 | return dcn_bw_rgb_sub_16; |
232 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: |
233 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: |
234 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: |
235 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: |
236 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: |
237 | return dcn_bw_rgb_sub_32; |
238 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: |
239 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: |
240 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: |
241 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: |
242 | return dcn_bw_rgb_sub_64; |
243 | case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: |
244 | case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: |
245 | return dcn_bw_yuv420_sub_8; |
246 | case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: |
247 | case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: |
248 | return dcn_bw_yuv420_sub_10; |
249 | default: |
250 | return dcn_bw_rgb_sub_32; |
251 | } |
252 | } |
253 | |
254 | enum source_macro_tile_size swizzle_mode_to_macro_tile_size(enum swizzle_mode_values sw_mode) |
255 | { |
256 | switch (sw_mode) { |
257 | /* for 4/8/16 high tiles */ |
258 | case DC_SW_LINEAR: |
259 | return dm_4k_tile; |
260 | case DC_SW_4KB_S: |
261 | case DC_SW_4KB_S_X: |
262 | return dm_4k_tile; |
263 | case DC_SW_64KB_S: |
264 | case DC_SW_64KB_S_X: |
265 | case DC_SW_64KB_S_T: |
266 | return dm_64k_tile; |
267 | case DC_SW_VAR_S: |
268 | case DC_SW_VAR_S_X: |
269 | return dm_256k_tile; |
270 | |
271 | /* For 64bpp 2 high tiles */ |
272 | case DC_SW_4KB_D: |
273 | case DC_SW_4KB_D_X: |
274 | return dm_4k_tile; |
275 | case DC_SW_64KB_D: |
276 | case DC_SW_64KB_D_X: |
277 | case DC_SW_64KB_D_T: |
278 | return dm_64k_tile; |
279 | case DC_SW_VAR_D: |
280 | case DC_SW_VAR_D_X: |
281 | return dm_256k_tile; |
282 | |
283 | case DC_SW_4KB_R: |
284 | case DC_SW_4KB_R_X: |
285 | return dm_4k_tile; |
286 | case DC_SW_64KB_R: |
287 | case DC_SW_64KB_R_X: |
288 | return dm_64k_tile; |
289 | case DC_SW_VAR_R: |
290 | case DC_SW_VAR_R_X: |
291 | return dm_256k_tile; |
292 | |
293 | /* Unsupported swizzle modes for dcn */ |
294 | case DC_SW_256B_S: |
295 | default: |
296 | ASSERT(0); /* Not supported */ |
297 | return 0; |
298 | } |
299 | } |
300 | |
301 | static void pipe_ctx_to_e2e_pipe_params ( |
302 | const struct pipe_ctx *pipe, |
303 | struct _vcs_dpi_display_pipe_params_st *input) |
304 | { |
305 | input->src.is_hsplit = false; |
306 | |
307 | /* stereo can never be split */ |
308 | if (pipe->plane_state->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE || |
309 | pipe->plane_state->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) { |
310 | /* reset the split group if it was already considered split. */ |
311 | input->src.hsplit_grp = pipe->pipe_idx; |
312 | } else if (pipe->top_pipe != NULL && pipe->top_pipe->plane_state == pipe->plane_state) { |
313 | input->src.is_hsplit = true; |
314 | } else if (pipe->bottom_pipe != NULL && pipe->bottom_pipe->plane_state == pipe->plane_state) { |
315 | input->src.is_hsplit = true; |
316 | } |
317 | |
318 | if (pipe->plane_res.dpp->ctx->dc->debug.optimized_watermark) { |
319 | /* |
320 | * this method requires us to always re-calculate watermark when dcc change |
321 | * between flip. |
322 | */ |
323 | input->src.dcc = pipe->plane_state->dcc.enable ? 1 : 0; |
324 | } else { |
325 | /* |
326 | * allow us to disable dcc on the fly without re-calculating WM |
327 | * |
328 | * extra overhead for DCC is quite small. for 1080p WM without |
329 | * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us) |
330 | */ |
331 | unsigned int bpe; |
332 | |
333 | input->src.dcc = pipe->plane_res.dpp->ctx->dc->res_pool->hubbub->funcs-> |
334 | dcc_support_pixel_format(pipe->plane_state->format, &bpe) ? 1 : 0; |
335 | } |
336 | input->src.dcc_rate = 1; |
337 | input->src.meta_pitch = pipe->plane_state->dcc.meta_pitch; |
338 | input->src.source_scan = dm_horz; |
339 | input->src.sw_mode = pipe->plane_state->tiling_info.gfx9.swizzle; |
340 | |
341 | input->src.viewport_width = pipe->plane_res.scl_data.viewport.width; |
342 | input->src.viewport_height = pipe->plane_res.scl_data.viewport.height; |
343 | input->src.data_pitch = pipe->plane_res.scl_data.viewport.width; |
344 | input->src.data_pitch_c = pipe->plane_res.scl_data.viewport.width; |
345 | input->src.cur0_src_width = 128; /* TODO: Cursor calcs, not curently stored */ |
346 | input->src.cur0_bpp = 32; |
347 | |
348 | input->src.macro_tile_size = swizzle_mode_to_macro_tile_size(sw_mode: pipe->plane_state->tiling_info.gfx9.swizzle); |
349 | |
350 | switch (pipe->plane_state->rotation) { |
351 | case ROTATION_ANGLE_0: |
352 | case ROTATION_ANGLE_180: |
353 | input->src.source_scan = dm_horz; |
354 | break; |
355 | case ROTATION_ANGLE_90: |
356 | case ROTATION_ANGLE_270: |
357 | input->src.source_scan = dm_vert; |
358 | break; |
359 | default: |
360 | ASSERT(0); /* Not supported */ |
361 | break; |
362 | } |
363 | |
364 | /* TODO: Fix pixel format mappings */ |
365 | switch (pipe->plane_state->format) { |
366 | case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: |
367 | case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: |
368 | input->src.source_format = dm_420_8; |
369 | input->src.viewport_width_c = input->src.viewport_width / 2; |
370 | input->src.viewport_height_c = input->src.viewport_height / 2; |
371 | break; |
372 | case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: |
373 | case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: |
374 | input->src.source_format = dm_420_10; |
375 | input->src.viewport_width_c = input->src.viewport_width / 2; |
376 | input->src.viewport_height_c = input->src.viewport_height / 2; |
377 | break; |
378 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: |
379 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: |
380 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: |
381 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: |
382 | input->src.source_format = dm_444_64; |
383 | input->src.viewport_width_c = input->src.viewport_width; |
384 | input->src.viewport_height_c = input->src.viewport_height; |
385 | break; |
386 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
387 | input->src.source_format = dm_rgbe_alpha; |
388 | input->src.viewport_width_c = input->src.viewport_width; |
389 | input->src.viewport_height_c = input->src.viewport_height; |
390 | break; |
391 | default: |
392 | input->src.source_format = dm_444_32; |
393 | input->src.viewport_width_c = input->src.viewport_width; |
394 | input->src.viewport_height_c = input->src.viewport_height; |
395 | break; |
396 | } |
397 | |
398 | input->scale_taps.htaps = pipe->plane_res.scl_data.taps.h_taps; |
399 | input->scale_ratio_depth.hscl_ratio = pipe->plane_res.scl_data.ratios.horz.value/4294967296.0; |
400 | input->scale_ratio_depth.vscl_ratio = pipe->plane_res.scl_data.ratios.vert.value/4294967296.0; |
401 | input->scale_ratio_depth.vinit = pipe->plane_res.scl_data.inits.v.value/4294967296.0; |
402 | if (input->scale_ratio_depth.vinit < 1.0) |
403 | input->scale_ratio_depth.vinit = 1; |
404 | input->scale_taps.vtaps = pipe->plane_res.scl_data.taps.v_taps; |
405 | input->scale_taps.vtaps_c = pipe->plane_res.scl_data.taps.v_taps_c; |
406 | input->scale_taps.htaps_c = pipe->plane_res.scl_data.taps.h_taps_c; |
407 | input->scale_ratio_depth.hscl_ratio_c = pipe->plane_res.scl_data.ratios.horz_c.value/4294967296.0; |
408 | input->scale_ratio_depth.vscl_ratio_c = pipe->plane_res.scl_data.ratios.vert_c.value/4294967296.0; |
409 | input->scale_ratio_depth.vinit_c = pipe->plane_res.scl_data.inits.v_c.value/4294967296.0; |
410 | if (input->scale_ratio_depth.vinit_c < 1.0) |
411 | input->scale_ratio_depth.vinit_c = 1; |
412 | switch (pipe->plane_res.scl_data.lb_params.depth) { |
413 | case LB_PIXEL_DEPTH_30BPP: |
414 | input->scale_ratio_depth.lb_depth = 30; break; |
415 | case LB_PIXEL_DEPTH_36BPP: |
416 | input->scale_ratio_depth.lb_depth = 36; break; |
417 | default: |
418 | input->scale_ratio_depth.lb_depth = 24; break; |
419 | } |
420 | |
421 | |
422 | input->dest.vactive = pipe->stream->timing.v_addressable + pipe->stream->timing.v_border_top |
423 | + pipe->stream->timing.v_border_bottom; |
424 | |
425 | input->dest.recout_width = pipe->plane_res.scl_data.recout.width; |
426 | input->dest.recout_height = pipe->plane_res.scl_data.recout.height; |
427 | |
428 | input->dest.full_recout_width = pipe->plane_res.scl_data.recout.width; |
429 | input->dest.full_recout_height = pipe->plane_res.scl_data.recout.height; |
430 | |
431 | input->dest.htotal = pipe->stream->timing.h_total; |
432 | input->dest.hblank_start = input->dest.htotal - pipe->stream->timing.h_front_porch; |
433 | input->dest.hblank_end = input->dest.hblank_start |
434 | - pipe->stream->timing.h_addressable |
435 | - pipe->stream->timing.h_border_left |
436 | - pipe->stream->timing.h_border_right; |
437 | |
438 | input->dest.vtotal = pipe->stream->timing.v_total; |
439 | input->dest.vblank_start = input->dest.vtotal - pipe->stream->timing.v_front_porch; |
440 | input->dest.vblank_end = input->dest.vblank_start |
441 | - pipe->stream->timing.v_addressable |
442 | - pipe->stream->timing.v_border_bottom |
443 | - pipe->stream->timing.v_border_top; |
444 | input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_100hz/10000.0; |
445 | input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start; |
446 | input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset; |
447 | input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset; |
448 | input->dest.vupdate_width = pipe->pipe_dlg_param.vupdate_width; |
449 | |
450 | } |
451 | |
452 | static void dcn_bw_calc_rq_dlg_ttu( |
453 | const struct dc *dc, |
454 | const struct dcn_bw_internal_vars *v, |
455 | struct pipe_ctx *pipe, |
456 | int in_idx) |
457 | { |
458 | struct display_mode_lib *dml = (struct display_mode_lib *)(&dc->dml); |
459 | struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &pipe->dlg_regs; |
460 | struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &pipe->ttu_regs; |
461 | struct _vcs_dpi_display_rq_regs_st *rq_regs = &pipe->rq_regs; |
462 | struct _vcs_dpi_display_rq_params_st *rq_param = &pipe->dml_rq_param; |
463 | struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param = &pipe->dml_dlg_sys_param; |
464 | struct _vcs_dpi_display_e2e_pipe_params_st *input = &pipe->dml_input; |
465 | float total_active_bw = 0; |
466 | float total_prefetch_bw = 0; |
467 | int total_flip_bytes = 0; |
468 | int i; |
469 | |
470 | memset(dlg_regs, 0, sizeof(*dlg_regs)); |
471 | memset(ttu_regs, 0, sizeof(*ttu_regs)); |
472 | memset(rq_regs, 0, sizeof(*rq_regs)); |
473 | memset(rq_param, 0, sizeof(*rq_param)); |
474 | memset(dlg_sys_param, 0, sizeof(*dlg_sys_param)); |
475 | memset(input, 0, sizeof(*input)); |
476 | |
477 | for (i = 0; i < number_of_planes; i++) { |
478 | total_active_bw += v->read_bandwidth[i]; |
479 | total_prefetch_bw += v->prefetch_bandwidth[i]; |
480 | total_flip_bytes += v->total_immediate_flip_bytes[i]; |
481 | } |
482 | dlg_sys_param->total_flip_bw = v->return_bw - dcn_bw_max2(arg1: total_active_bw, arg2: total_prefetch_bw); |
483 | if (dlg_sys_param->total_flip_bw < 0.0) |
484 | dlg_sys_param->total_flip_bw = 0; |
485 | |
486 | dlg_sys_param->t_mclk_wm_us = v->dram_clock_change_watermark; |
487 | dlg_sys_param->t_sr_wm_us = v->stutter_enter_plus_exit_watermark; |
488 | dlg_sys_param->t_urg_wm_us = v->urgent_watermark; |
489 | dlg_sys_param->t_extra_us = v->urgent_extra_latency; |
490 | dlg_sys_param->deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep; |
491 | dlg_sys_param->total_flip_bytes = total_flip_bytes; |
492 | |
493 | pipe_ctx_to_e2e_pipe_params(pipe, input: &input->pipe); |
494 | input->clks_cfg.dcfclk_mhz = v->dcfclk; |
495 | input->clks_cfg.dispclk_mhz = v->dispclk; |
496 | input->clks_cfg.dppclk_mhz = v->dppclk; |
497 | input->clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; |
498 | input->clks_cfg.socclk_mhz = v->socclk; |
499 | input->clks_cfg.voltage = v->voltage_level; |
500 | // dc->dml.logger = pool->base.logger; |
501 | input->dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444; |
502 | input->dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp; |
503 | //input[in_idx].dout.output_standard; |
504 | |
505 | /*todo: soc->sr_enter_plus_exit_time??*/ |
506 | |
507 | dml1_rq_dlg_get_rq_params(mode_lib: dml, rq_param, pipe_src_param: &input->pipe.src); |
508 | dml1_extract_rq_regs(mode_lib: dml, rq_regs, rq_param); |
509 | dml1_rq_dlg_get_dlg_params( |
510 | mode_lib: dml, |
511 | dlg_regs, |
512 | ttu_regs, |
513 | rq_dlg_param: &rq_param->dlg, |
514 | dlg_sys_param, |
515 | e2e_pipe_param: input, |
516 | cstate_en: true, |
517 | pstate_en: true, |
518 | vm_en: v->pte_enable == dcn_bw_yes, |
519 | iflip_en: pipe->plane_state->flip_immediate); |
520 | } |
521 | |
522 | static void split_stream_across_pipes( |
523 | struct resource_context *res_ctx, |
524 | const struct resource_pool *pool, |
525 | struct pipe_ctx *primary_pipe, |
526 | struct pipe_ctx *secondary_pipe) |
527 | { |
528 | int pipe_idx = secondary_pipe->pipe_idx; |
529 | |
530 | if (!primary_pipe->plane_state) |
531 | return; |
532 | |
533 | *secondary_pipe = *primary_pipe; |
534 | |
535 | secondary_pipe->pipe_idx = pipe_idx; |
536 | secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx]; |
537 | secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx]; |
538 | secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx]; |
539 | secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx]; |
540 | secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx]; |
541 | secondary_pipe->plane_res.mpcc_inst = pool->dpps[secondary_pipe->pipe_idx]->inst; |
542 | if (primary_pipe->bottom_pipe) { |
543 | ASSERT(primary_pipe->bottom_pipe != secondary_pipe); |
544 | secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe; |
545 | secondary_pipe->bottom_pipe->top_pipe = secondary_pipe; |
546 | } |
547 | primary_pipe->bottom_pipe = secondary_pipe; |
548 | secondary_pipe->top_pipe = primary_pipe; |
549 | |
550 | resource_build_scaling_params(pipe_ctx: primary_pipe); |
551 | resource_build_scaling_params(pipe_ctx: secondary_pipe); |
552 | } |
553 | |
554 | #if 0 |
555 | static void calc_wm_sets_and_perf_params( |
556 | struct dc_state *context, |
557 | struct dcn_bw_internal_vars *v) |
558 | { |
559 | /* Calculate set A last to keep internal var state consistent for required config */ |
560 | if (v->voltage_level < 2) { |
561 | v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vnom0p8; |
562 | v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vnom0p8; |
563 | v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vnom0p8; |
564 | dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); |
565 | |
566 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = |
567 | v->stutter_exit_watermark * 1000; |
568 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = |
569 | v->stutter_enter_plus_exit_watermark * 1000; |
570 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = |
571 | v->dram_clock_change_watermark * 1000; |
572 | context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; |
573 | context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = v->urgent_watermark * 1000; |
574 | |
575 | v->dcfclk_per_state[1] = v->dcfclkv_nom0p8; |
576 | v->dcfclk_per_state[0] = v->dcfclkv_nom0p8; |
577 | v->dcfclk = v->dcfclkv_nom0p8; |
578 | dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); |
579 | |
580 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = |
581 | v->stutter_exit_watermark * 1000; |
582 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = |
583 | v->stutter_enter_plus_exit_watermark * 1000; |
584 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = |
585 | v->dram_clock_change_watermark * 1000; |
586 | context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; |
587 | context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = v->urgent_watermark * 1000; |
588 | } |
589 | |
590 | if (v->voltage_level < 3) { |
591 | v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vmax0p9; |
592 | v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmax0p9; |
593 | v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmax0p9; |
594 | v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vmax0p9; |
595 | v->dcfclk_per_state[2] = v->dcfclkv_max0p9; |
596 | v->dcfclk_per_state[1] = v->dcfclkv_max0p9; |
597 | v->dcfclk_per_state[0] = v->dcfclkv_max0p9; |
598 | v->dcfclk = v->dcfclkv_max0p9; |
599 | dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); |
600 | |
601 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = |
602 | v->stutter_exit_watermark * 1000; |
603 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = |
604 | v->stutter_enter_plus_exit_watermark * 1000; |
605 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = |
606 | v->dram_clock_change_watermark * 1000; |
607 | context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; |
608 | context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = v->urgent_watermark * 1000; |
609 | } |
610 | |
611 | v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8; |
612 | v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmid0p72; |
613 | v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmin0p65; |
614 | v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_per_state[v->voltage_level]; |
615 | v->dcfclk_per_state[2] = v->dcfclkv_nom0p8; |
616 | v->dcfclk_per_state[1] = v->dcfclkv_mid0p72; |
617 | v->dcfclk_per_state[0] = v->dcfclkv_min0p65; |
618 | v->dcfclk = v->dcfclk_per_state[v->voltage_level]; |
619 | dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); |
620 | |
621 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = |
622 | v->stutter_exit_watermark * 1000; |
623 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = |
624 | v->stutter_enter_plus_exit_watermark * 1000; |
625 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = |
626 | v->dram_clock_change_watermark * 1000; |
627 | context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; |
628 | context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; |
629 | if (v->voltage_level >= 2) { |
630 | context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a; |
631 | context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a; |
632 | } |
633 | if (v->voltage_level >= 3) |
634 | context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; |
635 | } |
636 | #endif |
637 | |
638 | static bool dcn_bw_apply_registry_override(struct dc *dc) |
639 | { |
640 | bool updated = false; |
641 | |
642 | if ((int)(dc->dcn_soc->sr_exit_time * 1000) != dc->debug.sr_exit_time_ns |
643 | && dc->debug.sr_exit_time_ns) { |
644 | updated = true; |
645 | dc->dcn_soc->sr_exit_time = dc->debug.sr_exit_time_ns / 1000.0; |
646 | } |
647 | |
648 | if ((int)(dc->dcn_soc->sr_enter_plus_exit_time * 1000) |
649 | != dc->debug.sr_enter_plus_exit_time_ns |
650 | && dc->debug.sr_enter_plus_exit_time_ns) { |
651 | updated = true; |
652 | dc->dcn_soc->sr_enter_plus_exit_time = |
653 | dc->debug.sr_enter_plus_exit_time_ns / 1000.0; |
654 | } |
655 | |
656 | if ((int)(dc->dcn_soc->urgent_latency * 1000) != dc->debug.urgent_latency_ns |
657 | && dc->debug.urgent_latency_ns) { |
658 | updated = true; |
659 | dc->dcn_soc->urgent_latency = dc->debug.urgent_latency_ns / 1000.0; |
660 | } |
661 | |
662 | if ((int)(dc->dcn_soc->percent_of_ideal_drambw_received_after_urg_latency * 1000) |
663 | != dc->debug.percent_of_ideal_drambw |
664 | && dc->debug.percent_of_ideal_drambw) { |
665 | updated = true; |
666 | dc->dcn_soc->percent_of_ideal_drambw_received_after_urg_latency = |
667 | dc->debug.percent_of_ideal_drambw; |
668 | } |
669 | |
670 | if ((int)(dc->dcn_soc->dram_clock_change_latency * 1000) |
671 | != dc->debug.dram_clock_change_latency_ns |
672 | && dc->debug.dram_clock_change_latency_ns) { |
673 | updated = true; |
674 | dc->dcn_soc->dram_clock_change_latency = |
675 | dc->debug.dram_clock_change_latency_ns / 1000.0; |
676 | } |
677 | |
678 | return updated; |
679 | } |
680 | |
681 | static void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v) |
682 | { |
683 | /* |
684 | * disable optional pipe split by lower dispclk bounding box |
685 | * at DPM0 |
686 | */ |
687 | v->max_dispclk[0] = v->max_dppclk_vmin0p65; |
688 | } |
689 | |
690 | static void hack_force_pipe_split(struct dcn_bw_internal_vars *v, |
691 | unsigned int pixel_rate_100hz) |
692 | { |
693 | float pixel_rate_mhz = pixel_rate_100hz / 10000; |
694 | |
695 | /* |
696 | * force enabling pipe split by lower dpp clock for DPM0 to just |
697 | * below the specify pixel_rate, so bw calc would split pipe. |
698 | */ |
699 | if (pixel_rate_mhz < v->max_dppclk[0]) |
700 | v->max_dppclk[0] = pixel_rate_mhz; |
701 | } |
702 | |
703 | static void hack_bounding_box(struct dcn_bw_internal_vars *v, |
704 | struct dc_debug_options *dbg, |
705 | struct dc_state *context) |
706 | { |
707 | int i; |
708 | |
709 | for (i = 0; i < MAX_PIPES; i++) { |
710 | struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; |
711 | |
712 | /** |
713 | * Workaround for avoiding pipe-split in cases where we'd split |
714 | * planes that are too small, resulting in splits that aren't |
715 | * valid for the scaler. |
716 | */ |
717 | if (pipe->plane_state && |
718 | (pipe->plane_state->dst_rect.width <= 16 || |
719 | pipe->plane_state->dst_rect.height <= 16 || |
720 | pipe->plane_state->src_rect.width <= 16 || |
721 | pipe->plane_state->src_rect.height <= 16)) { |
722 | hack_disable_optional_pipe_split(v); |
723 | return; |
724 | } |
725 | } |
726 | |
727 | if (dbg->pipe_split_policy == MPC_SPLIT_AVOID) |
728 | hack_disable_optional_pipe_split(v); |
729 | |
730 | if (dbg->pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP && |
731 | context->stream_count >= 2) |
732 | hack_disable_optional_pipe_split(v); |
733 | |
734 | if (context->stream_count == 1 && |
735 | dbg->force_single_disp_pipe_split) |
736 | hack_force_pipe_split(v, pixel_rate_100hz: context->streams[0]->timing.pix_clk_100hz); |
737 | } |
738 | |
739 | static unsigned int get_highest_allowed_voltage_level(bool is_vmin_only_asic) |
740 | { |
741 | /* for low power RV2 variants, the highest voltage level we want is 0 */ |
742 | if (is_vmin_only_asic) |
743 | return 0; |
744 | else /* we are ok with all levels */ |
745 | return 4; |
746 | } |
747 | |
748 | bool dcn_validate_bandwidth( |
749 | struct dc *dc, |
750 | struct dc_state *context, |
751 | bool fast_validate) |
752 | { |
753 | /* |
754 | * we want a breakdown of the various stages of validation, which the |
755 | * perf_trace macro doesn't support |
756 | */ |
757 | BW_VAL_TRACE_SETUP(); |
758 | |
759 | const struct resource_pool *pool = dc->res_pool; |
760 | struct dcn_bw_internal_vars *v = &context->dcn_bw_vars; |
761 | int i, input_idx, k; |
762 | int vesa_sync_start, asic_blank_end, asic_blank_start; |
763 | bool bw_limit_pass; |
764 | float bw_limit; |
765 | |
766 | PERFORMANCE_TRACE_START(); |
767 | |
768 | BW_VAL_TRACE_COUNT(); |
769 | |
770 | if (dcn_bw_apply_registry_override(dc)) |
771 | dcn_bw_sync_calcs_and_dml(dc); |
772 | |
773 | memset(v, 0, sizeof(*v)); |
774 | |
775 | v->sr_exit_time = dc->dcn_soc->sr_exit_time; |
776 | v->sr_enter_plus_exit_time = dc->dcn_soc->sr_enter_plus_exit_time; |
777 | v->urgent_latency = dc->dcn_soc->urgent_latency; |
778 | v->write_back_latency = dc->dcn_soc->write_back_latency; |
779 | v->percent_of_ideal_drambw_received_after_urg_latency = |
780 | dc->dcn_soc->percent_of_ideal_drambw_received_after_urg_latency; |
781 | |
782 | v->dcfclkv_min0p65 = dc->dcn_soc->dcfclkv_min0p65; |
783 | v->dcfclkv_mid0p72 = dc->dcn_soc->dcfclkv_mid0p72; |
784 | v->dcfclkv_nom0p8 = dc->dcn_soc->dcfclkv_nom0p8; |
785 | v->dcfclkv_max0p9 = dc->dcn_soc->dcfclkv_max0p9; |
786 | |
787 | v->max_dispclk_vmin0p65 = dc->dcn_soc->max_dispclk_vmin0p65; |
788 | v->max_dispclk_vmid0p72 = dc->dcn_soc->max_dispclk_vmid0p72; |
789 | v->max_dispclk_vnom0p8 = dc->dcn_soc->max_dispclk_vnom0p8; |
790 | v->max_dispclk_vmax0p9 = dc->dcn_soc->max_dispclk_vmax0p9; |
791 | |
792 | v->max_dppclk_vmin0p65 = dc->dcn_soc->max_dppclk_vmin0p65; |
793 | v->max_dppclk_vmid0p72 = dc->dcn_soc->max_dppclk_vmid0p72; |
794 | v->max_dppclk_vnom0p8 = dc->dcn_soc->max_dppclk_vnom0p8; |
795 | v->max_dppclk_vmax0p9 = dc->dcn_soc->max_dppclk_vmax0p9; |
796 | |
797 | v->socclk = dc->dcn_soc->socclk; |
798 | |
799 | v->fabric_and_dram_bandwidth_vmin0p65 = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65; |
800 | v->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72; |
801 | v->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8; |
802 | v->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9; |
803 | |
804 | v->phyclkv_min0p65 = dc->dcn_soc->phyclkv_min0p65; |
805 | v->phyclkv_mid0p72 = dc->dcn_soc->phyclkv_mid0p72; |
806 | v->phyclkv_nom0p8 = dc->dcn_soc->phyclkv_nom0p8; |
807 | v->phyclkv_max0p9 = dc->dcn_soc->phyclkv_max0p9; |
808 | |
809 | v->downspreading = dc->dcn_soc->downspreading; |
810 | v->round_trip_ping_latency_cycles = dc->dcn_soc->round_trip_ping_latency_cycles; |
811 | v->urgent_out_of_order_return_per_channel = dc->dcn_soc->urgent_out_of_order_return_per_channel; |
812 | v->number_of_channels = dc->dcn_soc->number_of_channels; |
813 | v->vmm_page_size = dc->dcn_soc->vmm_page_size; |
814 | v->dram_clock_change_latency = dc->dcn_soc->dram_clock_change_latency; |
815 | v->return_bus_width = dc->dcn_soc->return_bus_width; |
816 | |
817 | v->rob_buffer_size_in_kbyte = dc->dcn_ip->rob_buffer_size_in_kbyte; |
818 | v->det_buffer_size_in_kbyte = dc->dcn_ip->det_buffer_size_in_kbyte; |
819 | v->dpp_output_buffer_pixels = dc->dcn_ip->dpp_output_buffer_pixels; |
820 | v->opp_output_buffer_lines = dc->dcn_ip->opp_output_buffer_lines; |
821 | v->pixel_chunk_size_in_kbyte = dc->dcn_ip->pixel_chunk_size_in_kbyte; |
822 | v->pte_enable = dc->dcn_ip->pte_enable; |
823 | v->pte_chunk_size = dc->dcn_ip->pte_chunk_size; |
824 | v->meta_chunk_size = dc->dcn_ip->meta_chunk_size; |
825 | v->writeback_chunk_size = dc->dcn_ip->writeback_chunk_size; |
826 | v->odm_capability = dc->dcn_ip->odm_capability; |
827 | v->dsc_capability = dc->dcn_ip->dsc_capability; |
828 | v->line_buffer_size = dc->dcn_ip->line_buffer_size; |
829 | v->is_line_buffer_bpp_fixed = dc->dcn_ip->is_line_buffer_bpp_fixed; |
830 | v->line_buffer_fixed_bpp = dc->dcn_ip->line_buffer_fixed_bpp; |
831 | v->max_line_buffer_lines = dc->dcn_ip->max_line_buffer_lines; |
832 | v->writeback_luma_buffer_size = dc->dcn_ip->writeback_luma_buffer_size; |
833 | v->writeback_chroma_buffer_size = dc->dcn_ip->writeback_chroma_buffer_size; |
834 | v->max_num_dpp = dc->dcn_ip->max_num_dpp; |
835 | v->max_num_writeback = dc->dcn_ip->max_num_writeback; |
836 | v->max_dchub_topscl_throughput = dc->dcn_ip->max_dchub_topscl_throughput; |
837 | v->max_pscl_tolb_throughput = dc->dcn_ip->max_pscl_tolb_throughput; |
838 | v->max_lb_tovscl_throughput = dc->dcn_ip->max_lb_tovscl_throughput; |
839 | v->max_vscl_tohscl_throughput = dc->dcn_ip->max_vscl_tohscl_throughput; |
840 | v->max_hscl_ratio = dc->dcn_ip->max_hscl_ratio; |
841 | v->max_vscl_ratio = dc->dcn_ip->max_vscl_ratio; |
842 | v->max_hscl_taps = dc->dcn_ip->max_hscl_taps; |
843 | v->max_vscl_taps = dc->dcn_ip->max_vscl_taps; |
844 | v->under_scan_factor = dc->dcn_ip->under_scan_factor; |
845 | v->pte_buffer_size_in_requests = dc->dcn_ip->pte_buffer_size_in_requests; |
846 | v->dispclk_ramping_margin = dc->dcn_ip->dispclk_ramping_margin; |
847 | v->max_inter_dcn_tile_repeaters = dc->dcn_ip->max_inter_dcn_tile_repeaters; |
848 | v->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = |
849 | dc->dcn_ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; |
850 | v->bug_forcing_luma_and_chroma_request_to_same_size_fixed = |
851 | dc->dcn_ip->bug_forcing_luma_and_chroma_request_to_same_size_fixed; |
852 | |
853 | v->voltage[5] = dcn_bw_no_support; |
854 | v->voltage[4] = dcn_bw_v_max0p9; |
855 | v->voltage[3] = dcn_bw_v_max0p9; |
856 | v->voltage[2] = dcn_bw_v_nom0p8; |
857 | v->voltage[1] = dcn_bw_v_mid0p72; |
858 | v->voltage[0] = dcn_bw_v_min0p65; |
859 | v->fabric_and_dram_bandwidth_per_state[5] = v->fabric_and_dram_bandwidth_vmax0p9; |
860 | v->fabric_and_dram_bandwidth_per_state[4] = v->fabric_and_dram_bandwidth_vmax0p9; |
861 | v->fabric_and_dram_bandwidth_per_state[3] = v->fabric_and_dram_bandwidth_vmax0p9; |
862 | v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8; |
863 | v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmid0p72; |
864 | v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmin0p65; |
865 | v->dcfclk_per_state[5] = v->dcfclkv_max0p9; |
866 | v->dcfclk_per_state[4] = v->dcfclkv_max0p9; |
867 | v->dcfclk_per_state[3] = v->dcfclkv_max0p9; |
868 | v->dcfclk_per_state[2] = v->dcfclkv_nom0p8; |
869 | v->dcfclk_per_state[1] = v->dcfclkv_mid0p72; |
870 | v->dcfclk_per_state[0] = v->dcfclkv_min0p65; |
871 | v->max_dispclk[5] = v->max_dispclk_vmax0p9; |
872 | v->max_dispclk[4] = v->max_dispclk_vmax0p9; |
873 | v->max_dispclk[3] = v->max_dispclk_vmax0p9; |
874 | v->max_dispclk[2] = v->max_dispclk_vnom0p8; |
875 | v->max_dispclk[1] = v->max_dispclk_vmid0p72; |
876 | v->max_dispclk[0] = v->max_dispclk_vmin0p65; |
877 | v->max_dppclk[5] = v->max_dppclk_vmax0p9; |
878 | v->max_dppclk[4] = v->max_dppclk_vmax0p9; |
879 | v->max_dppclk[3] = v->max_dppclk_vmax0p9; |
880 | v->max_dppclk[2] = v->max_dppclk_vnom0p8; |
881 | v->max_dppclk[1] = v->max_dppclk_vmid0p72; |
882 | v->max_dppclk[0] = v->max_dppclk_vmin0p65; |
883 | v->phyclk_per_state[5] = v->phyclkv_max0p9; |
884 | v->phyclk_per_state[4] = v->phyclkv_max0p9; |
885 | v->phyclk_per_state[3] = v->phyclkv_max0p9; |
886 | v->phyclk_per_state[2] = v->phyclkv_nom0p8; |
887 | v->phyclk_per_state[1] = v->phyclkv_mid0p72; |
888 | v->phyclk_per_state[0] = v->phyclkv_min0p65; |
889 | v->synchronized_vblank = dcn_bw_no; |
890 | v->ta_pscalculation = dcn_bw_override; |
891 | v->allow_different_hratio_vratio = dcn_bw_yes; |
892 | |
893 | for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { |
894 | struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; |
895 | |
896 | if (!pipe->stream) |
897 | continue; |
898 | /* skip all but first of split pipes */ |
899 | if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) |
900 | continue; |
901 | |
902 | v->underscan_output[input_idx] = false; /* taken care of in recout already*/ |
903 | v->interlace_output[input_idx] = false; |
904 | |
905 | v->htotal[input_idx] = pipe->stream->timing.h_total; |
906 | v->vtotal[input_idx] = pipe->stream->timing.v_total; |
907 | v->vactive[input_idx] = pipe->stream->timing.v_addressable + |
908 | pipe->stream->timing.v_border_top + pipe->stream->timing.v_border_bottom; |
909 | v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total |
910 | - v->vactive[input_idx] |
911 | - pipe->stream->timing.v_front_porch; |
912 | v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_100hz/10000.0; |
913 | if (pipe->stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) |
914 | v->pixel_clock[input_idx] *= 2; |
915 | if (!pipe->plane_state) { |
916 | v->dcc_enable[input_idx] = dcn_bw_yes; |
917 | v->source_pixel_format[input_idx] = dcn_bw_rgb_sub_32; |
918 | v->source_surface_mode[input_idx] = dcn_bw_sw_4_kb_s; |
919 | v->lb_bit_per_pixel[input_idx] = 30; |
920 | v->viewport_width[input_idx] = pipe->stream->timing.h_addressable; |
921 | v->viewport_height[input_idx] = pipe->stream->timing.v_addressable; |
922 | /* |
923 | * for cases where we have no plane, we want to validate up to 1080p |
924 | * source size because here we are only interested in if the output |
925 | * timing is supported or not. if we cannot support native resolution |
926 | * of the high res display, we still want to support lower res up scale |
927 | * to native |
928 | */ |
929 | if (v->viewport_width[input_idx] > 1920) |
930 | v->viewport_width[input_idx] = 1920; |
931 | if (v->viewport_height[input_idx] > 1080) |
932 | v->viewport_height[input_idx] = 1080; |
933 | v->scaler_rec_out_width[input_idx] = v->viewport_width[input_idx]; |
934 | v->scaler_recout_height[input_idx] = v->viewport_height[input_idx]; |
935 | v->override_hta_ps[input_idx] = 1; |
936 | v->override_vta_ps[input_idx] = 1; |
937 | v->override_hta_pschroma[input_idx] = 1; |
938 | v->override_vta_pschroma[input_idx] = 1; |
939 | v->source_scan[input_idx] = dcn_bw_hor; |
940 | |
941 | } else { |
942 | v->viewport_height[input_idx] = pipe->plane_res.scl_data.viewport.height; |
943 | v->viewport_width[input_idx] = pipe->plane_res.scl_data.viewport.width; |
944 | v->scaler_rec_out_width[input_idx] = pipe->plane_res.scl_data.recout.width; |
945 | v->scaler_recout_height[input_idx] = pipe->plane_res.scl_data.recout.height; |
946 | if (pipe->bottom_pipe && pipe->bottom_pipe->plane_state == pipe->plane_state) { |
947 | if (pipe->plane_state->rotation % 2 == 0) { |
948 | int viewport_end = pipe->plane_res.scl_data.viewport.width |
949 | + pipe->plane_res.scl_data.viewport.x; |
950 | int viewport_b_end = pipe->bottom_pipe->plane_res.scl_data.viewport.width |
951 | + pipe->bottom_pipe->plane_res.scl_data.viewport.x; |
952 | |
953 | if (viewport_end > viewport_b_end) |
954 | v->viewport_width[input_idx] = viewport_end |
955 | - pipe->bottom_pipe->plane_res.scl_data.viewport.x; |
956 | else |
957 | v->viewport_width[input_idx] = viewport_b_end |
958 | - pipe->plane_res.scl_data.viewport.x; |
959 | } else { |
960 | int viewport_end = pipe->plane_res.scl_data.viewport.height |
961 | + pipe->plane_res.scl_data.viewport.y; |
962 | int viewport_b_end = pipe->bottom_pipe->plane_res.scl_data.viewport.height |
963 | + pipe->bottom_pipe->plane_res.scl_data.viewport.y; |
964 | |
965 | if (viewport_end > viewport_b_end) |
966 | v->viewport_height[input_idx] = viewport_end |
967 | - pipe->bottom_pipe->plane_res.scl_data.viewport.y; |
968 | else |
969 | v->viewport_height[input_idx] = viewport_b_end |
970 | - pipe->plane_res.scl_data.viewport.y; |
971 | } |
972 | v->scaler_rec_out_width[input_idx] = pipe->plane_res.scl_data.recout.width |
973 | + pipe->bottom_pipe->plane_res.scl_data.recout.width; |
974 | } |
975 | |
976 | if (pipe->plane_state->rotation % 2 == 0) { |
977 | ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dc_fixpt_one.value |
978 | || v->scaler_rec_out_width[input_idx] == v->viewport_width[input_idx]); |
979 | ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dc_fixpt_one.value |
980 | || v->scaler_recout_height[input_idx] == v->viewport_height[input_idx]); |
981 | } else { |
982 | ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dc_fixpt_one.value |
983 | || v->scaler_recout_height[input_idx] == v->viewport_width[input_idx]); |
984 | ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dc_fixpt_one.value |
985 | || v->scaler_rec_out_width[input_idx] == v->viewport_height[input_idx]); |
986 | } |
987 | |
988 | if (dc->debug.optimized_watermark) { |
989 | /* |
990 | * this method requires us to always re-calculate watermark when dcc change |
991 | * between flip. |
992 | */ |
993 | v->dcc_enable[input_idx] = pipe->plane_state->dcc.enable ? dcn_bw_yes : dcn_bw_no; |
994 | } else { |
995 | /* |
996 | * allow us to disable dcc on the fly without re-calculating WM |
997 | * |
998 | * extra overhead for DCC is quite small. for 1080p WM without |
999 | * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us) |
1000 | */ |
1001 | unsigned int bpe; |
1002 | |
1003 | v->dcc_enable[input_idx] = dc->res_pool->hubbub->funcs->dcc_support_pixel_format( |
1004 | pipe->plane_state->format, &bpe) ? dcn_bw_yes : dcn_bw_no; |
1005 | } |
1006 | |
1007 | v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs( |
1008 | format: pipe->plane_state->format); |
1009 | v->source_surface_mode[input_idx] = tl_sw_mode_to_bw_defs( |
1010 | sw_mode: pipe->plane_state->tiling_info.gfx9.swizzle); |
1011 | v->lb_bit_per_pixel[input_idx] = tl_lb_bpp_to_int(depth: pipe->plane_res.scl_data.lb_params.depth); |
1012 | v->override_hta_ps[input_idx] = pipe->plane_res.scl_data.taps.h_taps; |
1013 | v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps; |
1014 | v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c; |
1015 | v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c; |
1016 | /* |
1017 | * Spreadsheet doesn't handle taps_c is one properly, |
1018 | * need to force Chroma to always be scaled to pass |
1019 | * bandwidth validation. |
1020 | */ |
1021 | if (v->override_hta_pschroma[input_idx] == 1) |
1022 | v->override_hta_pschroma[input_idx] = 2; |
1023 | if (v->override_vta_pschroma[input_idx] == 1) |
1024 | v->override_vta_pschroma[input_idx] = 2; |
1025 | v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor; |
1026 | } |
1027 | if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) |
1028 | v->lb_bit_per_pixel[input_idx] = v->line_buffer_fixed_bpp; |
1029 | v->dcc_rate[input_idx] = 1; /*TODO: Worst case? does this change?*/ |
1030 | v->output_format[input_idx] = pipe->stream->timing.pixel_encoding == |
1031 | PIXEL_ENCODING_YCBCR420 ? dcn_bw_420 : dcn_bw_444; |
1032 | v->output[input_idx] = pipe->stream->signal == |
1033 | SIGNAL_TYPE_HDMI_TYPE_A ? dcn_bw_hdmi : dcn_bw_dp; |
1034 | v->output_deep_color[input_idx] = dcn_bw_encoder_8bpc; |
1035 | if (v->output[input_idx] == dcn_bw_hdmi) { |
1036 | switch (pipe->stream->timing.display_color_depth) { |
1037 | case COLOR_DEPTH_101010: |
1038 | v->output_deep_color[input_idx] = dcn_bw_encoder_10bpc; |
1039 | break; |
1040 | case COLOR_DEPTH_121212: |
1041 | v->output_deep_color[input_idx] = dcn_bw_encoder_12bpc; |
1042 | break; |
1043 | case COLOR_DEPTH_161616: |
1044 | v->output_deep_color[input_idx] = dcn_bw_encoder_16bpc; |
1045 | break; |
1046 | default: |
1047 | break; |
1048 | } |
1049 | } |
1050 | |
1051 | input_idx++; |
1052 | } |
1053 | v->number_of_active_planes = input_idx; |
1054 | |
1055 | scaler_settings_calculation(v); |
1056 | |
1057 | hack_bounding_box(v, dbg: &dc->debug, context); |
1058 | |
1059 | mode_support_and_system_configuration(v); |
1060 | |
1061 | /* Unhack dppclk: dont bother with trying to pipe split if we cannot maintain dpm0 */ |
1062 | if (v->voltage_level != 0 |
1063 | && context->stream_count == 1 |
1064 | && dc->debug.force_single_disp_pipe_split) { |
1065 | v->max_dppclk[0] = v->max_dppclk_vmin0p65; |
1066 | mode_support_and_system_configuration(v); |
1067 | } |
1068 | |
1069 | if (v->voltage_level == 0 && |
1070 | (dc->debug.sr_exit_time_dpm0_ns |
1071 | || dc->debug.sr_enter_plus_exit_time_dpm0_ns)) { |
1072 | |
1073 | if (dc->debug.sr_enter_plus_exit_time_dpm0_ns) |
1074 | v->sr_enter_plus_exit_time = |
1075 | dc->debug.sr_enter_plus_exit_time_dpm0_ns / 1000.0f; |
1076 | if (dc->debug.sr_exit_time_dpm0_ns) |
1077 | v->sr_exit_time = dc->debug.sr_exit_time_dpm0_ns / 1000.0f; |
1078 | context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = v->sr_enter_plus_exit_time; |
1079 | context->bw_ctx.dml.soc.sr_exit_time_us = v->sr_exit_time; |
1080 | mode_support_and_system_configuration(v); |
1081 | } |
1082 | |
1083 | display_pipe_configuration(v); |
1084 | |
1085 | for (k = 0; k <= v->number_of_active_planes - 1; k++) { |
1086 | if (v->source_scan[k] == dcn_bw_hor) |
1087 | v->swath_width_y[k] = v->viewport_width[k] / v->dpp_per_plane[k]; |
1088 | else |
1089 | v->swath_width_y[k] = v->viewport_height[k] / v->dpp_per_plane[k]; |
1090 | } |
1091 | for (k = 0; k <= v->number_of_active_planes - 1; k++) { |
1092 | if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { |
1093 | v->byte_per_pixel_dety[k] = 8.0; |
1094 | v->byte_per_pixel_detc[k] = 0.0; |
1095 | } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_32) { |
1096 | v->byte_per_pixel_dety[k] = 4.0; |
1097 | v->byte_per_pixel_detc[k] = 0.0; |
1098 | } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_16) { |
1099 | v->byte_per_pixel_dety[k] = 2.0; |
1100 | v->byte_per_pixel_detc[k] = 0.0; |
1101 | } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { |
1102 | v->byte_per_pixel_dety[k] = 1.0; |
1103 | v->byte_per_pixel_detc[k] = 2.0; |
1104 | } else { |
1105 | v->byte_per_pixel_dety[k] = 4.0f / 3.0f; |
1106 | v->byte_per_pixel_detc[k] = 8.0f / 3.0f; |
1107 | } |
1108 | } |
1109 | |
1110 | v->total_data_read_bandwidth = 0.0; |
1111 | for (k = 0; k <= v->number_of_active_planes - 1; k++) { |
1112 | v->read_bandwidth_plane_luma[k] = v->swath_width_y[k] * v->dpp_per_plane[k] * |
1113 | dcn_bw_ceil2(arg: v->byte_per_pixel_dety[k], significance: 1.0) / (v->htotal[k] / v->pixel_clock[k]) * v->v_ratio[k]; |
1114 | v->read_bandwidth_plane_chroma[k] = v->swath_width_y[k] / 2.0 * v->dpp_per_plane[k] * |
1115 | dcn_bw_ceil2(arg: v->byte_per_pixel_detc[k], significance: 2.0) / (v->htotal[k] / v->pixel_clock[k]) * v->v_ratio[k] / 2.0; |
1116 | v->total_data_read_bandwidth = v->total_data_read_bandwidth + |
1117 | v->read_bandwidth_plane_luma[k] + v->read_bandwidth_plane_chroma[k]; |
1118 | } |
1119 | |
1120 | BW_VAL_TRACE_END_VOLTAGE_LEVEL(); |
1121 | |
1122 | if (v->voltage_level != number_of_states_plus_one && !fast_validate) { |
1123 | float bw_consumed = v->total_bandwidth_consumed_gbyte_per_second; |
1124 | |
1125 | if (bw_consumed < v->fabric_and_dram_bandwidth_vmin0p65) |
1126 | bw_consumed = v->fabric_and_dram_bandwidth_vmin0p65; |
1127 | else if (bw_consumed < v->fabric_and_dram_bandwidth_vmid0p72) |
1128 | bw_consumed = v->fabric_and_dram_bandwidth_vmid0p72; |
1129 | else if (bw_consumed < v->fabric_and_dram_bandwidth_vnom0p8) |
1130 | bw_consumed = v->fabric_and_dram_bandwidth_vnom0p8; |
1131 | else |
1132 | bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9; |
1133 | |
1134 | if (bw_consumed < v->fabric_and_dram_bandwidth) |
1135 | if (dc->debug.voltage_align_fclk) |
1136 | bw_consumed = v->fabric_and_dram_bandwidth; |
1137 | |
1138 | display_pipe_configuration(v); |
1139 | /*calc_wm_sets_and_perf_params(context, v);*/ |
1140 | /* Only 1 set is used by dcn since no noticeable |
1141 | * performance improvement was measured and due to hw bug DEGVIDCN10-254 |
1142 | */ |
1143 | dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); |
1144 | |
1145 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = |
1146 | v->stutter_exit_watermark * 1000; |
1147 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = |
1148 | v->stutter_enter_plus_exit_watermark * 1000; |
1149 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = |
1150 | v->dram_clock_change_watermark * 1000; |
1151 | context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; |
1152 | context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; |
1153 | context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a; |
1154 | context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a; |
1155 | context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; |
1156 | |
1157 | context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / |
1158 | (ddr4_dram_factor_single_Channel * v->number_of_channels)); |
1159 | if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65) |
1160 | context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / 32); |
1161 | |
1162 | context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); |
1163 | context->bw_ctx.bw.dcn.clk.dcfclk_khz = (int)(v->dcfclk * 1000); |
1164 | |
1165 | context->bw_ctx.bw.dcn.clk.dispclk_khz = (int)(v->dispclk * 1000); |
1166 | if (dc->debug.max_disp_clk == true) |
1167 | context->bw_ctx.bw.dcn.clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); |
1168 | |
1169 | if (context->bw_ctx.bw.dcn.clk.dispclk_khz < |
1170 | dc->debug.min_disp_clk_khz) { |
1171 | context->bw_ctx.bw.dcn.clk.dispclk_khz = |
1172 | dc->debug.min_disp_clk_khz; |
1173 | } |
1174 | |
1175 | context->bw_ctx.bw.dcn.clk.dppclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz / |
1176 | v->dispclk_dppclk_ratio; |
1177 | context->bw_ctx.bw.dcn.clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; |
1178 | switch (v->voltage_level) { |
1179 | case 0: |
1180 | context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = |
1181 | (int)(dc->dcn_soc->max_dppclk_vmin0p65 * 1000); |
1182 | break; |
1183 | case 1: |
1184 | context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = |
1185 | (int)(dc->dcn_soc->max_dppclk_vmid0p72 * 1000); |
1186 | break; |
1187 | case 2: |
1188 | context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = |
1189 | (int)(dc->dcn_soc->max_dppclk_vnom0p8 * 1000); |
1190 | break; |
1191 | default: |
1192 | context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = |
1193 | (int)(dc->dcn_soc->max_dppclk_vmax0p9 * 1000); |
1194 | break; |
1195 | } |
1196 | |
1197 | BW_VAL_TRACE_END_WATERMARKS(); |
1198 | |
1199 | for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { |
1200 | struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; |
1201 | |
1202 | /* skip inactive pipe */ |
1203 | if (!pipe->stream) |
1204 | continue; |
1205 | /* skip all but first of split pipes */ |
1206 | if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) |
1207 | continue; |
1208 | |
1209 | pipe->pipe_dlg_param.vupdate_width = v->v_update_width_pix[input_idx]; |
1210 | pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset_pix[input_idx]; |
1211 | pipe->pipe_dlg_param.vready_offset = v->v_ready_offset_pix[input_idx]; |
1212 | pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx]; |
1213 | |
1214 | pipe->pipe_dlg_param.htotal = pipe->stream->timing.h_total; |
1215 | pipe->pipe_dlg_param.vtotal = pipe->stream->timing.v_total; |
1216 | vesa_sync_start = pipe->stream->timing.v_addressable + |
1217 | pipe->stream->timing.v_border_bottom + |
1218 | pipe->stream->timing.v_front_porch; |
1219 | |
1220 | asic_blank_end = (pipe->stream->timing.v_total - |
1221 | vesa_sync_start - |
1222 | pipe->stream->timing.v_border_top) |
1223 | * (pipe->stream->timing.flags.INTERLACE ? 1 : 0); |
1224 | |
1225 | asic_blank_start = asic_blank_end + |
1226 | (pipe->stream->timing.v_border_top + |
1227 | pipe->stream->timing.v_addressable + |
1228 | pipe->stream->timing.v_border_bottom) |
1229 | * (pipe->stream->timing.flags.INTERLACE ? 1 : 0); |
1230 | |
1231 | pipe->pipe_dlg_param.vblank_start = asic_blank_start; |
1232 | pipe->pipe_dlg_param.vblank_end = asic_blank_end; |
1233 | |
1234 | if (pipe->plane_state) { |
1235 | struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe; |
1236 | |
1237 | pipe->plane_state->update_flags.bits.full_update = 1; |
1238 | |
1239 | if (v->dpp_per_plane[input_idx] == 2 || |
1240 | ((pipe->stream->view_format == |
1241 | VIEW_3D_FORMAT_SIDE_BY_SIDE || |
1242 | pipe->stream->view_format == |
1243 | VIEW_3D_FORMAT_TOP_AND_BOTTOM) && |
1244 | (pipe->stream->timing.timing_3d_format == |
1245 | TIMING_3D_FORMAT_TOP_AND_BOTTOM || |
1246 | pipe->stream->timing.timing_3d_format == |
1247 | TIMING_3D_FORMAT_SIDE_BY_SIDE))) { |
1248 | if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) { |
1249 | /* update previously split pipe */ |
1250 | hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width_pix[input_idx]; |
1251 | hsplit_pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset_pix[input_idx]; |
1252 | hsplit_pipe->pipe_dlg_param.vready_offset = v->v_ready_offset_pix[input_idx]; |
1253 | hsplit_pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx]; |
1254 | |
1255 | hsplit_pipe->pipe_dlg_param.htotal = pipe->stream->timing.h_total; |
1256 | hsplit_pipe->pipe_dlg_param.vtotal = pipe->stream->timing.v_total; |
1257 | hsplit_pipe->pipe_dlg_param.vblank_start = pipe->pipe_dlg_param.vblank_start; |
1258 | hsplit_pipe->pipe_dlg_param.vblank_end = pipe->pipe_dlg_param.vblank_end; |
1259 | } else { |
1260 | /* pipe not split previously needs split */ |
1261 | hsplit_pipe = resource_find_free_secondary_pipe_legacy(res_ctx: &context->res_ctx, pool, primary_pipe: pipe); |
1262 | ASSERT(hsplit_pipe); |
1263 | split_stream_across_pipes(res_ctx: &context->res_ctx, pool, primary_pipe: pipe, secondary_pipe: hsplit_pipe); |
1264 | } |
1265 | |
1266 | dcn_bw_calc_rq_dlg_ttu(dc, v, pipe: hsplit_pipe, in_idx: input_idx); |
1267 | } else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) { |
1268 | /* merge previously split pipe */ |
1269 | pipe->bottom_pipe = hsplit_pipe->bottom_pipe; |
1270 | if (hsplit_pipe->bottom_pipe) |
1271 | hsplit_pipe->bottom_pipe->top_pipe = pipe; |
1272 | hsplit_pipe->plane_state = NULL; |
1273 | hsplit_pipe->stream = NULL; |
1274 | hsplit_pipe->top_pipe = NULL; |
1275 | hsplit_pipe->bottom_pipe = NULL; |
1276 | /* Clear plane_res and stream_res */ |
1277 | memset(&hsplit_pipe->plane_res, 0, sizeof(hsplit_pipe->plane_res)); |
1278 | memset(&hsplit_pipe->stream_res, 0, sizeof(hsplit_pipe->stream_res)); |
1279 | resource_build_scaling_params(pipe_ctx: pipe); |
1280 | } |
1281 | /* for now important to do this after pipe split for building e2e params */ |
1282 | dcn_bw_calc_rq_dlg_ttu(dc, v, pipe, in_idx: input_idx); |
1283 | } |
1284 | |
1285 | input_idx++; |
1286 | } |
1287 | } else if (v->voltage_level == number_of_states_plus_one) { |
1288 | BW_VAL_TRACE_SKIP(fail); |
1289 | } else if (fast_validate) { |
1290 | BW_VAL_TRACE_SKIP(fast); |
1291 | } |
1292 | |
1293 | if (v->voltage_level == 0) { |
1294 | context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = |
1295 | dc->dcn_soc->sr_enter_plus_exit_time; |
1296 | context->bw_ctx.dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time; |
1297 | } |
1298 | |
1299 | /* |
1300 | * BW limit is set to prevent display from impacting other system functions |
1301 | */ |
1302 | |
1303 | bw_limit = dc->dcn_soc->percent_disp_bw_limit * v->fabric_and_dram_bandwidth_vmax0p9; |
1304 | bw_limit_pass = (v->total_data_read_bandwidth / 1000.0) < bw_limit; |
1305 | |
1306 | PERFORMANCE_TRACE_END(); |
1307 | BW_VAL_TRACE_FINISH(); |
1308 | |
1309 | if (bw_limit_pass && v->voltage_level <= get_highest_allowed_voltage_level(is_vmin_only_asic: dc->config.is_vmin_only_asic)) |
1310 | return true; |
1311 | else |
1312 | return false; |
1313 | } |
1314 | |
1315 | static unsigned int dcn_find_normalized_clock_vdd_Level( |
1316 | const struct dc *dc, |
1317 | enum dm_pp_clock_type clocks_type, |
1318 | int clocks_in_khz) |
1319 | { |
1320 | int vdd_level = dcn_bw_v_min0p65; |
1321 | |
1322 | if (clocks_in_khz == 0)/*todo some clock not in the considerations*/ |
1323 | return vdd_level; |
1324 | |
1325 | switch (clocks_type) { |
1326 | case DM_PP_CLOCK_TYPE_DISPLAY_CLK: |
1327 | if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmax0p9*1000) { |
1328 | vdd_level = dcn_bw_v_max0p91; |
1329 | BREAK_TO_DEBUGGER(); |
1330 | } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vnom0p8*1000) { |
1331 | vdd_level = dcn_bw_v_max0p9; |
1332 | } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmid0p72*1000) { |
1333 | vdd_level = dcn_bw_v_nom0p8; |
1334 | } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmin0p65*1000) { |
1335 | vdd_level = dcn_bw_v_mid0p72; |
1336 | } else |
1337 | vdd_level = dcn_bw_v_min0p65; |
1338 | break; |
1339 | case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: |
1340 | if (clocks_in_khz > dc->dcn_soc->phyclkv_max0p9*1000) { |
1341 | vdd_level = dcn_bw_v_max0p91; |
1342 | BREAK_TO_DEBUGGER(); |
1343 | } else if (clocks_in_khz > dc->dcn_soc->phyclkv_nom0p8*1000) { |
1344 | vdd_level = dcn_bw_v_max0p9; |
1345 | } else if (clocks_in_khz > dc->dcn_soc->phyclkv_mid0p72*1000) { |
1346 | vdd_level = dcn_bw_v_nom0p8; |
1347 | } else if (clocks_in_khz > dc->dcn_soc->phyclkv_min0p65*1000) { |
1348 | vdd_level = dcn_bw_v_mid0p72; |
1349 | } else |
1350 | vdd_level = dcn_bw_v_min0p65; |
1351 | break; |
1352 | |
1353 | case DM_PP_CLOCK_TYPE_DPPCLK: |
1354 | if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmax0p9*1000) { |
1355 | vdd_level = dcn_bw_v_max0p91; |
1356 | BREAK_TO_DEBUGGER(); |
1357 | } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vnom0p8*1000) { |
1358 | vdd_level = dcn_bw_v_max0p9; |
1359 | } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmid0p72*1000) { |
1360 | vdd_level = dcn_bw_v_nom0p8; |
1361 | } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmin0p65*1000) { |
1362 | vdd_level = dcn_bw_v_mid0p72; |
1363 | } else |
1364 | vdd_level = dcn_bw_v_min0p65; |
1365 | break; |
1366 | |
1367 | case DM_PP_CLOCK_TYPE_MEMORY_CLK: |
1368 | { |
1369 | unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc->number_of_channels); |
1370 | |
1371 | if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9*1000000/factor) { |
1372 | vdd_level = dcn_bw_v_max0p91; |
1373 | BREAK_TO_DEBUGGER(); |
1374 | } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8*1000000/factor) { |
1375 | vdd_level = dcn_bw_v_max0p9; |
1376 | } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72*1000000/factor) { |
1377 | vdd_level = dcn_bw_v_nom0p8; |
1378 | } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65*1000000/factor) { |
1379 | vdd_level = dcn_bw_v_mid0p72; |
1380 | } else |
1381 | vdd_level = dcn_bw_v_min0p65; |
1382 | } |
1383 | break; |
1384 | |
1385 | case DM_PP_CLOCK_TYPE_DCFCLK: |
1386 | if (clocks_in_khz > dc->dcn_soc->dcfclkv_max0p9*1000) { |
1387 | vdd_level = dcn_bw_v_max0p91; |
1388 | BREAK_TO_DEBUGGER(); |
1389 | } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_nom0p8*1000) { |
1390 | vdd_level = dcn_bw_v_max0p9; |
1391 | } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_mid0p72*1000) { |
1392 | vdd_level = dcn_bw_v_nom0p8; |
1393 | } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_min0p65*1000) { |
1394 | vdd_level = dcn_bw_v_mid0p72; |
1395 | } else |
1396 | vdd_level = dcn_bw_v_min0p65; |
1397 | break; |
1398 | |
1399 | default: |
1400 | break; |
1401 | } |
1402 | return vdd_level; |
1403 | } |
1404 | |
1405 | unsigned int dcn_find_dcfclk_suits_all( |
1406 | const struct dc *dc, |
1407 | struct dc_clocks *clocks) |
1408 | { |
1409 | unsigned vdd_level, vdd_level_temp; |
1410 | unsigned dcf_clk; |
1411 | |
1412 | /*find a common supported voltage level*/ |
1413 | vdd_level = dcn_find_normalized_clock_vdd_Level( |
1414 | dc, clocks_type: DM_PP_CLOCK_TYPE_DISPLAY_CLK, clocks_in_khz: clocks->dispclk_khz); |
1415 | vdd_level_temp = dcn_find_normalized_clock_vdd_Level( |
1416 | dc, clocks_type: DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, clocks_in_khz: clocks->phyclk_khz); |
1417 | |
1418 | vdd_level = dcn_bw_max(arg1: vdd_level, arg2: vdd_level_temp); |
1419 | vdd_level_temp = dcn_find_normalized_clock_vdd_Level( |
1420 | dc, clocks_type: DM_PP_CLOCK_TYPE_DPPCLK, clocks_in_khz: clocks->dppclk_khz); |
1421 | vdd_level = dcn_bw_max(arg1: vdd_level, arg2: vdd_level_temp); |
1422 | |
1423 | vdd_level_temp = dcn_find_normalized_clock_vdd_Level( |
1424 | dc, clocks_type: DM_PP_CLOCK_TYPE_MEMORY_CLK, clocks_in_khz: clocks->fclk_khz); |
1425 | vdd_level = dcn_bw_max(arg1: vdd_level, arg2: vdd_level_temp); |
1426 | vdd_level_temp = dcn_find_normalized_clock_vdd_Level( |
1427 | dc, clocks_type: DM_PP_CLOCK_TYPE_DCFCLK, clocks_in_khz: clocks->dcfclk_khz); |
1428 | |
1429 | /*find that level conresponding dcfclk*/ |
1430 | vdd_level = dcn_bw_max(arg1: vdd_level, arg2: vdd_level_temp); |
1431 | if (vdd_level == dcn_bw_v_max0p91) { |
1432 | BREAK_TO_DEBUGGER(); |
1433 | dcf_clk = dc->dcn_soc->dcfclkv_max0p9*1000; |
1434 | } else if (vdd_level == dcn_bw_v_max0p9) |
1435 | dcf_clk = dc->dcn_soc->dcfclkv_max0p9*1000; |
1436 | else if (vdd_level == dcn_bw_v_nom0p8) |
1437 | dcf_clk = dc->dcn_soc->dcfclkv_nom0p8*1000; |
1438 | else if (vdd_level == dcn_bw_v_mid0p72) |
1439 | dcf_clk = dc->dcn_soc->dcfclkv_mid0p72*1000; |
1440 | else |
1441 | dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000; |
1442 | |
1443 | DC_LOG_BANDWIDTH_CALCS("\tdcf_clk for voltage = %d\n" , dcf_clk); |
1444 | return dcf_clk; |
1445 | } |
1446 | |
1447 | void dcn_bw_update_from_pplib_fclks( |
1448 | struct dc *dc, |
1449 | struct dm_pp_clock_levels_with_voltage *fclks) |
1450 | { |
1451 | unsigned vmin0p65_idx, vmid0p72_idx, vnom0p8_idx, vmax0p9_idx; |
1452 | |
1453 | ASSERT(fclks->num_levels); |
1454 | |
1455 | vmin0p65_idx = 0; |
1456 | vmid0p72_idx = fclks->num_levels - |
1457 | (fclks->num_levels > 2 ? 3 : (fclks->num_levels > 1 ? 2 : 1)); |
1458 | vnom0p8_idx = fclks->num_levels - (fclks->num_levels > 1 ? 2 : 1); |
1459 | vmax0p9_idx = fclks->num_levels - 1; |
1460 | |
1461 | dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = |
1462 | 32 * (fclks->data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0; |
1463 | dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = |
1464 | dc->dcn_soc->number_of_channels * |
1465 | (fclks->data[vmid0p72_idx].clocks_in_khz / 1000.0) |
1466 | * ddr4_dram_factor_single_Channel / 1000.0; |
1467 | dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = |
1468 | dc->dcn_soc->number_of_channels * |
1469 | (fclks->data[vnom0p8_idx].clocks_in_khz / 1000.0) |
1470 | * ddr4_dram_factor_single_Channel / 1000.0; |
1471 | dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = |
1472 | dc->dcn_soc->number_of_channels * |
1473 | (fclks->data[vmax0p9_idx].clocks_in_khz / 1000.0) |
1474 | * ddr4_dram_factor_single_Channel / 1000.0; |
1475 | } |
1476 | |
1477 | void dcn_bw_update_from_pplib_dcfclks( |
1478 | struct dc *dc, |
1479 | struct dm_pp_clock_levels_with_voltage *dcfclks) |
1480 | { |
1481 | if (dcfclks->num_levels >= 3) { |
1482 | dc->dcn_soc->dcfclkv_min0p65 = dcfclks->data[0].clocks_in_khz / 1000.0; |
1483 | dc->dcn_soc->dcfclkv_mid0p72 = dcfclks->data[dcfclks->num_levels - 3].clocks_in_khz / 1000.0; |
1484 | dc->dcn_soc->dcfclkv_nom0p8 = dcfclks->data[dcfclks->num_levels - 2].clocks_in_khz / 1000.0; |
1485 | dc->dcn_soc->dcfclkv_max0p9 = dcfclks->data[dcfclks->num_levels - 1].clocks_in_khz / 1000.0; |
1486 | } |
1487 | } |
1488 | |
1489 | void dcn_get_soc_clks( |
1490 | struct dc *dc, |
1491 | int *min_fclk_khz, |
1492 | int *min_dcfclk_khz, |
1493 | int *socclk_khz) |
1494 | { |
1495 | *min_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 * 1000000 / 32; |
1496 | *min_dcfclk_khz = dc->dcn_soc->dcfclkv_min0p65 * 1000; |
1497 | *socclk_khz = dc->dcn_soc->socclk * 1000; |
1498 | } |
1499 | |
1500 | void dcn_bw_notify_pplib_of_wm_ranges( |
1501 | struct dc *dc, |
1502 | int min_fclk_khz, |
1503 | int min_dcfclk_khz, |
1504 | int socclk_khz) |
1505 | { |
1506 | struct pp_smu_funcs_rv *pp = NULL; |
1507 | struct pp_smu_wm_range_sets ranges = {0}; |
1508 | const int overdrive = 5000000; /* 5 GHz to cover Overdrive */ |
1509 | |
1510 | if (dc->res_pool->pp_smu) |
1511 | pp = &dc->res_pool->pp_smu->rv_funcs; |
1512 | if (!pp || !pp->set_wm_ranges) |
1513 | return; |
1514 | |
1515 | /* Now notify PPLib/SMU about which Watermarks sets they should select |
1516 | * depending on DPM state they are in. And update BW MGR GFX Engine and |
1517 | * Memory clock member variables for Watermarks calculations for each |
1518 | * Watermark Set. Only one watermark set for dcn1 due to hw bug DEGVIDCN10-254. |
1519 | */ |
1520 | /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont |
1521 | * care what the value is, hence min to overdrive level |
1522 | */ |
1523 | ranges.num_reader_wm_sets = WM_SET_COUNT; |
1524 | ranges.num_writer_wm_sets = WM_SET_COUNT; |
1525 | ranges.reader_wm_sets[0].wm_inst = WM_A; |
1526 | ranges.reader_wm_sets[0].min_drain_clk_mhz = min_dcfclk_khz / 1000; |
1527 | ranges.reader_wm_sets[0].max_drain_clk_mhz = overdrive / 1000; |
1528 | ranges.reader_wm_sets[0].min_fill_clk_mhz = min_fclk_khz / 1000; |
1529 | ranges.reader_wm_sets[0].max_fill_clk_mhz = overdrive / 1000; |
1530 | ranges.writer_wm_sets[0].wm_inst = WM_A; |
1531 | ranges.writer_wm_sets[0].min_fill_clk_mhz = socclk_khz / 1000; |
1532 | ranges.writer_wm_sets[0].max_fill_clk_mhz = overdrive / 1000; |
1533 | ranges.writer_wm_sets[0].min_drain_clk_mhz = min_fclk_khz / 1000; |
1534 | ranges.writer_wm_sets[0].max_drain_clk_mhz = overdrive / 1000; |
1535 | |
1536 | if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) { |
1537 | ranges.reader_wm_sets[0].wm_inst = WM_A; |
1538 | ranges.reader_wm_sets[0].min_drain_clk_mhz = 300; |
1539 | ranges.reader_wm_sets[0].max_drain_clk_mhz = 5000; |
1540 | ranges.reader_wm_sets[0].min_fill_clk_mhz = 800; |
1541 | ranges.reader_wm_sets[0].max_fill_clk_mhz = 5000; |
1542 | ranges.writer_wm_sets[0].wm_inst = WM_A; |
1543 | ranges.writer_wm_sets[0].min_fill_clk_mhz = 200; |
1544 | ranges.writer_wm_sets[0].max_fill_clk_mhz = 5000; |
1545 | ranges.writer_wm_sets[0].min_drain_clk_mhz = 800; |
1546 | ranges.writer_wm_sets[0].max_drain_clk_mhz = 5000; |
1547 | } |
1548 | |
1549 | ranges.reader_wm_sets[1] = ranges.writer_wm_sets[0]; |
1550 | ranges.reader_wm_sets[1].wm_inst = WM_B; |
1551 | |
1552 | ranges.reader_wm_sets[2] = ranges.writer_wm_sets[0]; |
1553 | ranges.reader_wm_sets[2].wm_inst = WM_C; |
1554 | |
1555 | ranges.reader_wm_sets[3] = ranges.writer_wm_sets[0]; |
1556 | ranges.reader_wm_sets[3].wm_inst = WM_D; |
1557 | |
1558 | /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ |
1559 | pp->set_wm_ranges(&pp->pp_smu, &ranges); |
1560 | } |
1561 | |
1562 | void dcn_bw_sync_calcs_and_dml(struct dc *dc) |
1563 | { |
1564 | DC_LOG_BANDWIDTH_CALCS("sr_exit_time: %f ns\n" |
1565 | "sr_enter_plus_exit_time: %f ns\n" |
1566 | "urgent_latency: %f ns\n" |
1567 | "write_back_latency: %f ns\n" |
1568 | "percent_of_ideal_drambw_received_after_urg_latency: %f %%\n" |
1569 | "max_request_size: %d bytes\n" |
1570 | "dcfclkv_max0p9: %f kHz\n" |
1571 | "dcfclkv_nom0p8: %f kHz\n" |
1572 | "dcfclkv_mid0p72: %f kHz\n" |
1573 | "dcfclkv_min0p65: %f kHz\n" |
1574 | "max_dispclk_vmax0p9: %f kHz\n" |
1575 | "max_dispclk_vnom0p8: %f kHz\n" |
1576 | "max_dispclk_vmid0p72: %f kHz\n" |
1577 | "max_dispclk_vmin0p65: %f kHz\n" |
1578 | "max_dppclk_vmax0p9: %f kHz\n" |
1579 | "max_dppclk_vnom0p8: %f kHz\n" |
1580 | "max_dppclk_vmid0p72: %f kHz\n" |
1581 | "max_dppclk_vmin0p65: %f kHz\n" |
1582 | "socclk: %f kHz\n" |
1583 | "fabric_and_dram_bandwidth_vmax0p9: %f MB/s\n" |
1584 | "fabric_and_dram_bandwidth_vnom0p8: %f MB/s\n" |
1585 | "fabric_and_dram_bandwidth_vmid0p72: %f MB/s\n" |
1586 | "fabric_and_dram_bandwidth_vmin0p65: %f MB/s\n" |
1587 | "phyclkv_max0p9: %f kHz\n" |
1588 | "phyclkv_nom0p8: %f kHz\n" |
1589 | "phyclkv_mid0p72: %f kHz\n" |
1590 | "phyclkv_min0p65: %f kHz\n" |
1591 | "downspreading: %f %%\n" |
1592 | "round_trip_ping_latency_cycles: %d DCFCLK Cycles\n" |
1593 | "urgent_out_of_order_return_per_channel: %d Bytes\n" |
1594 | "number_of_channels: %d\n" |
1595 | "vmm_page_size: %d Bytes\n" |
1596 | "dram_clock_change_latency: %f ns\n" |
1597 | "return_bus_width: %d Bytes\n" , |
1598 | dc->dcn_soc->sr_exit_time * 1000, |
1599 | dc->dcn_soc->sr_enter_plus_exit_time * 1000, |
1600 | dc->dcn_soc->urgent_latency * 1000, |
1601 | dc->dcn_soc->write_back_latency * 1000, |
1602 | dc->dcn_soc->percent_of_ideal_drambw_received_after_urg_latency, |
1603 | dc->dcn_soc->max_request_size, |
1604 | dc->dcn_soc->dcfclkv_max0p9 * 1000, |
1605 | dc->dcn_soc->dcfclkv_nom0p8 * 1000, |
1606 | dc->dcn_soc->dcfclkv_mid0p72 * 1000, |
1607 | dc->dcn_soc->dcfclkv_min0p65 * 1000, |
1608 | dc->dcn_soc->max_dispclk_vmax0p9 * 1000, |
1609 | dc->dcn_soc->max_dispclk_vnom0p8 * 1000, |
1610 | dc->dcn_soc->max_dispclk_vmid0p72 * 1000, |
1611 | dc->dcn_soc->max_dispclk_vmin0p65 * 1000, |
1612 | dc->dcn_soc->max_dppclk_vmax0p9 * 1000, |
1613 | dc->dcn_soc->max_dppclk_vnom0p8 * 1000, |
1614 | dc->dcn_soc->max_dppclk_vmid0p72 * 1000, |
1615 | dc->dcn_soc->max_dppclk_vmin0p65 * 1000, |
1616 | dc->dcn_soc->socclk * 1000, |
1617 | dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 * 1000, |
1618 | dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 * 1000, |
1619 | dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 * 1000, |
1620 | dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 * 1000, |
1621 | dc->dcn_soc->phyclkv_max0p9 * 1000, |
1622 | dc->dcn_soc->phyclkv_nom0p8 * 1000, |
1623 | dc->dcn_soc->phyclkv_mid0p72 * 1000, |
1624 | dc->dcn_soc->phyclkv_min0p65 * 1000, |
1625 | dc->dcn_soc->downspreading * 100, |
1626 | dc->dcn_soc->round_trip_ping_latency_cycles, |
1627 | dc->dcn_soc->urgent_out_of_order_return_per_channel, |
1628 | dc->dcn_soc->number_of_channels, |
1629 | dc->dcn_soc->vmm_page_size, |
1630 | dc->dcn_soc->dram_clock_change_latency * 1000, |
1631 | dc->dcn_soc->return_bus_width); |
1632 | DC_LOG_BANDWIDTH_CALCS("rob_buffer_size_in_kbyte: %f\n" |
1633 | "det_buffer_size_in_kbyte: %f\n" |
1634 | "dpp_output_buffer_pixels: %f\n" |
1635 | "opp_output_buffer_lines: %f\n" |
1636 | "pixel_chunk_size_in_kbyte: %f\n" |
1637 | "pte_enable: %d\n" |
1638 | "pte_chunk_size: %d kbytes\n" |
1639 | "meta_chunk_size: %d kbytes\n" |
1640 | "writeback_chunk_size: %d kbytes\n" |
1641 | "odm_capability: %d\n" |
1642 | "dsc_capability: %d\n" |
1643 | "line_buffer_size: %d bits\n" |
1644 | "max_line_buffer_lines: %d\n" |
1645 | "is_line_buffer_bpp_fixed: %d\n" |
1646 | "line_buffer_fixed_bpp: %d\n" |
1647 | "writeback_luma_buffer_size: %d kbytes\n" |
1648 | "writeback_chroma_buffer_size: %d kbytes\n" |
1649 | "max_num_dpp: %d\n" |
1650 | "max_num_writeback: %d\n" |
1651 | "max_dchub_topscl_throughput: %d pixels/dppclk\n" |
1652 | "max_pscl_tolb_throughput: %d pixels/dppclk\n" |
1653 | "max_lb_tovscl_throughput: %d pixels/dppclk\n" |
1654 | "max_vscl_tohscl_throughput: %d pixels/dppclk\n" |
1655 | "max_hscl_ratio: %f\n" |
1656 | "max_vscl_ratio: %f\n" |
1657 | "max_hscl_taps: %d\n" |
1658 | "max_vscl_taps: %d\n" |
1659 | "pte_buffer_size_in_requests: %d\n" |
1660 | "dispclk_ramping_margin: %f %%\n" |
1661 | "under_scan_factor: %f %%\n" |
1662 | "max_inter_dcn_tile_repeaters: %d\n" |
1663 | "can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one: %d\n" |
1664 | "bug_forcing_luma_and_chroma_request_to_same_size_fixed: %d\n" |
1665 | "dcfclk_cstate_latency: %d\n" , |
1666 | dc->dcn_ip->rob_buffer_size_in_kbyte, |
1667 | dc->dcn_ip->det_buffer_size_in_kbyte, |
1668 | dc->dcn_ip->dpp_output_buffer_pixels, |
1669 | dc->dcn_ip->opp_output_buffer_lines, |
1670 | dc->dcn_ip->pixel_chunk_size_in_kbyte, |
1671 | dc->dcn_ip->pte_enable, |
1672 | dc->dcn_ip->pte_chunk_size, |
1673 | dc->dcn_ip->meta_chunk_size, |
1674 | dc->dcn_ip->writeback_chunk_size, |
1675 | dc->dcn_ip->odm_capability, |
1676 | dc->dcn_ip->dsc_capability, |
1677 | dc->dcn_ip->line_buffer_size, |
1678 | dc->dcn_ip->max_line_buffer_lines, |
1679 | dc->dcn_ip->is_line_buffer_bpp_fixed, |
1680 | dc->dcn_ip->line_buffer_fixed_bpp, |
1681 | dc->dcn_ip->writeback_luma_buffer_size, |
1682 | dc->dcn_ip->writeback_chroma_buffer_size, |
1683 | dc->dcn_ip->max_num_dpp, |
1684 | dc->dcn_ip->max_num_writeback, |
1685 | dc->dcn_ip->max_dchub_topscl_throughput, |
1686 | dc->dcn_ip->max_pscl_tolb_throughput, |
1687 | dc->dcn_ip->max_lb_tovscl_throughput, |
1688 | dc->dcn_ip->max_vscl_tohscl_throughput, |
1689 | dc->dcn_ip->max_hscl_ratio, |
1690 | dc->dcn_ip->max_vscl_ratio, |
1691 | dc->dcn_ip->max_hscl_taps, |
1692 | dc->dcn_ip->max_vscl_taps, |
1693 | dc->dcn_ip->pte_buffer_size_in_requests, |
1694 | dc->dcn_ip->dispclk_ramping_margin, |
1695 | dc->dcn_ip->under_scan_factor * 100, |
1696 | dc->dcn_ip->max_inter_dcn_tile_repeaters, |
1697 | dc->dcn_ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one, |
1698 | dc->dcn_ip->bug_forcing_luma_and_chroma_request_to_same_size_fixed, |
1699 | dc->dcn_ip->dcfclk_cstate_latency); |
1700 | |
1701 | dc->dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time; |
1702 | dc->dml.soc.sr_enter_plus_exit_time_us = dc->dcn_soc->sr_enter_plus_exit_time; |
1703 | dc->dml.soc.urgent_latency_us = dc->dcn_soc->urgent_latency; |
1704 | dc->dml.soc.writeback_latency_us = dc->dcn_soc->write_back_latency; |
1705 | dc->dml.soc.ideal_dram_bw_after_urgent_percent = |
1706 | dc->dcn_soc->percent_of_ideal_drambw_received_after_urg_latency; |
1707 | dc->dml.soc.max_request_size_bytes = dc->dcn_soc->max_request_size; |
1708 | dc->dml.soc.downspread_percent = dc->dcn_soc->downspreading; |
1709 | dc->dml.soc.round_trip_ping_latency_dcfclk_cycles = |
1710 | dc->dcn_soc->round_trip_ping_latency_cycles; |
1711 | dc->dml.soc.urgent_out_of_order_return_per_channel_bytes = |
1712 | dc->dcn_soc->urgent_out_of_order_return_per_channel; |
1713 | dc->dml.soc.num_chans = dc->dcn_soc->number_of_channels; |
1714 | dc->dml.soc.vmm_page_size_bytes = dc->dcn_soc->vmm_page_size; |
1715 | dc->dml.soc.dram_clock_change_latency_us = dc->dcn_soc->dram_clock_change_latency; |
1716 | dc->dml.soc.return_bus_width_bytes = dc->dcn_soc->return_bus_width; |
1717 | |
1718 | dc->dml.ip.rob_buffer_size_kbytes = dc->dcn_ip->rob_buffer_size_in_kbyte; |
1719 | dc->dml.ip.det_buffer_size_kbytes = dc->dcn_ip->det_buffer_size_in_kbyte; |
1720 | dc->dml.ip.dpp_output_buffer_pixels = dc->dcn_ip->dpp_output_buffer_pixels; |
1721 | dc->dml.ip.opp_output_buffer_lines = dc->dcn_ip->opp_output_buffer_lines; |
1722 | dc->dml.ip.pixel_chunk_size_kbytes = dc->dcn_ip->pixel_chunk_size_in_kbyte; |
1723 | dc->dml.ip.pte_enable = dc->dcn_ip->pte_enable == dcn_bw_yes; |
1724 | dc->dml.ip.pte_chunk_size_kbytes = dc->dcn_ip->pte_chunk_size; |
1725 | dc->dml.ip.meta_chunk_size_kbytes = dc->dcn_ip->meta_chunk_size; |
1726 | dc->dml.ip.writeback_chunk_size_kbytes = dc->dcn_ip->writeback_chunk_size; |
1727 | dc->dml.ip.line_buffer_size_bits = dc->dcn_ip->line_buffer_size; |
1728 | dc->dml.ip.max_line_buffer_lines = dc->dcn_ip->max_line_buffer_lines; |
1729 | dc->dml.ip.IsLineBufferBppFixed = dc->dcn_ip->is_line_buffer_bpp_fixed == dcn_bw_yes; |
1730 | dc->dml.ip.LineBufferFixedBpp = dc->dcn_ip->line_buffer_fixed_bpp; |
1731 | dc->dml.ip.writeback_luma_buffer_size_kbytes = dc->dcn_ip->writeback_luma_buffer_size; |
1732 | dc->dml.ip.writeback_chroma_buffer_size_kbytes = dc->dcn_ip->writeback_chroma_buffer_size; |
1733 | dc->dml.ip.max_num_dpp = dc->dcn_ip->max_num_dpp; |
1734 | dc->dml.ip.max_num_wb = dc->dcn_ip->max_num_writeback; |
1735 | dc->dml.ip.max_dchub_pscl_bw_pix_per_clk = dc->dcn_ip->max_dchub_topscl_throughput; |
1736 | dc->dml.ip.max_pscl_lb_bw_pix_per_clk = dc->dcn_ip->max_pscl_tolb_throughput; |
1737 | dc->dml.ip.max_lb_vscl_bw_pix_per_clk = dc->dcn_ip->max_lb_tovscl_throughput; |
1738 | dc->dml.ip.max_vscl_hscl_bw_pix_per_clk = dc->dcn_ip->max_vscl_tohscl_throughput; |
1739 | dc->dml.ip.max_hscl_ratio = dc->dcn_ip->max_hscl_ratio; |
1740 | dc->dml.ip.max_vscl_ratio = dc->dcn_ip->max_vscl_ratio; |
1741 | dc->dml.ip.max_hscl_taps = dc->dcn_ip->max_hscl_taps; |
1742 | dc->dml.ip.max_vscl_taps = dc->dcn_ip->max_vscl_taps; |
1743 | /*pte_buffer_size_in_requests missing in dml*/ |
1744 | dc->dml.ip.dispclk_ramp_margin_percent = dc->dcn_ip->dispclk_ramping_margin; |
1745 | dc->dml.ip.underscan_factor = dc->dcn_ip->under_scan_factor; |
1746 | dc->dml.ip.max_inter_dcn_tile_repeaters = dc->dcn_ip->max_inter_dcn_tile_repeaters; |
1747 | dc->dml.ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = |
1748 | dc->dcn_ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one == dcn_bw_yes; |
1749 | dc->dml.ip.bug_forcing_LC_req_same_size_fixed = |
1750 | dc->dcn_ip->bug_forcing_luma_and_chroma_request_to_same_size_fixed == dcn_bw_yes; |
1751 | dc->dml.ip.dcfclk_cstate_latency = dc->dcn_ip->dcfclk_cstate_latency; |
1752 | } |
1753 | |