2 * Copyright 2017 Advanced Micro Devices, Inc.
3 * Copyright 2019 Raptor Engineering, LLC
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
27 #include "dm_services.h"
29 #include "dcn_calcs.h"
30 #include "dcn_calc_auto.h"
31 #include "dal_asic_id.h"
33 #include "dcn10/dcn10_resource.h"
34 #include "dcn10/dcn10_hubbub.h"
35 #include "dml/dml1_display_rq_dlg_calc.h"
37 #include "dcn_calc_math.h"
42 #define WM_SET_COUNT 4
50 * This file is gcc-parseable HW gospel, coming straight from HW engineers.
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.
57 /* Defaults from spreadsheet rev#247.
58 * RV2 delta: dram_clock_change_latency, max_num_dpp
60 const struct dcn_soc_bounding_box dcn10_soc_defaults
= {
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, /*%*/
69 /* below default clocks derived from STA target base on
70 * slow-slow corner + 10% margin with voltages aligned to FCLK.
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 */
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 */
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 */
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*/
98 /* BW depend on FCLK, MCLK, # of channels */
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*/
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,
111 .number_of_channels
= 2,
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*/
121 /* Depends on user class (client vs embedded, workstation, etc) */
122 .percent_disp_bw_limit
= 0.3f
/*%*/
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*/
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*/
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?*/
162 static enum dcn_bw_defs
tl_sw_mode_to_bw_defs(enum swizzle_mode_values sw_mode
)
166 return dcn_bw_sw_linear
;
168 return dcn_bw_sw_4_kb_s
;
170 return dcn_bw_sw_4_kb_d
;
172 return dcn_bw_sw_64_kb_s
;
174 return dcn_bw_sw_64_kb_d
;
176 return dcn_bw_sw_var_s
;
178 return dcn_bw_sw_var_d
;
180 return dcn_bw_sw_64_kb_s_t
;
182 return dcn_bw_sw_64_kb_d_t
;
184 return dcn_bw_sw_4_kb_s_x
;
186 return dcn_bw_sw_4_kb_d_x
;
188 return dcn_bw_sw_64_kb_s_x
;
190 return dcn_bw_sw_64_kb_d_x
;
192 return dcn_bw_sw_var_s_x
;
194 return dcn_bw_sw_var_d_x
;
205 BREAK_TO_DEBUGGER(); /*not in formula*/
206 return dcn_bw_sw_4_kb_s
;
210 static int tl_lb_bpp_to_int(enum lb_pixel_depth depth
)
213 case LB_PIXEL_DEPTH_18BPP
:
215 case LB_PIXEL_DEPTH_24BPP
:
217 case LB_PIXEL_DEPTH_30BPP
:
219 case LB_PIXEL_DEPTH_36BPP
:
226 static enum dcn_bw_defs
tl_pixel_format_to_bw_defs(enum surface_pixel_format 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_ARGB16161616F
:
240 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:
241 return dcn_bw_rgb_sub_64
;
242 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr
:
243 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb
:
244 return dcn_bw_yuv420_sub_8
;
245 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr
:
246 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb
:
247 return dcn_bw_yuv420_sub_10
;
249 return dcn_bw_rgb_sub_32
;
253 enum source_macro_tile_size
swizzle_mode_to_macro_tile_size(enum swizzle_mode_values sw_mode
)
256 /* for 4/8/16 high tiles */
270 /* For 64bpp 2 high tiles */
292 /* Unsupported swizzle modes for dcn */
295 ASSERT(0); /* Not supported */
300 static void pipe_ctx_to_e2e_pipe_params (
301 const struct pipe_ctx
*pipe
,
302 struct _vcs_dpi_display_pipe_params_st
*input
)
304 input
->src
.is_hsplit
= false;
306 /* stereo can never be split */
307 if (pipe
->plane_state
->stereo_format
== PLANE_STEREO_FORMAT_SIDE_BY_SIDE
||
308 pipe
->plane_state
->stereo_format
== PLANE_STEREO_FORMAT_TOP_AND_BOTTOM
) {
309 /* reset the split group if it was already considered split. */
310 input
->src
.hsplit_grp
= pipe
->pipe_idx
;
311 } else if (pipe
->top_pipe
!= NULL
&& pipe
->top_pipe
->plane_state
== pipe
->plane_state
) {
312 input
->src
.is_hsplit
= true;
313 } else if (pipe
->bottom_pipe
!= NULL
&& pipe
->bottom_pipe
->plane_state
== pipe
->plane_state
) {
314 input
->src
.is_hsplit
= true;
317 if (pipe
->plane_res
.dpp
->ctx
->dc
->debug
.optimized_watermark
) {
319 * this method requires us to always re-calculate watermark when dcc change
322 input
->src
.dcc
= pipe
->plane_state
->dcc
.enable
? 1 : 0;
325 * allow us to disable dcc on the fly without re-calculating WM
327 * extra overhead for DCC is quite small. for 1080p WM without
328 * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us)
332 input
->src
.dcc
= pipe
->plane_res
.dpp
->ctx
->dc
->res_pool
->hubbub
->funcs
->
333 dcc_support_pixel_format(pipe
->plane_state
->format
, &bpe
) ? 1 : 0;
335 input
->src
.dcc_rate
= 1;
336 input
->src
.meta_pitch
= pipe
->plane_state
->dcc
.meta_pitch
;
337 input
->src
.source_scan
= dm_horz
;
338 input
->src
.sw_mode
= pipe
->plane_state
->tiling_info
.gfx9
.swizzle
;
340 input
->src
.viewport_width
= pipe
->plane_res
.scl_data
.viewport
.width
;
341 input
->src
.viewport_height
= pipe
->plane_res
.scl_data
.viewport
.height
;
342 input
->src
.data_pitch
= pipe
->plane_res
.scl_data
.viewport
.width
;
343 input
->src
.data_pitch_c
= pipe
->plane_res
.scl_data
.viewport
.width
;
344 input
->src
.cur0_src_width
= 128; /* TODO: Cursor calcs, not curently stored */
345 input
->src
.cur0_bpp
= 32;
347 input
->src
.macro_tile_size
= swizzle_mode_to_macro_tile_size(pipe
->plane_state
->tiling_info
.gfx9
.swizzle
);
349 switch (pipe
->plane_state
->rotation
) {
350 case ROTATION_ANGLE_0
:
351 case ROTATION_ANGLE_180
:
352 input
->src
.source_scan
= dm_horz
;
354 case ROTATION_ANGLE_90
:
355 case ROTATION_ANGLE_270
:
356 input
->src
.source_scan
= dm_vert
;
359 ASSERT(0); /* Not supported */
363 /* TODO: Fix pixel format mappings */
364 switch (pipe
->plane_state
->format
) {
365 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr
:
366 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb
:
367 input
->src
.source_format
= dm_420_8
;
368 input
->src
.viewport_width_c
= input
->src
.viewport_width
/ 2;
369 input
->src
.viewport_height_c
= input
->src
.viewport_height
/ 2;
371 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr
:
372 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb
:
373 input
->src
.source_format
= dm_420_10
;
374 input
->src
.viewport_width_c
= input
->src
.viewport_width
/ 2;
375 input
->src
.viewport_height_c
= input
->src
.viewport_height
/ 2;
377 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
:
378 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F
:
379 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:
380 input
->src
.source_format
= dm_444_64
;
381 input
->src
.viewport_width_c
= input
->src
.viewport_width
;
382 input
->src
.viewport_height_c
= input
->src
.viewport_height
;
384 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
:
385 input
->src
.source_format
= dm_rgbe_alpha
;
386 input
->src
.viewport_width_c
= input
->src
.viewport_width
;
387 input
->src
.viewport_height_c
= input
->src
.viewport_height
;
390 input
->src
.source_format
= dm_444_32
;
391 input
->src
.viewport_width_c
= input
->src
.viewport_width
;
392 input
->src
.viewport_height_c
= input
->src
.viewport_height
;
396 input
->scale_taps
.htaps
= pipe
->plane_res
.scl_data
.taps
.h_taps
;
397 input
->scale_ratio_depth
.hscl_ratio
= pipe
->plane_res
.scl_data
.ratios
.horz
.value
/4294967296.0;
398 input
->scale_ratio_depth
.vscl_ratio
= pipe
->plane_res
.scl_data
.ratios
.vert
.value
/4294967296.0;
399 input
->scale_ratio_depth
.vinit
= pipe
->plane_res
.scl_data
.inits
.v
.value
/4294967296.0;
400 if (input
->scale_ratio_depth
.vinit
< 1.0)
401 input
->scale_ratio_depth
.vinit
= 1;
402 input
->scale_taps
.vtaps
= pipe
->plane_res
.scl_data
.taps
.v_taps
;
403 input
->scale_taps
.vtaps_c
= pipe
->plane_res
.scl_data
.taps
.v_taps_c
;
404 input
->scale_taps
.htaps_c
= pipe
->plane_res
.scl_data
.taps
.h_taps_c
;
405 input
->scale_ratio_depth
.hscl_ratio_c
= pipe
->plane_res
.scl_data
.ratios
.horz_c
.value
/4294967296.0;
406 input
->scale_ratio_depth
.vscl_ratio_c
= pipe
->plane_res
.scl_data
.ratios
.vert_c
.value
/4294967296.0;
407 input
->scale_ratio_depth
.vinit_c
= pipe
->plane_res
.scl_data
.inits
.v_c
.value
/4294967296.0;
408 if (input
->scale_ratio_depth
.vinit_c
< 1.0)
409 input
->scale_ratio_depth
.vinit_c
= 1;
410 switch (pipe
->plane_res
.scl_data
.lb_params
.depth
) {
411 case LB_PIXEL_DEPTH_30BPP
:
412 input
->scale_ratio_depth
.lb_depth
= 30; break;
413 case LB_PIXEL_DEPTH_36BPP
:
414 input
->scale_ratio_depth
.lb_depth
= 36; break;
416 input
->scale_ratio_depth
.lb_depth
= 24; break;
420 input
->dest
.vactive
= pipe
->stream
->timing
.v_addressable
+ pipe
->stream
->timing
.v_border_top
421 + pipe
->stream
->timing
.v_border_bottom
;
423 input
->dest
.recout_width
= pipe
->plane_res
.scl_data
.recout
.width
;
424 input
->dest
.recout_height
= pipe
->plane_res
.scl_data
.recout
.height
;
426 input
->dest
.full_recout_width
= pipe
->plane_res
.scl_data
.recout
.width
;
427 input
->dest
.full_recout_height
= pipe
->plane_res
.scl_data
.recout
.height
;
429 input
->dest
.htotal
= pipe
->stream
->timing
.h_total
;
430 input
->dest
.hblank_start
= input
->dest
.htotal
- pipe
->stream
->timing
.h_front_porch
;
431 input
->dest
.hblank_end
= input
->dest
.hblank_start
432 - pipe
->stream
->timing
.h_addressable
433 - pipe
->stream
->timing
.h_border_left
434 - pipe
->stream
->timing
.h_border_right
;
436 input
->dest
.vtotal
= pipe
->stream
->timing
.v_total
;
437 input
->dest
.vblank_start
= input
->dest
.vtotal
- pipe
->stream
->timing
.v_front_porch
;
438 input
->dest
.vblank_end
= input
->dest
.vblank_start
439 - pipe
->stream
->timing
.v_addressable
440 - pipe
->stream
->timing
.v_border_bottom
441 - pipe
->stream
->timing
.v_border_top
;
442 input
->dest
.pixel_rate_mhz
= pipe
->stream
->timing
.pix_clk_100hz
/10000.0;
443 input
->dest
.vstartup_start
= pipe
->pipe_dlg_param
.vstartup_start
;
444 input
->dest
.vupdate_offset
= pipe
->pipe_dlg_param
.vupdate_offset
;
445 input
->dest
.vupdate_offset
= pipe
->pipe_dlg_param
.vupdate_offset
;
446 input
->dest
.vupdate_width
= pipe
->pipe_dlg_param
.vupdate_width
;
450 static void dcn_bw_calc_rq_dlg_ttu(
452 const struct dcn_bw_internal_vars
*v
,
453 struct pipe_ctx
*pipe
,
456 struct display_mode_lib
*dml
= (struct display_mode_lib
*)(&dc
->dml
);
457 struct _vcs_dpi_display_dlg_regs_st
*dlg_regs
= &pipe
->dlg_regs
;
458 struct _vcs_dpi_display_ttu_regs_st
*ttu_regs
= &pipe
->ttu_regs
;
459 struct _vcs_dpi_display_rq_regs_st
*rq_regs
= &pipe
->rq_regs
;
460 struct _vcs_dpi_display_rq_params_st rq_param
= {0};
461 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param
= {0};
462 struct _vcs_dpi_display_e2e_pipe_params_st input
= { { { 0 } } };
463 float total_active_bw
= 0;
464 float total_prefetch_bw
= 0;
465 int total_flip_bytes
= 0;
468 memset(dlg_regs
, 0, sizeof(*dlg_regs
));
469 memset(ttu_regs
, 0, sizeof(*ttu_regs
));
470 memset(rq_regs
, 0, sizeof(*rq_regs
));
472 for (i
= 0; i
< number_of_planes
; i
++) {
473 total_active_bw
+= v
->read_bandwidth
[i
];
474 total_prefetch_bw
+= v
->prefetch_bandwidth
[i
];
475 total_flip_bytes
+= v
->total_immediate_flip_bytes
[i
];
477 dlg_sys_param
.total_flip_bw
= v
->return_bw
- dcn_bw_max2(total_active_bw
, total_prefetch_bw
);
478 if (dlg_sys_param
.total_flip_bw
< 0.0)
479 dlg_sys_param
.total_flip_bw
= 0;
481 dlg_sys_param
.t_mclk_wm_us
= v
->dram_clock_change_watermark
;
482 dlg_sys_param
.t_sr_wm_us
= v
->stutter_enter_plus_exit_watermark
;
483 dlg_sys_param
.t_urg_wm_us
= v
->urgent_watermark
;
484 dlg_sys_param
.t_extra_us
= v
->urgent_extra_latency
;
485 dlg_sys_param
.deepsleep_dcfclk_mhz
= v
->dcf_clk_deep_sleep
;
486 dlg_sys_param
.total_flip_bytes
= total_flip_bytes
;
488 pipe_ctx_to_e2e_pipe_params(pipe
, &input
.pipe
);
489 input
.clks_cfg
.dcfclk_mhz
= v
->dcfclk
;
490 input
.clks_cfg
.dispclk_mhz
= v
->dispclk
;
491 input
.clks_cfg
.dppclk_mhz
= v
->dppclk
;
492 input
.clks_cfg
.refclk_mhz
= dc
->res_pool
->ref_clocks
.dchub_ref_clock_inKhz
/ 1000.0;
493 input
.clks_cfg
.socclk_mhz
= v
->socclk
;
494 input
.clks_cfg
.voltage
= v
->voltage_level
;
495 // dc->dml.logger = pool->base.logger;
496 input
.dout
.output_format
= (v
->output_format
[in_idx
] == dcn_bw_420
) ? dm_420
: dm_444
;
497 input
.dout
.output_type
= (v
->output
[in_idx
] == dcn_bw_hdmi
) ? dm_hdmi
: dm_dp
;
498 //input[in_idx].dout.output_standard;
500 /*todo: soc->sr_enter_plus_exit_time??*/
501 dlg_sys_param
.t_srx_delay_us
= dc
->dcn_ip
->dcfclk_cstate_latency
/ v
->dcf_clk_deep_sleep
;
503 dml1_rq_dlg_get_rq_params(dml
, &rq_param
, input
.pipe
.src
);
504 dml1_extract_rq_regs(dml
, rq_regs
, rq_param
);
505 dml1_rq_dlg_get_dlg_params(
514 v
->pte_enable
== dcn_bw_yes
,
515 pipe
->plane_state
->flip_immediate
);
518 static void split_stream_across_pipes(
519 struct resource_context
*res_ctx
,
520 const struct resource_pool
*pool
,
521 struct pipe_ctx
*primary_pipe
,
522 struct pipe_ctx
*secondary_pipe
)
524 int pipe_idx
= secondary_pipe
->pipe_idx
;
526 if (!primary_pipe
->plane_state
)
529 *secondary_pipe
= *primary_pipe
;
531 secondary_pipe
->pipe_idx
= pipe_idx
;
532 secondary_pipe
->plane_res
.mi
= pool
->mis
[secondary_pipe
->pipe_idx
];
533 secondary_pipe
->plane_res
.hubp
= pool
->hubps
[secondary_pipe
->pipe_idx
];
534 secondary_pipe
->plane_res
.ipp
= pool
->ipps
[secondary_pipe
->pipe_idx
];
535 secondary_pipe
->plane_res
.xfm
= pool
->transforms
[secondary_pipe
->pipe_idx
];
536 secondary_pipe
->plane_res
.dpp
= pool
->dpps
[secondary_pipe
->pipe_idx
];
537 secondary_pipe
->plane_res
.mpcc_inst
= pool
->dpps
[secondary_pipe
->pipe_idx
]->inst
;
538 if (primary_pipe
->bottom_pipe
) {
539 ASSERT(primary_pipe
->bottom_pipe
!= secondary_pipe
);
540 secondary_pipe
->bottom_pipe
= primary_pipe
->bottom_pipe
;
541 secondary_pipe
->bottom_pipe
->top_pipe
= secondary_pipe
;
543 primary_pipe
->bottom_pipe
= secondary_pipe
;
544 secondary_pipe
->top_pipe
= primary_pipe
;
546 resource_build_scaling_params(primary_pipe
);
547 resource_build_scaling_params(secondary_pipe
);
551 static void calc_wm_sets_and_perf_params(
552 struct dc_state
*context
,
553 struct dcn_bw_internal_vars
*v
)
555 /* Calculate set A last to keep internal var state consistent for required config */
556 if (v
->voltage_level
< 2) {
557 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vnom0p8
;
558 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vnom0p8
;
559 v
->fabric_and_dram_bandwidth
= v
->fabric_and_dram_bandwidth_vnom0p8
;
560 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
562 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.cstate_pstate
.cstate_exit_ns
=
563 v
->stutter_exit_watermark
* 1000;
564 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.cstate_pstate
.cstate_enter_plus_exit_ns
=
565 v
->stutter_enter_plus_exit_watermark
* 1000;
566 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.cstate_pstate
.pstate_change_ns
=
567 v
->dram_clock_change_watermark
* 1000;
568 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
569 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.urgent_ns
= v
->urgent_watermark
* 1000;
571 v
->dcfclk_per_state
[1] = v
->dcfclkv_nom0p8
;
572 v
->dcfclk_per_state
[0] = v
->dcfclkv_nom0p8
;
573 v
->dcfclk
= v
->dcfclkv_nom0p8
;
574 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
576 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.cstate_pstate
.cstate_exit_ns
=
577 v
->stutter_exit_watermark
* 1000;
578 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.cstate_pstate
.cstate_enter_plus_exit_ns
=
579 v
->stutter_enter_plus_exit_watermark
* 1000;
580 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.cstate_pstate
.pstate_change_ns
=
581 v
->dram_clock_change_watermark
* 1000;
582 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
583 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.urgent_ns
= v
->urgent_watermark
* 1000;
586 if (v
->voltage_level
< 3) {
587 v
->fabric_and_dram_bandwidth_per_state
[2] = v
->fabric_and_dram_bandwidth_vmax0p9
;
588 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vmax0p9
;
589 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vmax0p9
;
590 v
->fabric_and_dram_bandwidth
= v
->fabric_and_dram_bandwidth_vmax0p9
;
591 v
->dcfclk_per_state
[2] = v
->dcfclkv_max0p9
;
592 v
->dcfclk_per_state
[1] = v
->dcfclkv_max0p9
;
593 v
->dcfclk_per_state
[0] = v
->dcfclkv_max0p9
;
594 v
->dcfclk
= v
->dcfclkv_max0p9
;
595 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
597 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.cstate_pstate
.cstate_exit_ns
=
598 v
->stutter_exit_watermark
* 1000;
599 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.cstate_pstate
.cstate_enter_plus_exit_ns
=
600 v
->stutter_enter_plus_exit_watermark
* 1000;
601 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.cstate_pstate
.pstate_change_ns
=
602 v
->dram_clock_change_watermark
* 1000;
603 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
604 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.urgent_ns
= v
->urgent_watermark
* 1000;
607 v
->fabric_and_dram_bandwidth_per_state
[2] = v
->fabric_and_dram_bandwidth_vnom0p8
;
608 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vmid0p72
;
609 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vmin0p65
;
610 v
->fabric_and_dram_bandwidth
= v
->fabric_and_dram_bandwidth_per_state
[v
->voltage_level
];
611 v
->dcfclk_per_state
[2] = v
->dcfclkv_nom0p8
;
612 v
->dcfclk_per_state
[1] = v
->dcfclkv_mid0p72
;
613 v
->dcfclk_per_state
[0] = v
->dcfclkv_min0p65
;
614 v
->dcfclk
= v
->dcfclk_per_state
[v
->voltage_level
];
615 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
617 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_exit_ns
=
618 v
->stutter_exit_watermark
* 1000;
619 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_enter_plus_exit_ns
=
620 v
->stutter_enter_plus_exit_watermark
* 1000;
621 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.pstate_change_ns
=
622 v
->dram_clock_change_watermark
* 1000;
623 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
624 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.urgent_ns
= v
->urgent_watermark
* 1000;
625 if (v
->voltage_level
>= 2) {
626 context
->bw_ctx
.bw
.dcn
.watermarks
.b
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
627 context
->bw_ctx
.bw
.dcn
.watermarks
.c
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
629 if (v
->voltage_level
>= 3)
630 context
->bw_ctx
.bw
.dcn
.watermarks
.d
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
634 static bool dcn_bw_apply_registry_override(struct dc
*dc
)
636 bool updated
= false;
639 if ((int)(dc
->dcn_soc
->sr_exit_time
* 1000) != dc
->debug
.sr_exit_time_ns
640 && dc
->debug
.sr_exit_time_ns
) {
642 dc
->dcn_soc
->sr_exit_time
= dc
->debug
.sr_exit_time_ns
/ 1000.0;
645 if ((int)(dc
->dcn_soc
->sr_enter_plus_exit_time
* 1000)
646 != dc
->debug
.sr_enter_plus_exit_time_ns
647 && dc
->debug
.sr_enter_plus_exit_time_ns
) {
649 dc
->dcn_soc
->sr_enter_plus_exit_time
=
650 dc
->debug
.sr_enter_plus_exit_time_ns
/ 1000.0;
653 if ((int)(dc
->dcn_soc
->urgent_latency
* 1000) != dc
->debug
.urgent_latency_ns
654 && dc
->debug
.urgent_latency_ns
) {
656 dc
->dcn_soc
->urgent_latency
= dc
->debug
.urgent_latency_ns
/ 1000.0;
659 if ((int)(dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
* 1000)
660 != dc
->debug
.percent_of_ideal_drambw
661 && dc
->debug
.percent_of_ideal_drambw
) {
663 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
=
664 dc
->debug
.percent_of_ideal_drambw
;
667 if ((int)(dc
->dcn_soc
->dram_clock_change_latency
* 1000)
668 != dc
->debug
.dram_clock_change_latency_ns
669 && dc
->debug
.dram_clock_change_latency_ns
) {
671 dc
->dcn_soc
->dram_clock_change_latency
=
672 dc
->debug
.dram_clock_change_latency_ns
/ 1000.0;
679 static void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars
*v
)
682 * disable optional pipe split by lower dispclk bounding box
685 v
->max_dispclk
[0] = v
->max_dppclk_vmin0p65
;
688 static void hack_force_pipe_split(struct dcn_bw_internal_vars
*v
,
689 unsigned int pixel_rate_100hz
)
691 float pixel_rate_mhz
= pixel_rate_100hz
/ 10000;
694 * force enabling pipe split by lower dpp clock for DPM0 to just
695 * below the specify pixel_rate, so bw calc would split pipe.
697 if (pixel_rate_mhz
< v
->max_dppclk
[0])
698 v
->max_dppclk
[0] = pixel_rate_mhz
;
701 static void hack_bounding_box(struct dcn_bw_internal_vars
*v
,
702 struct dc_debug_options
*dbg
,
703 struct dc_state
*context
)
707 for (i
= 0; i
< MAX_PIPES
; i
++) {
708 struct pipe_ctx
*pipe
= &context
->res_ctx
.pipe_ctx
[i
];
711 * Workaround for avoiding pipe-split in cases where we'd split
712 * planes that are too small, resulting in splits that aren't
713 * valid for the scaler.
715 if (pipe
->plane_state
&&
716 (pipe
->plane_state
->dst_rect
.width
<= 16 ||
717 pipe
->plane_state
->dst_rect
.height
<= 16 ||
718 pipe
->plane_state
->src_rect
.width
<= 16 ||
719 pipe
->plane_state
->src_rect
.height
<= 16)) {
720 hack_disable_optional_pipe_split(v
);
725 if (dbg
->pipe_split_policy
== MPC_SPLIT_AVOID
)
726 hack_disable_optional_pipe_split(v
);
728 if (dbg
->pipe_split_policy
== MPC_SPLIT_AVOID_MULT_DISP
&&
729 context
->stream_count
>= 2)
730 hack_disable_optional_pipe_split(v
);
732 if (context
->stream_count
== 1 &&
733 dbg
->force_single_disp_pipe_split
)
734 hack_force_pipe_split(v
, context
->streams
[0]->timing
.pix_clk_100hz
);
737 unsigned int get_highest_allowed_voltage_level(uint32_t chip_family
, uint32_t hw_internal_rev
, uint32_t pci_revision_id
)
739 /* for low power RV2 variants, the highest voltage level we want is 0 */
740 if ((chip_family
== FAMILY_RV
) &&
741 ASICREV_IS_RAVEN2(hw_internal_rev
))
742 switch (pci_revision_id
) {
747 case PRID_POLLOCK_94
:
748 case PRID_POLLOCK_95
:
749 case PRID_POLLOCK_E9
:
750 case PRID_POLLOCK_EA
:
751 case PRID_POLLOCK_EB
:
757 /* we are ok with all levels */
761 bool dcn_validate_bandwidth(
763 struct dc_state
*context
,
767 * we want a breakdown of the various stages of validation, which the
768 * perf_trace macro doesn't support
770 BW_VAL_TRACE_SETUP();
772 const struct resource_pool
*pool
= dc
->res_pool
;
773 struct dcn_bw_internal_vars
*v
= &context
->dcn_bw_vars
;
775 int vesa_sync_start
, asic_blank_end
, asic_blank_start
;
779 PERFORMANCE_TRACE_START();
781 BW_VAL_TRACE_COUNT();
783 if (dcn_bw_apply_registry_override(dc
))
784 dcn_bw_sync_calcs_and_dml(dc
);
786 memset(v
, 0, sizeof(*v
));
789 v
->sr_exit_time
= dc
->dcn_soc
->sr_exit_time
;
790 v
->sr_enter_plus_exit_time
= dc
->dcn_soc
->sr_enter_plus_exit_time
;
791 v
->urgent_latency
= dc
->dcn_soc
->urgent_latency
;
792 v
->write_back_latency
= dc
->dcn_soc
->write_back_latency
;
793 v
->percent_of_ideal_drambw_received_after_urg_latency
=
794 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
;
796 v
->dcfclkv_min0p65
= dc
->dcn_soc
->dcfclkv_min0p65
;
797 v
->dcfclkv_mid0p72
= dc
->dcn_soc
->dcfclkv_mid0p72
;
798 v
->dcfclkv_nom0p8
= dc
->dcn_soc
->dcfclkv_nom0p8
;
799 v
->dcfclkv_max0p9
= dc
->dcn_soc
->dcfclkv_max0p9
;
801 v
->max_dispclk_vmin0p65
= dc
->dcn_soc
->max_dispclk_vmin0p65
;
802 v
->max_dispclk_vmid0p72
= dc
->dcn_soc
->max_dispclk_vmid0p72
;
803 v
->max_dispclk_vnom0p8
= dc
->dcn_soc
->max_dispclk_vnom0p8
;
804 v
->max_dispclk_vmax0p9
= dc
->dcn_soc
->max_dispclk_vmax0p9
;
806 v
->max_dppclk_vmin0p65
= dc
->dcn_soc
->max_dppclk_vmin0p65
;
807 v
->max_dppclk_vmid0p72
= dc
->dcn_soc
->max_dppclk_vmid0p72
;
808 v
->max_dppclk_vnom0p8
= dc
->dcn_soc
->max_dppclk_vnom0p8
;
809 v
->max_dppclk_vmax0p9
= dc
->dcn_soc
->max_dppclk_vmax0p9
;
811 v
->socclk
= dc
->dcn_soc
->socclk
;
813 v
->fabric_and_dram_bandwidth_vmin0p65
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
;
814 v
->fabric_and_dram_bandwidth_vmid0p72
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
;
815 v
->fabric_and_dram_bandwidth_vnom0p8
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
;
816 v
->fabric_and_dram_bandwidth_vmax0p9
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
;
818 v
->phyclkv_min0p65
= dc
->dcn_soc
->phyclkv_min0p65
;
819 v
->phyclkv_mid0p72
= dc
->dcn_soc
->phyclkv_mid0p72
;
820 v
->phyclkv_nom0p8
= dc
->dcn_soc
->phyclkv_nom0p8
;
821 v
->phyclkv_max0p9
= dc
->dcn_soc
->phyclkv_max0p9
;
823 v
->downspreading
= dc
->dcn_soc
->downspreading
;
824 v
->round_trip_ping_latency_cycles
= dc
->dcn_soc
->round_trip_ping_latency_cycles
;
825 v
->urgent_out_of_order_return_per_channel
= dc
->dcn_soc
->urgent_out_of_order_return_per_channel
;
826 v
->number_of_channels
= dc
->dcn_soc
->number_of_channels
;
827 v
->vmm_page_size
= dc
->dcn_soc
->vmm_page_size
;
828 v
->dram_clock_change_latency
= dc
->dcn_soc
->dram_clock_change_latency
;
829 v
->return_bus_width
= dc
->dcn_soc
->return_bus_width
;
831 v
->rob_buffer_size_in_kbyte
= dc
->dcn_ip
->rob_buffer_size_in_kbyte
;
832 v
->det_buffer_size_in_kbyte
= dc
->dcn_ip
->det_buffer_size_in_kbyte
;
833 v
->dpp_output_buffer_pixels
= dc
->dcn_ip
->dpp_output_buffer_pixels
;
834 v
->opp_output_buffer_lines
= dc
->dcn_ip
->opp_output_buffer_lines
;
835 v
->pixel_chunk_size_in_kbyte
= dc
->dcn_ip
->pixel_chunk_size_in_kbyte
;
836 v
->pte_enable
= dc
->dcn_ip
->pte_enable
;
837 v
->pte_chunk_size
= dc
->dcn_ip
->pte_chunk_size
;
838 v
->meta_chunk_size
= dc
->dcn_ip
->meta_chunk_size
;
839 v
->writeback_chunk_size
= dc
->dcn_ip
->writeback_chunk_size
;
840 v
->odm_capability
= dc
->dcn_ip
->odm_capability
;
841 v
->dsc_capability
= dc
->dcn_ip
->dsc_capability
;
842 v
->line_buffer_size
= dc
->dcn_ip
->line_buffer_size
;
843 v
->is_line_buffer_bpp_fixed
= dc
->dcn_ip
->is_line_buffer_bpp_fixed
;
844 v
->line_buffer_fixed_bpp
= dc
->dcn_ip
->line_buffer_fixed_bpp
;
845 v
->max_line_buffer_lines
= dc
->dcn_ip
->max_line_buffer_lines
;
846 v
->writeback_luma_buffer_size
= dc
->dcn_ip
->writeback_luma_buffer_size
;
847 v
->writeback_chroma_buffer_size
= dc
->dcn_ip
->writeback_chroma_buffer_size
;
848 v
->max_num_dpp
= dc
->dcn_ip
->max_num_dpp
;
849 v
->max_num_writeback
= dc
->dcn_ip
->max_num_writeback
;
850 v
->max_dchub_topscl_throughput
= dc
->dcn_ip
->max_dchub_topscl_throughput
;
851 v
->max_pscl_tolb_throughput
= dc
->dcn_ip
->max_pscl_tolb_throughput
;
852 v
->max_lb_tovscl_throughput
= dc
->dcn_ip
->max_lb_tovscl_throughput
;
853 v
->max_vscl_tohscl_throughput
= dc
->dcn_ip
->max_vscl_tohscl_throughput
;
854 v
->max_hscl_ratio
= dc
->dcn_ip
->max_hscl_ratio
;
855 v
->max_vscl_ratio
= dc
->dcn_ip
->max_vscl_ratio
;
856 v
->max_hscl_taps
= dc
->dcn_ip
->max_hscl_taps
;
857 v
->max_vscl_taps
= dc
->dcn_ip
->max_vscl_taps
;
858 v
->under_scan_factor
= dc
->dcn_ip
->under_scan_factor
;
859 v
->pte_buffer_size_in_requests
= dc
->dcn_ip
->pte_buffer_size_in_requests
;
860 v
->dispclk_ramping_margin
= dc
->dcn_ip
->dispclk_ramping_margin
;
861 v
->max_inter_dcn_tile_repeaters
= dc
->dcn_ip
->max_inter_dcn_tile_repeaters
;
862 v
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
=
863 dc
->dcn_ip
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
;
864 v
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
=
865 dc
->dcn_ip
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
;
867 v
->voltage
[5] = dcn_bw_no_support
;
868 v
->voltage
[4] = dcn_bw_v_max0p9
;
869 v
->voltage
[3] = dcn_bw_v_max0p9
;
870 v
->voltage
[2] = dcn_bw_v_nom0p8
;
871 v
->voltage
[1] = dcn_bw_v_mid0p72
;
872 v
->voltage
[0] = dcn_bw_v_min0p65
;
873 v
->fabric_and_dram_bandwidth_per_state
[5] = v
->fabric_and_dram_bandwidth_vmax0p9
;
874 v
->fabric_and_dram_bandwidth_per_state
[4] = v
->fabric_and_dram_bandwidth_vmax0p9
;
875 v
->fabric_and_dram_bandwidth_per_state
[3] = v
->fabric_and_dram_bandwidth_vmax0p9
;
876 v
->fabric_and_dram_bandwidth_per_state
[2] = v
->fabric_and_dram_bandwidth_vnom0p8
;
877 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vmid0p72
;
878 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vmin0p65
;
879 v
->dcfclk_per_state
[5] = v
->dcfclkv_max0p9
;
880 v
->dcfclk_per_state
[4] = v
->dcfclkv_max0p9
;
881 v
->dcfclk_per_state
[3] = v
->dcfclkv_max0p9
;
882 v
->dcfclk_per_state
[2] = v
->dcfclkv_nom0p8
;
883 v
->dcfclk_per_state
[1] = v
->dcfclkv_mid0p72
;
884 v
->dcfclk_per_state
[0] = v
->dcfclkv_min0p65
;
885 v
->max_dispclk
[5] = v
->max_dispclk_vmax0p9
;
886 v
->max_dispclk
[4] = v
->max_dispclk_vmax0p9
;
887 v
->max_dispclk
[3] = v
->max_dispclk_vmax0p9
;
888 v
->max_dispclk
[2] = v
->max_dispclk_vnom0p8
;
889 v
->max_dispclk
[1] = v
->max_dispclk_vmid0p72
;
890 v
->max_dispclk
[0] = v
->max_dispclk_vmin0p65
;
891 v
->max_dppclk
[5] = v
->max_dppclk_vmax0p9
;
892 v
->max_dppclk
[4] = v
->max_dppclk_vmax0p9
;
893 v
->max_dppclk
[3] = v
->max_dppclk_vmax0p9
;
894 v
->max_dppclk
[2] = v
->max_dppclk_vnom0p8
;
895 v
->max_dppclk
[1] = v
->max_dppclk_vmid0p72
;
896 v
->max_dppclk
[0] = v
->max_dppclk_vmin0p65
;
897 v
->phyclk_per_state
[5] = v
->phyclkv_max0p9
;
898 v
->phyclk_per_state
[4] = v
->phyclkv_max0p9
;
899 v
->phyclk_per_state
[3] = v
->phyclkv_max0p9
;
900 v
->phyclk_per_state
[2] = v
->phyclkv_nom0p8
;
901 v
->phyclk_per_state
[1] = v
->phyclkv_mid0p72
;
902 v
->phyclk_per_state
[0] = v
->phyclkv_min0p65
;
903 v
->synchronized_vblank
= dcn_bw_no
;
904 v
->ta_pscalculation
= dcn_bw_override
;
905 v
->allow_different_hratio_vratio
= dcn_bw_yes
;
907 for (i
= 0, input_idx
= 0; i
< pool
->pipe_count
; i
++) {
908 struct pipe_ctx
*pipe
= &context
->res_ctx
.pipe_ctx
[i
];
912 /* skip all but first of split pipes */
913 if (pipe
->top_pipe
&& pipe
->top_pipe
->plane_state
== pipe
->plane_state
)
916 v
->underscan_output
[input_idx
] = false; /* taken care of in recout already*/
917 v
->interlace_output
[input_idx
] = false;
919 v
->htotal
[input_idx
] = pipe
->stream
->timing
.h_total
;
920 v
->vtotal
[input_idx
] = pipe
->stream
->timing
.v_total
;
921 v
->vactive
[input_idx
] = pipe
->stream
->timing
.v_addressable
+
922 pipe
->stream
->timing
.v_border_top
+ pipe
->stream
->timing
.v_border_bottom
;
923 v
->v_sync_plus_back_porch
[input_idx
] = pipe
->stream
->timing
.v_total
924 - v
->vactive
[input_idx
]
925 - pipe
->stream
->timing
.v_front_porch
;
926 v
->pixel_clock
[input_idx
] = pipe
->stream
->timing
.pix_clk_100hz
/10000.0;
927 if (pipe
->stream
->timing
.timing_3d_format
== TIMING_3D_FORMAT_HW_FRAME_PACKING
)
928 v
->pixel_clock
[input_idx
] *= 2;
929 if (!pipe
->plane_state
) {
930 v
->dcc_enable
[input_idx
] = dcn_bw_yes
;
931 v
->source_pixel_format
[input_idx
] = dcn_bw_rgb_sub_32
;
932 v
->source_surface_mode
[input_idx
] = dcn_bw_sw_4_kb_s
;
933 v
->lb_bit_per_pixel
[input_idx
] = 30;
934 v
->viewport_width
[input_idx
] = pipe
->stream
->timing
.h_addressable
;
935 v
->viewport_height
[input_idx
] = pipe
->stream
->timing
.v_addressable
;
937 * for cases where we have no plane, we want to validate up to 1080p
938 * source size because here we are only interested in if the output
939 * timing is supported or not. if we cannot support native resolution
940 * of the high res display, we still want to support lower res up scale
943 if (v
->viewport_width
[input_idx
] > 1920)
944 v
->viewport_width
[input_idx
] = 1920;
945 if (v
->viewport_height
[input_idx
] > 1080)
946 v
->viewport_height
[input_idx
] = 1080;
947 v
->scaler_rec_out_width
[input_idx
] = v
->viewport_width
[input_idx
];
948 v
->scaler_recout_height
[input_idx
] = v
->viewport_height
[input_idx
];
949 v
->override_hta_ps
[input_idx
] = 1;
950 v
->override_vta_ps
[input_idx
] = 1;
951 v
->override_hta_pschroma
[input_idx
] = 1;
952 v
->override_vta_pschroma
[input_idx
] = 1;
953 v
->source_scan
[input_idx
] = dcn_bw_hor
;
956 v
->viewport_height
[input_idx
] = pipe
->plane_res
.scl_data
.viewport
.height
;
957 v
->viewport_width
[input_idx
] = pipe
->plane_res
.scl_data
.viewport
.width
;
958 v
->scaler_rec_out_width
[input_idx
] = pipe
->plane_res
.scl_data
.recout
.width
;
959 v
->scaler_recout_height
[input_idx
] = pipe
->plane_res
.scl_data
.recout
.height
;
960 if (pipe
->bottom_pipe
&& pipe
->bottom_pipe
->plane_state
== pipe
->plane_state
) {
961 if (pipe
->plane_state
->rotation
% 2 == 0) {
962 int viewport_end
= pipe
->plane_res
.scl_data
.viewport
.width
963 + pipe
->plane_res
.scl_data
.viewport
.x
;
964 int viewport_b_end
= pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.width
965 + pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.x
;
967 if (viewport_end
> viewport_b_end
)
968 v
->viewport_width
[input_idx
] = viewport_end
969 - pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.x
;
971 v
->viewport_width
[input_idx
] = viewport_b_end
972 - pipe
->plane_res
.scl_data
.viewport
.x
;
974 int viewport_end
= pipe
->plane_res
.scl_data
.viewport
.height
975 + pipe
->plane_res
.scl_data
.viewport
.y
;
976 int viewport_b_end
= pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.height
977 + pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.y
;
979 if (viewport_end
> viewport_b_end
)
980 v
->viewport_height
[input_idx
] = viewport_end
981 - pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.y
;
983 v
->viewport_height
[input_idx
] = viewport_b_end
984 - pipe
->plane_res
.scl_data
.viewport
.y
;
986 v
->scaler_rec_out_width
[input_idx
] = pipe
->plane_res
.scl_data
.recout
.width
987 + pipe
->bottom_pipe
->plane_res
.scl_data
.recout
.width
;
990 if (pipe
->plane_state
->rotation
% 2 == 0) {
991 ASSERT(pipe
->plane_res
.scl_data
.ratios
.horz
.value
!= dc_fixpt_one
.value
992 || v
->scaler_rec_out_width
[input_idx
] == v
->viewport_width
[input_idx
]);
993 ASSERT(pipe
->plane_res
.scl_data
.ratios
.vert
.value
!= dc_fixpt_one
.value
994 || v
->scaler_recout_height
[input_idx
] == v
->viewport_height
[input_idx
]);
996 ASSERT(pipe
->plane_res
.scl_data
.ratios
.horz
.value
!= dc_fixpt_one
.value
997 || v
->scaler_recout_height
[input_idx
] == v
->viewport_width
[input_idx
]);
998 ASSERT(pipe
->plane_res
.scl_data
.ratios
.vert
.value
!= dc_fixpt_one
.value
999 || v
->scaler_rec_out_width
[input_idx
] == v
->viewport_height
[input_idx
]);
1002 if (dc
->debug
.optimized_watermark
) {
1004 * this method requires us to always re-calculate watermark when dcc change
1007 v
->dcc_enable
[input_idx
] = pipe
->plane_state
->dcc
.enable
? dcn_bw_yes
: dcn_bw_no
;
1010 * allow us to disable dcc on the fly without re-calculating WM
1012 * extra overhead for DCC is quite small. for 1080p WM without
1013 * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us)
1017 v
->dcc_enable
[input_idx
] = dc
->res_pool
->hubbub
->funcs
->dcc_support_pixel_format(
1018 pipe
->plane_state
->format
, &bpe
) ? dcn_bw_yes
: dcn_bw_no
;
1021 v
->source_pixel_format
[input_idx
] = tl_pixel_format_to_bw_defs(
1022 pipe
->plane_state
->format
);
1023 v
->source_surface_mode
[input_idx
] = tl_sw_mode_to_bw_defs(
1024 pipe
->plane_state
->tiling_info
.gfx9
.swizzle
);
1025 v
->lb_bit_per_pixel
[input_idx
] = tl_lb_bpp_to_int(pipe
->plane_res
.scl_data
.lb_params
.depth
);
1026 v
->override_hta_ps
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.h_taps
;
1027 v
->override_vta_ps
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.v_taps
;
1028 v
->override_hta_pschroma
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.h_taps_c
;
1029 v
->override_vta_pschroma
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.v_taps_c
;
1031 * Spreadsheet doesn't handle taps_c is one properly,
1032 * need to force Chroma to always be scaled to pass
1033 * bandwidth validation.
1035 if (v
->override_hta_pschroma
[input_idx
] == 1)
1036 v
->override_hta_pschroma
[input_idx
] = 2;
1037 if (v
->override_vta_pschroma
[input_idx
] == 1)
1038 v
->override_vta_pschroma
[input_idx
] = 2;
1039 v
->source_scan
[input_idx
] = (pipe
->plane_state
->rotation
% 2) ? dcn_bw_vert
: dcn_bw_hor
;
1041 if (v
->is_line_buffer_bpp_fixed
== dcn_bw_yes
)
1042 v
->lb_bit_per_pixel
[input_idx
] = v
->line_buffer_fixed_bpp
;
1043 v
->dcc_rate
[input_idx
] = 1; /*TODO: Worst case? does this change?*/
1044 v
->output_format
[input_idx
] = pipe
->stream
->timing
.pixel_encoding
==
1045 PIXEL_ENCODING_YCBCR420
? dcn_bw_420
: dcn_bw_444
;
1046 v
->output
[input_idx
] = pipe
->stream
->signal
==
1047 SIGNAL_TYPE_HDMI_TYPE_A
? dcn_bw_hdmi
: dcn_bw_dp
;
1048 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_8bpc
;
1049 if (v
->output
[input_idx
] == dcn_bw_hdmi
) {
1050 switch (pipe
->stream
->timing
.display_color_depth
) {
1051 case COLOR_DEPTH_101010
:
1052 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_10bpc
;
1054 case COLOR_DEPTH_121212
:
1055 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_12bpc
;
1057 case COLOR_DEPTH_161616
:
1058 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_16bpc
;
1067 v
->number_of_active_planes
= input_idx
;
1069 scaler_settings_calculation(v
);
1071 hack_bounding_box(v
, &dc
->debug
, context
);
1073 mode_support_and_system_configuration(v
);
1075 /* Unhack dppclk: dont bother with trying to pipe split if we cannot maintain dpm0 */
1076 if (v
->voltage_level
!= 0
1077 && context
->stream_count
== 1
1078 && dc
->debug
.force_single_disp_pipe_split
) {
1079 v
->max_dppclk
[0] = v
->max_dppclk_vmin0p65
;
1080 mode_support_and_system_configuration(v
);
1083 if (v
->voltage_level
== 0 &&
1084 (dc
->debug
.sr_exit_time_dpm0_ns
1085 || dc
->debug
.sr_enter_plus_exit_time_dpm0_ns
)) {
1087 if (dc
->debug
.sr_enter_plus_exit_time_dpm0_ns
)
1088 v
->sr_enter_plus_exit_time
=
1089 dc
->debug
.sr_enter_plus_exit_time_dpm0_ns
/ 1000.0f
;
1090 if (dc
->debug
.sr_exit_time_dpm0_ns
)
1091 v
->sr_exit_time
= dc
->debug
.sr_exit_time_dpm0_ns
/ 1000.0f
;
1092 context
->bw_ctx
.dml
.soc
.sr_enter_plus_exit_time_us
= v
->sr_enter_plus_exit_time
;
1093 context
->bw_ctx
.dml
.soc
.sr_exit_time_us
= v
->sr_exit_time
;
1094 mode_support_and_system_configuration(v
);
1097 display_pipe_configuration(v
);
1099 for (k
= 0; k
<= v
->number_of_active_planes
- 1; k
++) {
1100 if (v
->source_scan
[k
] == dcn_bw_hor
)
1101 v
->swath_width_y
[k
] = v
->viewport_width
[k
] / v
->dpp_per_plane
[k
];
1103 v
->swath_width_y
[k
] = v
->viewport_height
[k
] / v
->dpp_per_plane
[k
];
1105 for (k
= 0; k
<= v
->number_of_active_planes
- 1; k
++) {
1106 if (v
->source_pixel_format
[k
] == dcn_bw_rgb_sub_64
) {
1107 v
->byte_per_pixel_dety
[k
] = 8.0;
1108 v
->byte_per_pixel_detc
[k
] = 0.0;
1109 } else if (v
->source_pixel_format
[k
] == dcn_bw_rgb_sub_32
) {
1110 v
->byte_per_pixel_dety
[k
] = 4.0;
1111 v
->byte_per_pixel_detc
[k
] = 0.0;
1112 } else if (v
->source_pixel_format
[k
] == dcn_bw_rgb_sub_16
) {
1113 v
->byte_per_pixel_dety
[k
] = 2.0;
1114 v
->byte_per_pixel_detc
[k
] = 0.0;
1115 } else if (v
->source_pixel_format
[k
] == dcn_bw_yuv420_sub_8
) {
1116 v
->byte_per_pixel_dety
[k
] = 1.0;
1117 v
->byte_per_pixel_detc
[k
] = 2.0;
1119 v
->byte_per_pixel_dety
[k
] = 4.0f
/ 3.0f
;
1120 v
->byte_per_pixel_detc
[k
] = 8.0f
/ 3.0f
;
1124 v
->total_data_read_bandwidth
= 0.0;
1125 for (k
= 0; k
<= v
->number_of_active_planes
- 1; k
++) {
1126 v
->read_bandwidth_plane_luma
[k
] = v
->swath_width_y
[k
] * v
->dpp_per_plane
[k
] *
1127 dcn_bw_ceil2(v
->byte_per_pixel_dety
[k
], 1.0) / (v
->htotal
[k
] / v
->pixel_clock
[k
]) * v
->v_ratio
[k
];
1128 v
->read_bandwidth_plane_chroma
[k
] = v
->swath_width_y
[k
] / 2.0 * v
->dpp_per_plane
[k
] *
1129 dcn_bw_ceil2(v
->byte_per_pixel_detc
[k
], 2.0) / (v
->htotal
[k
] / v
->pixel_clock
[k
]) * v
->v_ratio
[k
] / 2.0;
1130 v
->total_data_read_bandwidth
= v
->total_data_read_bandwidth
+
1131 v
->read_bandwidth_plane_luma
[k
] + v
->read_bandwidth_plane_chroma
[k
];
1134 BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1136 if (v
->voltage_level
!= number_of_states_plus_one
&& !fast_validate
) {
1137 float bw_consumed
= v
->total_bandwidth_consumed_gbyte_per_second
;
1139 if (bw_consumed
< v
->fabric_and_dram_bandwidth_vmin0p65
)
1140 bw_consumed
= v
->fabric_and_dram_bandwidth_vmin0p65
;
1141 else if (bw_consumed
< v
->fabric_and_dram_bandwidth_vmid0p72
)
1142 bw_consumed
= v
->fabric_and_dram_bandwidth_vmid0p72
;
1143 else if (bw_consumed
< v
->fabric_and_dram_bandwidth_vnom0p8
)
1144 bw_consumed
= v
->fabric_and_dram_bandwidth_vnom0p8
;
1146 bw_consumed
= v
->fabric_and_dram_bandwidth_vmax0p9
;
1148 if (bw_consumed
< v
->fabric_and_dram_bandwidth
)
1149 if (dc
->debug
.voltage_align_fclk
)
1150 bw_consumed
= v
->fabric_and_dram_bandwidth
;
1152 display_pipe_configuration(v
);
1153 /*calc_wm_sets_and_perf_params(context, v);*/
1154 /* Only 1 set is used by dcn since no noticeable
1155 * performance improvement was measured and due to hw bug DEGVIDCN10-254
1157 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
1159 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_exit_ns
=
1160 v
->stutter_exit_watermark
* 1000;
1161 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_enter_plus_exit_ns
=
1162 v
->stutter_enter_plus_exit_watermark
* 1000;
1163 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.pstate_change_ns
=
1164 v
->dram_clock_change_watermark
* 1000;
1165 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
1166 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.urgent_ns
= v
->urgent_watermark
* 1000;
1167 context
->bw_ctx
.bw
.dcn
.watermarks
.b
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
1168 context
->bw_ctx
.bw
.dcn
.watermarks
.c
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
1169 context
->bw_ctx
.bw
.dcn
.watermarks
.d
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
1171 context
->bw_ctx
.bw
.dcn
.clk
.fclk_khz
= (int)(bw_consumed
* 1000000 /
1172 (ddr4_dram_factor_single_Channel
* v
->number_of_channels
));
1173 if (bw_consumed
== v
->fabric_and_dram_bandwidth_vmin0p65
)
1174 context
->bw_ctx
.bw
.dcn
.clk
.fclk_khz
= (int)(bw_consumed
* 1000000 / 32);
1176 context
->bw_ctx
.bw
.dcn
.clk
.dcfclk_deep_sleep_khz
= (int)(v
->dcf_clk_deep_sleep
* 1000);
1177 context
->bw_ctx
.bw
.dcn
.clk
.dcfclk_khz
= (int)(v
->dcfclk
* 1000);
1179 context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
= (int)(v
->dispclk
* 1000);
1180 if (dc
->debug
.max_disp_clk
== true)
1181 context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
= (int)(dc
->dcn_soc
->max_dispclk_vmax0p9
* 1000);
1183 if (context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
<
1184 dc
->debug
.min_disp_clk_khz
) {
1185 context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
=
1186 dc
->debug
.min_disp_clk_khz
;
1189 context
->bw_ctx
.bw
.dcn
.clk
.dppclk_khz
= context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
/
1190 v
->dispclk_dppclk_ratio
;
1191 context
->bw_ctx
.bw
.dcn
.clk
.phyclk_khz
= v
->phyclk_per_state
[v
->voltage_level
];
1192 switch (v
->voltage_level
) {
1194 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1195 (int)(dc
->dcn_soc
->max_dppclk_vmin0p65
* 1000);
1198 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1199 (int)(dc
->dcn_soc
->max_dppclk_vmid0p72
* 1000);
1202 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1203 (int)(dc
->dcn_soc
->max_dppclk_vnom0p8
* 1000);
1206 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1207 (int)(dc
->dcn_soc
->max_dppclk_vmax0p9
* 1000);
1211 BW_VAL_TRACE_END_WATERMARKS();
1213 for (i
= 0, input_idx
= 0; i
< pool
->pipe_count
; i
++) {
1214 struct pipe_ctx
*pipe
= &context
->res_ctx
.pipe_ctx
[i
];
1216 /* skip inactive pipe */
1219 /* skip all but first of split pipes */
1220 if (pipe
->top_pipe
&& pipe
->top_pipe
->plane_state
== pipe
->plane_state
)
1223 pipe
->pipe_dlg_param
.vupdate_width
= v
->v_update_width_pix
[input_idx
];
1224 pipe
->pipe_dlg_param
.vupdate_offset
= v
->v_update_offset_pix
[input_idx
];
1225 pipe
->pipe_dlg_param
.vready_offset
= v
->v_ready_offset_pix
[input_idx
];
1226 pipe
->pipe_dlg_param
.vstartup_start
= v
->v_startup
[input_idx
];
1228 pipe
->pipe_dlg_param
.htotal
= pipe
->stream
->timing
.h_total
;
1229 pipe
->pipe_dlg_param
.vtotal
= pipe
->stream
->timing
.v_total
;
1230 vesa_sync_start
= pipe
->stream
->timing
.v_addressable
+
1231 pipe
->stream
->timing
.v_border_bottom
+
1232 pipe
->stream
->timing
.v_front_porch
;
1234 asic_blank_end
= (pipe
->stream
->timing
.v_total
-
1236 pipe
->stream
->timing
.v_border_top
)
1237 * (pipe
->stream
->timing
.flags
.INTERLACE
? 1 : 0);
1239 asic_blank_start
= asic_blank_end
+
1240 (pipe
->stream
->timing
.v_border_top
+
1241 pipe
->stream
->timing
.v_addressable
+
1242 pipe
->stream
->timing
.v_border_bottom
)
1243 * (pipe
->stream
->timing
.flags
.INTERLACE
? 1 : 0);
1245 pipe
->pipe_dlg_param
.vblank_start
= asic_blank_start
;
1246 pipe
->pipe_dlg_param
.vblank_end
= asic_blank_end
;
1248 if (pipe
->plane_state
) {
1249 struct pipe_ctx
*hsplit_pipe
= pipe
->bottom_pipe
;
1251 pipe
->plane_state
->update_flags
.bits
.full_update
= 1;
1253 if (v
->dpp_per_plane
[input_idx
] == 2 ||
1254 ((pipe
->stream
->view_format
==
1255 VIEW_3D_FORMAT_SIDE_BY_SIDE
||
1256 pipe
->stream
->view_format
==
1257 VIEW_3D_FORMAT_TOP_AND_BOTTOM
) &&
1258 (pipe
->stream
->timing
.timing_3d_format
==
1259 TIMING_3D_FORMAT_TOP_AND_BOTTOM
||
1260 pipe
->stream
->timing
.timing_3d_format
==
1261 TIMING_3D_FORMAT_SIDE_BY_SIDE
))) {
1262 if (hsplit_pipe
&& hsplit_pipe
->plane_state
== pipe
->plane_state
) {
1263 /* update previously split pipe */
1264 hsplit_pipe
->pipe_dlg_param
.vupdate_width
= v
->v_update_width_pix
[input_idx
];
1265 hsplit_pipe
->pipe_dlg_param
.vupdate_offset
= v
->v_update_offset_pix
[input_idx
];
1266 hsplit_pipe
->pipe_dlg_param
.vready_offset
= v
->v_ready_offset_pix
[input_idx
];
1267 hsplit_pipe
->pipe_dlg_param
.vstartup_start
= v
->v_startup
[input_idx
];
1269 hsplit_pipe
->pipe_dlg_param
.htotal
= pipe
->stream
->timing
.h_total
;
1270 hsplit_pipe
->pipe_dlg_param
.vtotal
= pipe
->stream
->timing
.v_total
;
1271 hsplit_pipe
->pipe_dlg_param
.vblank_start
= pipe
->pipe_dlg_param
.vblank_start
;
1272 hsplit_pipe
->pipe_dlg_param
.vblank_end
= pipe
->pipe_dlg_param
.vblank_end
;
1274 /* pipe not split previously needs split */
1275 hsplit_pipe
= find_idle_secondary_pipe(&context
->res_ctx
, pool
, pipe
);
1276 ASSERT(hsplit_pipe
);
1277 split_stream_across_pipes(&context
->res_ctx
, pool
, pipe
, hsplit_pipe
);
1280 dcn_bw_calc_rq_dlg_ttu(dc
, v
, hsplit_pipe
, input_idx
);
1281 } else if (hsplit_pipe
&& hsplit_pipe
->plane_state
== pipe
->plane_state
) {
1282 /* merge previously split pipe */
1283 pipe
->bottom_pipe
= hsplit_pipe
->bottom_pipe
;
1284 if (hsplit_pipe
->bottom_pipe
)
1285 hsplit_pipe
->bottom_pipe
->top_pipe
= pipe
;
1286 hsplit_pipe
->plane_state
= NULL
;
1287 hsplit_pipe
->stream
= NULL
;
1288 hsplit_pipe
->top_pipe
= NULL
;
1289 hsplit_pipe
->bottom_pipe
= NULL
;
1290 /* Clear plane_res and stream_res */
1291 memset(&hsplit_pipe
->plane_res
, 0, sizeof(hsplit_pipe
->plane_res
));
1292 memset(&hsplit_pipe
->stream_res
, 0, sizeof(hsplit_pipe
->stream_res
));
1293 resource_build_scaling_params(pipe
);
1295 /* for now important to do this after pipe split for building e2e params */
1296 dcn_bw_calc_rq_dlg_ttu(dc
, v
, pipe
, input_idx
);
1301 } else if (v
->voltage_level
== number_of_states_plus_one
) {
1302 BW_VAL_TRACE_SKIP(fail
);
1303 } else if (fast_validate
) {
1304 BW_VAL_TRACE_SKIP(fast
);
1307 if (v
->voltage_level
== 0) {
1308 context
->bw_ctx
.dml
.soc
.sr_enter_plus_exit_time_us
=
1309 dc
->dcn_soc
->sr_enter_plus_exit_time
;
1310 context
->bw_ctx
.dml
.soc
.sr_exit_time_us
= dc
->dcn_soc
->sr_exit_time
;
1314 * BW limit is set to prevent display from impacting other system functions
1317 bw_limit
= dc
->dcn_soc
->percent_disp_bw_limit
* v
->fabric_and_dram_bandwidth_vmax0p9
;
1318 bw_limit_pass
= (v
->total_data_read_bandwidth
/ 1000.0) < bw_limit
;
1322 PERFORMANCE_TRACE_END();
1323 BW_VAL_TRACE_FINISH();
1325 if (bw_limit_pass
&& v
->voltage_level
<= get_highest_allowed_voltage_level(
1326 dc
->ctx
->asic_id
.chip_family
,
1327 dc
->ctx
->asic_id
.hw_internal_rev
,
1328 dc
->ctx
->asic_id
.pci_revision_id
))
1334 static unsigned int dcn_find_normalized_clock_vdd_Level(
1335 const struct dc
*dc
,
1336 enum dm_pp_clock_type clocks_type
,
1339 int vdd_level
= dcn_bw_v_min0p65
;
1341 if (clocks_in_khz
== 0)/*todo some clock not in the considerations*/
1344 switch (clocks_type
) {
1345 case DM_PP_CLOCK_TYPE_DISPLAY_CLK
:
1346 if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vmax0p9
*1000) {
1347 vdd_level
= dcn_bw_v_max0p91
;
1348 BREAK_TO_DEBUGGER();
1349 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vnom0p8
*1000) {
1350 vdd_level
= dcn_bw_v_max0p9
;
1351 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vmid0p72
*1000) {
1352 vdd_level
= dcn_bw_v_nom0p8
;
1353 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vmin0p65
*1000) {
1354 vdd_level
= dcn_bw_v_mid0p72
;
1356 vdd_level
= dcn_bw_v_min0p65
;
1358 case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK
:
1359 if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_max0p9
*1000) {
1360 vdd_level
= dcn_bw_v_max0p91
;
1361 BREAK_TO_DEBUGGER();
1362 } else if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_nom0p8
*1000) {
1363 vdd_level
= dcn_bw_v_max0p9
;
1364 } else if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_mid0p72
*1000) {
1365 vdd_level
= dcn_bw_v_nom0p8
;
1366 } else if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_min0p65
*1000) {
1367 vdd_level
= dcn_bw_v_mid0p72
;
1369 vdd_level
= dcn_bw_v_min0p65
;
1372 case DM_PP_CLOCK_TYPE_DPPCLK
:
1373 if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vmax0p9
*1000) {
1374 vdd_level
= dcn_bw_v_max0p91
;
1375 BREAK_TO_DEBUGGER();
1376 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vnom0p8
*1000) {
1377 vdd_level
= dcn_bw_v_max0p9
;
1378 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vmid0p72
*1000) {
1379 vdd_level
= dcn_bw_v_nom0p8
;
1380 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vmin0p65
*1000) {
1381 vdd_level
= dcn_bw_v_mid0p72
;
1383 vdd_level
= dcn_bw_v_min0p65
;
1386 case DM_PP_CLOCK_TYPE_MEMORY_CLK
:
1388 unsigned factor
= (ddr4_dram_factor_single_Channel
* dc
->dcn_soc
->number_of_channels
);
1390 if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
*1000000/factor
) {
1391 vdd_level
= dcn_bw_v_max0p91
;
1392 BREAK_TO_DEBUGGER();
1393 } else if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
*1000000/factor
) {
1394 vdd_level
= dcn_bw_v_max0p9
;
1395 } else if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
*1000000/factor
) {
1396 vdd_level
= dcn_bw_v_nom0p8
;
1397 } else if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
*1000000/factor
) {
1398 vdd_level
= dcn_bw_v_mid0p72
;
1400 vdd_level
= dcn_bw_v_min0p65
;
1404 case DM_PP_CLOCK_TYPE_DCFCLK
:
1405 if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_max0p9
*1000) {
1406 vdd_level
= dcn_bw_v_max0p91
;
1407 BREAK_TO_DEBUGGER();
1408 } else if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_nom0p8
*1000) {
1409 vdd_level
= dcn_bw_v_max0p9
;
1410 } else if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_mid0p72
*1000) {
1411 vdd_level
= dcn_bw_v_nom0p8
;
1412 } else if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_min0p65
*1000) {
1413 vdd_level
= dcn_bw_v_mid0p72
;
1415 vdd_level
= dcn_bw_v_min0p65
;
1424 unsigned int dcn_find_dcfclk_suits_all(
1425 const struct dc
*dc
,
1426 struct dc_clocks
*clocks
)
1428 unsigned vdd_level
, vdd_level_temp
;
1431 /*find a common supported voltage level*/
1432 vdd_level
= dcn_find_normalized_clock_vdd_Level(
1433 dc
, DM_PP_CLOCK_TYPE_DISPLAY_CLK
, clocks
->dispclk_khz
);
1434 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1435 dc
, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK
, clocks
->phyclk_khz
);
1437 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1438 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1439 dc
, DM_PP_CLOCK_TYPE_DPPCLK
, clocks
->dppclk_khz
);
1440 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1442 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1443 dc
, DM_PP_CLOCK_TYPE_MEMORY_CLK
, clocks
->fclk_khz
);
1444 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1445 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1446 dc
, DM_PP_CLOCK_TYPE_DCFCLK
, clocks
->dcfclk_khz
);
1448 /*find that level conresponding dcfclk*/
1449 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1450 if (vdd_level
== dcn_bw_v_max0p91
) {
1451 BREAK_TO_DEBUGGER();
1452 dcf_clk
= dc
->dcn_soc
->dcfclkv_max0p9
*1000;
1453 } else if (vdd_level
== dcn_bw_v_max0p9
)
1454 dcf_clk
= dc
->dcn_soc
->dcfclkv_max0p9
*1000;
1455 else if (vdd_level
== dcn_bw_v_nom0p8
)
1456 dcf_clk
= dc
->dcn_soc
->dcfclkv_nom0p8
*1000;
1457 else if (vdd_level
== dcn_bw_v_mid0p72
)
1458 dcf_clk
= dc
->dcn_soc
->dcfclkv_mid0p72
*1000;
1460 dcf_clk
= dc
->dcn_soc
->dcfclkv_min0p65
*1000;
1462 DC_LOG_BANDWIDTH_CALCS("\tdcf_clk for voltage = %d\n", dcf_clk
);
1466 static bool verify_clock_values(struct dm_pp_clock_levels_with_voltage
*clks
)
1470 if (clks
->num_levels
== 0)
1473 for (i
= 0; i
< clks
->num_levels
; i
++)
1474 /* Ensure that the result is sane */
1475 if (clks
->data
[i
].clocks_in_khz
== 0)
1481 void dcn_bw_update_from_pplib(struct dc
*dc
)
1483 struct dc_context
*ctx
= dc
->ctx
;
1484 struct dm_pp_clock_levels_with_voltage fclks
= {0}, dcfclks
= {0};
1486 unsigned vmin0p65_idx
, vmid0p72_idx
, vnom0p8_idx
, vmax0p9_idx
;
1488 /* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
1489 res
= dm_pp_get_clock_levels_by_type_with_voltage(
1490 ctx
, DM_PP_CLOCK_TYPE_FCLK
, &fclks
);
1495 res
= verify_clock_values(&fclks
);
1498 ASSERT(fclks
.num_levels
);
1501 vmid0p72_idx
= fclks
.num_levels
-
1502 (fclks
.num_levels
> 2 ? 3 : (fclks
.num_levels
> 1 ? 2 : 1));
1503 vnom0p8_idx
= fclks
.num_levels
- (fclks
.num_levels
> 1 ? 2 : 1);
1504 vmax0p9_idx
= fclks
.num_levels
- 1;
1506 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
=
1507 32 * (fclks
.data
[vmin0p65_idx
].clocks_in_khz
/ 1000.0) / 1000.0;
1508 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
=
1509 dc
->dcn_soc
->number_of_channels
*
1510 (fclks
.data
[vmid0p72_idx
].clocks_in_khz
/ 1000.0)
1511 * ddr4_dram_factor_single_Channel
/ 1000.0;
1512 dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
=
1513 dc
->dcn_soc
->number_of_channels
*
1514 (fclks
.data
[vnom0p8_idx
].clocks_in_khz
/ 1000.0)
1515 * ddr4_dram_factor_single_Channel
/ 1000.0;
1516 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
=
1517 dc
->dcn_soc
->number_of_channels
*
1518 (fclks
.data
[vmax0p9_idx
].clocks_in_khz
/ 1000.0)
1519 * ddr4_dram_factor_single_Channel
/ 1000.0;
1521 BREAK_TO_DEBUGGER();
1525 res
= dm_pp_get_clock_levels_by_type_with_voltage(
1526 ctx
, DM_PP_CLOCK_TYPE_DCFCLK
, &dcfclks
);
1531 res
= verify_clock_values(&dcfclks
);
1533 if (res
&& dcfclks
.num_levels
>= 3) {
1534 dc
->dcn_soc
->dcfclkv_min0p65
= dcfclks
.data
[0].clocks_in_khz
/ 1000.0;
1535 dc
->dcn_soc
->dcfclkv_mid0p72
= dcfclks
.data
[dcfclks
.num_levels
- 3].clocks_in_khz
/ 1000.0;
1536 dc
->dcn_soc
->dcfclkv_nom0p8
= dcfclks
.data
[dcfclks
.num_levels
- 2].clocks_in_khz
/ 1000.0;
1537 dc
->dcn_soc
->dcfclkv_max0p9
= dcfclks
.data
[dcfclks
.num_levels
- 1].clocks_in_khz
/ 1000.0;
1539 BREAK_TO_DEBUGGER();
1544 void dcn_bw_notify_pplib_of_wm_ranges(struct dc
*dc
)
1546 struct pp_smu_funcs_rv
*pp
= NULL
;
1547 struct pp_smu_wm_range_sets ranges
= {0};
1548 int min_fclk_khz
, min_dcfclk_khz
, socclk_khz
;
1549 const int overdrive
= 5000000; /* 5 GHz to cover Overdrive */
1551 if (dc
->res_pool
->pp_smu
)
1552 pp
= &dc
->res_pool
->pp_smu
->rv_funcs
;
1553 if (!pp
|| !pp
->set_wm_ranges
)
1557 min_fclk_khz
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
* 1000000 / 32;
1558 min_dcfclk_khz
= dc
->dcn_soc
->dcfclkv_min0p65
* 1000;
1559 socclk_khz
= dc
->dcn_soc
->socclk
* 1000;
1562 /* Now notify PPLib/SMU about which Watermarks sets they should select
1563 * depending on DPM state they are in. And update BW MGR GFX Engine and
1564 * Memory clock member variables for Watermarks calculations for each
1565 * Watermark Set. Only one watermark set for dcn1 due to hw bug DEGVIDCN10-254.
1567 /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont
1568 * care what the value is, hence min to overdrive level
1570 ranges
.num_reader_wm_sets
= WM_SET_COUNT
;
1571 ranges
.num_writer_wm_sets
= WM_SET_COUNT
;
1572 ranges
.reader_wm_sets
[0].wm_inst
= WM_A
;
1573 ranges
.reader_wm_sets
[0].min_drain_clk_mhz
= min_dcfclk_khz
/ 1000;
1574 ranges
.reader_wm_sets
[0].max_drain_clk_mhz
= overdrive
/ 1000;
1575 ranges
.reader_wm_sets
[0].min_fill_clk_mhz
= min_fclk_khz
/ 1000;
1576 ranges
.reader_wm_sets
[0].max_fill_clk_mhz
= overdrive
/ 1000;
1577 ranges
.writer_wm_sets
[0].wm_inst
= WM_A
;
1578 ranges
.writer_wm_sets
[0].min_fill_clk_mhz
= socclk_khz
/ 1000;
1579 ranges
.writer_wm_sets
[0].max_fill_clk_mhz
= overdrive
/ 1000;
1580 ranges
.writer_wm_sets
[0].min_drain_clk_mhz
= min_fclk_khz
/ 1000;
1581 ranges
.writer_wm_sets
[0].max_drain_clk_mhz
= overdrive
/ 1000;
1583 if (dc
->debug
.pplib_wm_report_mode
== WM_REPORT_OVERRIDE
) {
1584 ranges
.reader_wm_sets
[0].wm_inst
= WM_A
;
1585 ranges
.reader_wm_sets
[0].min_drain_clk_mhz
= 300;
1586 ranges
.reader_wm_sets
[0].max_drain_clk_mhz
= 5000;
1587 ranges
.reader_wm_sets
[0].min_fill_clk_mhz
= 800;
1588 ranges
.reader_wm_sets
[0].max_fill_clk_mhz
= 5000;
1589 ranges
.writer_wm_sets
[0].wm_inst
= WM_A
;
1590 ranges
.writer_wm_sets
[0].min_fill_clk_mhz
= 200;
1591 ranges
.writer_wm_sets
[0].max_fill_clk_mhz
= 5000;
1592 ranges
.writer_wm_sets
[0].min_drain_clk_mhz
= 800;
1593 ranges
.writer_wm_sets
[0].max_drain_clk_mhz
= 5000;
1596 ranges
.reader_wm_sets
[1] = ranges
.writer_wm_sets
[0];
1597 ranges
.reader_wm_sets
[1].wm_inst
= WM_B
;
1599 ranges
.reader_wm_sets
[2] = ranges
.writer_wm_sets
[0];
1600 ranges
.reader_wm_sets
[2].wm_inst
= WM_C
;
1602 ranges
.reader_wm_sets
[3] = ranges
.writer_wm_sets
[0];
1603 ranges
.reader_wm_sets
[3].wm_inst
= WM_D
;
1605 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1606 pp
->set_wm_ranges(&pp
->pp_smu
, &ranges
);
1609 void dcn_bw_sync_calcs_and_dml(struct dc
*dc
)
1612 DC_LOG_BANDWIDTH_CALCS("sr_exit_time: %f ns\n"
1613 "sr_enter_plus_exit_time: %f ns\n"
1614 "urgent_latency: %f ns\n"
1615 "write_back_latency: %f ns\n"
1616 "percent_of_ideal_drambw_received_after_urg_latency: %f %%\n"
1617 "max_request_size: %d bytes\n"
1618 "dcfclkv_max0p9: %f kHz\n"
1619 "dcfclkv_nom0p8: %f kHz\n"
1620 "dcfclkv_mid0p72: %f kHz\n"
1621 "dcfclkv_min0p65: %f kHz\n"
1622 "max_dispclk_vmax0p9: %f kHz\n"
1623 "max_dispclk_vnom0p8: %f kHz\n"
1624 "max_dispclk_vmid0p72: %f kHz\n"
1625 "max_dispclk_vmin0p65: %f kHz\n"
1626 "max_dppclk_vmax0p9: %f kHz\n"
1627 "max_dppclk_vnom0p8: %f kHz\n"
1628 "max_dppclk_vmid0p72: %f kHz\n"
1629 "max_dppclk_vmin0p65: %f kHz\n"
1631 "fabric_and_dram_bandwidth_vmax0p9: %f MB/s\n"
1632 "fabric_and_dram_bandwidth_vnom0p8: %f MB/s\n"
1633 "fabric_and_dram_bandwidth_vmid0p72: %f MB/s\n"
1634 "fabric_and_dram_bandwidth_vmin0p65: %f MB/s\n"
1635 "phyclkv_max0p9: %f kHz\n"
1636 "phyclkv_nom0p8: %f kHz\n"
1637 "phyclkv_mid0p72: %f kHz\n"
1638 "phyclkv_min0p65: %f kHz\n"
1639 "downspreading: %f %%\n"
1640 "round_trip_ping_latency_cycles: %d DCFCLK Cycles\n"
1641 "urgent_out_of_order_return_per_channel: %d Bytes\n"
1642 "number_of_channels: %d\n"
1643 "vmm_page_size: %d Bytes\n"
1644 "dram_clock_change_latency: %f ns\n"
1645 "return_bus_width: %d Bytes\n",
1646 dc
->dcn_soc
->sr_exit_time
* 1000,
1647 dc
->dcn_soc
->sr_enter_plus_exit_time
* 1000,
1648 dc
->dcn_soc
->urgent_latency
* 1000,
1649 dc
->dcn_soc
->write_back_latency
* 1000,
1650 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
,
1651 dc
->dcn_soc
->max_request_size
,
1652 dc
->dcn_soc
->dcfclkv_max0p9
* 1000,
1653 dc
->dcn_soc
->dcfclkv_nom0p8
* 1000,
1654 dc
->dcn_soc
->dcfclkv_mid0p72
* 1000,
1655 dc
->dcn_soc
->dcfclkv_min0p65
* 1000,
1656 dc
->dcn_soc
->max_dispclk_vmax0p9
* 1000,
1657 dc
->dcn_soc
->max_dispclk_vnom0p8
* 1000,
1658 dc
->dcn_soc
->max_dispclk_vmid0p72
* 1000,
1659 dc
->dcn_soc
->max_dispclk_vmin0p65
* 1000,
1660 dc
->dcn_soc
->max_dppclk_vmax0p9
* 1000,
1661 dc
->dcn_soc
->max_dppclk_vnom0p8
* 1000,
1662 dc
->dcn_soc
->max_dppclk_vmid0p72
* 1000,
1663 dc
->dcn_soc
->max_dppclk_vmin0p65
* 1000,
1664 dc
->dcn_soc
->socclk
* 1000,
1665 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
* 1000,
1666 dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
* 1000,
1667 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
* 1000,
1668 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
* 1000,
1669 dc
->dcn_soc
->phyclkv_max0p9
* 1000,
1670 dc
->dcn_soc
->phyclkv_nom0p8
* 1000,
1671 dc
->dcn_soc
->phyclkv_mid0p72
* 1000,
1672 dc
->dcn_soc
->phyclkv_min0p65
* 1000,
1673 dc
->dcn_soc
->downspreading
* 100,
1674 dc
->dcn_soc
->round_trip_ping_latency_cycles
,
1675 dc
->dcn_soc
->urgent_out_of_order_return_per_channel
,
1676 dc
->dcn_soc
->number_of_channels
,
1677 dc
->dcn_soc
->vmm_page_size
,
1678 dc
->dcn_soc
->dram_clock_change_latency
* 1000,
1679 dc
->dcn_soc
->return_bus_width
);
1680 DC_LOG_BANDWIDTH_CALCS("rob_buffer_size_in_kbyte: %f\n"
1681 "det_buffer_size_in_kbyte: %f\n"
1682 "dpp_output_buffer_pixels: %f\n"
1683 "opp_output_buffer_lines: %f\n"
1684 "pixel_chunk_size_in_kbyte: %f\n"
1686 "pte_chunk_size: %d kbytes\n"
1687 "meta_chunk_size: %d kbytes\n"
1688 "writeback_chunk_size: %d kbytes\n"
1689 "odm_capability: %d\n"
1690 "dsc_capability: %d\n"
1691 "line_buffer_size: %d bits\n"
1692 "max_line_buffer_lines: %d\n"
1693 "is_line_buffer_bpp_fixed: %d\n"
1694 "line_buffer_fixed_bpp: %d\n"
1695 "writeback_luma_buffer_size: %d kbytes\n"
1696 "writeback_chroma_buffer_size: %d kbytes\n"
1698 "max_num_writeback: %d\n"
1699 "max_dchub_topscl_throughput: %d pixels/dppclk\n"
1700 "max_pscl_tolb_throughput: %d pixels/dppclk\n"
1701 "max_lb_tovscl_throughput: %d pixels/dppclk\n"
1702 "max_vscl_tohscl_throughput: %d pixels/dppclk\n"
1703 "max_hscl_ratio: %f\n"
1704 "max_vscl_ratio: %f\n"
1705 "max_hscl_taps: %d\n"
1706 "max_vscl_taps: %d\n"
1707 "pte_buffer_size_in_requests: %d\n"
1708 "dispclk_ramping_margin: %f %%\n"
1709 "under_scan_factor: %f %%\n"
1710 "max_inter_dcn_tile_repeaters: %d\n"
1711 "can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one: %d\n"
1712 "bug_forcing_luma_and_chroma_request_to_same_size_fixed: %d\n"
1713 "dcfclk_cstate_latency: %d\n",
1714 dc
->dcn_ip
->rob_buffer_size_in_kbyte
,
1715 dc
->dcn_ip
->det_buffer_size_in_kbyte
,
1716 dc
->dcn_ip
->dpp_output_buffer_pixels
,
1717 dc
->dcn_ip
->opp_output_buffer_lines
,
1718 dc
->dcn_ip
->pixel_chunk_size_in_kbyte
,
1719 dc
->dcn_ip
->pte_enable
,
1720 dc
->dcn_ip
->pte_chunk_size
,
1721 dc
->dcn_ip
->meta_chunk_size
,
1722 dc
->dcn_ip
->writeback_chunk_size
,
1723 dc
->dcn_ip
->odm_capability
,
1724 dc
->dcn_ip
->dsc_capability
,
1725 dc
->dcn_ip
->line_buffer_size
,
1726 dc
->dcn_ip
->max_line_buffer_lines
,
1727 dc
->dcn_ip
->is_line_buffer_bpp_fixed
,
1728 dc
->dcn_ip
->line_buffer_fixed_bpp
,
1729 dc
->dcn_ip
->writeback_luma_buffer_size
,
1730 dc
->dcn_ip
->writeback_chroma_buffer_size
,
1731 dc
->dcn_ip
->max_num_dpp
,
1732 dc
->dcn_ip
->max_num_writeback
,
1733 dc
->dcn_ip
->max_dchub_topscl_throughput
,
1734 dc
->dcn_ip
->max_pscl_tolb_throughput
,
1735 dc
->dcn_ip
->max_lb_tovscl_throughput
,
1736 dc
->dcn_ip
->max_vscl_tohscl_throughput
,
1737 dc
->dcn_ip
->max_hscl_ratio
,
1738 dc
->dcn_ip
->max_vscl_ratio
,
1739 dc
->dcn_ip
->max_hscl_taps
,
1740 dc
->dcn_ip
->max_vscl_taps
,
1741 dc
->dcn_ip
->pte_buffer_size_in_requests
,
1742 dc
->dcn_ip
->dispclk_ramping_margin
,
1743 dc
->dcn_ip
->under_scan_factor
* 100,
1744 dc
->dcn_ip
->max_inter_dcn_tile_repeaters
,
1745 dc
->dcn_ip
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
,
1746 dc
->dcn_ip
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
,
1747 dc
->dcn_ip
->dcfclk_cstate_latency
);
1749 dc
->dml
.soc
.sr_exit_time_us
= dc
->dcn_soc
->sr_exit_time
;
1750 dc
->dml
.soc
.sr_enter_plus_exit_time_us
= dc
->dcn_soc
->sr_enter_plus_exit_time
;
1751 dc
->dml
.soc
.urgent_latency_us
= dc
->dcn_soc
->urgent_latency
;
1752 dc
->dml
.soc
.writeback_latency_us
= dc
->dcn_soc
->write_back_latency
;
1753 dc
->dml
.soc
.ideal_dram_bw_after_urgent_percent
=
1754 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
;
1755 dc
->dml
.soc
.max_request_size_bytes
= dc
->dcn_soc
->max_request_size
;
1756 dc
->dml
.soc
.downspread_percent
= dc
->dcn_soc
->downspreading
;
1757 dc
->dml
.soc
.round_trip_ping_latency_dcfclk_cycles
=
1758 dc
->dcn_soc
->round_trip_ping_latency_cycles
;
1759 dc
->dml
.soc
.urgent_out_of_order_return_per_channel_bytes
=
1760 dc
->dcn_soc
->urgent_out_of_order_return_per_channel
;
1761 dc
->dml
.soc
.num_chans
= dc
->dcn_soc
->number_of_channels
;
1762 dc
->dml
.soc
.vmm_page_size_bytes
= dc
->dcn_soc
->vmm_page_size
;
1763 dc
->dml
.soc
.dram_clock_change_latency_us
= dc
->dcn_soc
->dram_clock_change_latency
;
1764 dc
->dml
.soc
.return_bus_width_bytes
= dc
->dcn_soc
->return_bus_width
;
1766 dc
->dml
.ip
.rob_buffer_size_kbytes
= dc
->dcn_ip
->rob_buffer_size_in_kbyte
;
1767 dc
->dml
.ip
.det_buffer_size_kbytes
= dc
->dcn_ip
->det_buffer_size_in_kbyte
;
1768 dc
->dml
.ip
.dpp_output_buffer_pixels
= dc
->dcn_ip
->dpp_output_buffer_pixels
;
1769 dc
->dml
.ip
.opp_output_buffer_lines
= dc
->dcn_ip
->opp_output_buffer_lines
;
1770 dc
->dml
.ip
.pixel_chunk_size_kbytes
= dc
->dcn_ip
->pixel_chunk_size_in_kbyte
;
1771 dc
->dml
.ip
.pte_enable
= dc
->dcn_ip
->pte_enable
== dcn_bw_yes
;
1772 dc
->dml
.ip
.pte_chunk_size_kbytes
= dc
->dcn_ip
->pte_chunk_size
;
1773 dc
->dml
.ip
.meta_chunk_size_kbytes
= dc
->dcn_ip
->meta_chunk_size
;
1774 dc
->dml
.ip
.writeback_chunk_size_kbytes
= dc
->dcn_ip
->writeback_chunk_size
;
1775 dc
->dml
.ip
.line_buffer_size_bits
= dc
->dcn_ip
->line_buffer_size
;
1776 dc
->dml
.ip
.max_line_buffer_lines
= dc
->dcn_ip
->max_line_buffer_lines
;
1777 dc
->dml
.ip
.IsLineBufferBppFixed
= dc
->dcn_ip
->is_line_buffer_bpp_fixed
== dcn_bw_yes
;
1778 dc
->dml
.ip
.LineBufferFixedBpp
= dc
->dcn_ip
->line_buffer_fixed_bpp
;
1779 dc
->dml
.ip
.writeback_luma_buffer_size_kbytes
= dc
->dcn_ip
->writeback_luma_buffer_size
;
1780 dc
->dml
.ip
.writeback_chroma_buffer_size_kbytes
= dc
->dcn_ip
->writeback_chroma_buffer_size
;
1781 dc
->dml
.ip
.max_num_dpp
= dc
->dcn_ip
->max_num_dpp
;
1782 dc
->dml
.ip
.max_num_wb
= dc
->dcn_ip
->max_num_writeback
;
1783 dc
->dml
.ip
.max_dchub_pscl_bw_pix_per_clk
= dc
->dcn_ip
->max_dchub_topscl_throughput
;
1784 dc
->dml
.ip
.max_pscl_lb_bw_pix_per_clk
= dc
->dcn_ip
->max_pscl_tolb_throughput
;
1785 dc
->dml
.ip
.max_lb_vscl_bw_pix_per_clk
= dc
->dcn_ip
->max_lb_tovscl_throughput
;
1786 dc
->dml
.ip
.max_vscl_hscl_bw_pix_per_clk
= dc
->dcn_ip
->max_vscl_tohscl_throughput
;
1787 dc
->dml
.ip
.max_hscl_ratio
= dc
->dcn_ip
->max_hscl_ratio
;
1788 dc
->dml
.ip
.max_vscl_ratio
= dc
->dcn_ip
->max_vscl_ratio
;
1789 dc
->dml
.ip
.max_hscl_taps
= dc
->dcn_ip
->max_hscl_taps
;
1790 dc
->dml
.ip
.max_vscl_taps
= dc
->dcn_ip
->max_vscl_taps
;
1791 /*pte_buffer_size_in_requests missing in dml*/
1792 dc
->dml
.ip
.dispclk_ramp_margin_percent
= dc
->dcn_ip
->dispclk_ramping_margin
;
1793 dc
->dml
.ip
.underscan_factor
= dc
->dcn_ip
->under_scan_factor
;
1794 dc
->dml
.ip
.max_inter_dcn_tile_repeaters
= dc
->dcn_ip
->max_inter_dcn_tile_repeaters
;
1795 dc
->dml
.ip
.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
=
1796 dc
->dcn_ip
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
== dcn_bw_yes
;
1797 dc
->dml
.ip
.bug_forcing_LC_req_same_size_fixed
=
1798 dc
->dcn_ip
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
== dcn_bw_yes
;
1799 dc
->dml
.ip
.dcfclk_cstate_latency
= dc
->dcn_ip
->dcfclk_cstate_latency
;