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;
305 if (pipe
->top_pipe
!= NULL
&& pipe
->top_pipe
->plane_state
== pipe
->plane_state
)
306 input
->src
.is_hsplit
= true;
307 else if (pipe
->bottom_pipe
!= NULL
&& pipe
->bottom_pipe
->plane_state
== pipe
->plane_state
)
308 input
->src
.is_hsplit
= true;
310 if (pipe
->plane_res
.dpp
->ctx
->dc
->debug
.optimized_watermark
) {
312 * this method requires us to always re-calculate watermark when dcc change
315 input
->src
.dcc
= pipe
->plane_state
->dcc
.enable
? 1 : 0;
318 * allow us to disable dcc on the fly without re-calculating WM
320 * extra overhead for DCC is quite small. for 1080p WM without
321 * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us)
325 input
->src
.dcc
= pipe
->plane_res
.dpp
->ctx
->dc
->res_pool
->hubbub
->funcs
->
326 dcc_support_pixel_format(pipe
->plane_state
->format
, &bpe
) ? 1 : 0;
328 input
->src
.dcc_rate
= 1;
329 input
->src
.meta_pitch
= pipe
->plane_state
->dcc
.meta_pitch
;
330 input
->src
.source_scan
= dm_horz
;
331 input
->src
.sw_mode
= pipe
->plane_state
->tiling_info
.gfx9
.swizzle
;
333 input
->src
.viewport_width
= pipe
->plane_res
.scl_data
.viewport
.width
;
334 input
->src
.viewport_height
= pipe
->plane_res
.scl_data
.viewport
.height
;
335 input
->src
.data_pitch
= pipe
->plane_res
.scl_data
.viewport
.width
;
336 input
->src
.data_pitch_c
= pipe
->plane_res
.scl_data
.viewport
.width
;
337 input
->src
.cur0_src_width
= 128; /* TODO: Cursor calcs, not curently stored */
338 input
->src
.cur0_bpp
= 32;
340 input
->src
.macro_tile_size
= swizzle_mode_to_macro_tile_size(pipe
->plane_state
->tiling_info
.gfx9
.swizzle
);
342 switch (pipe
->plane_state
->rotation
) {
343 case ROTATION_ANGLE_0
:
344 case ROTATION_ANGLE_180
:
345 input
->src
.source_scan
= dm_horz
;
347 case ROTATION_ANGLE_90
:
348 case ROTATION_ANGLE_270
:
349 input
->src
.source_scan
= dm_vert
;
352 ASSERT(0); /* Not supported */
356 /* TODO: Fix pixel format mappings */
357 switch (pipe
->plane_state
->format
) {
358 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr
:
359 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb
:
360 input
->src
.source_format
= dm_420_8
;
361 input
->src
.viewport_width_c
= input
->src
.viewport_width
/ 2;
362 input
->src
.viewport_height_c
= input
->src
.viewport_height
/ 2;
364 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr
:
365 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb
:
366 input
->src
.source_format
= dm_420_10
;
367 input
->src
.viewport_width_c
= input
->src
.viewport_width
/ 2;
368 input
->src
.viewport_height_c
= input
->src
.viewport_height
/ 2;
370 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
:
371 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F
:
372 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:
373 input
->src
.source_format
= dm_444_64
;
374 input
->src
.viewport_width_c
= input
->src
.viewport_width
;
375 input
->src
.viewport_height_c
= input
->src
.viewport_height
;
378 input
->src
.source_format
= dm_444_32
;
379 input
->src
.viewport_width_c
= input
->src
.viewport_width
;
380 input
->src
.viewport_height_c
= input
->src
.viewport_height
;
384 input
->scale_taps
.htaps
= pipe
->plane_res
.scl_data
.taps
.h_taps
;
385 input
->scale_ratio_depth
.hscl_ratio
= pipe
->plane_res
.scl_data
.ratios
.horz
.value
/4294967296.0;
386 input
->scale_ratio_depth
.vscl_ratio
= pipe
->plane_res
.scl_data
.ratios
.vert
.value
/4294967296.0;
387 input
->scale_ratio_depth
.vinit
= pipe
->plane_res
.scl_data
.inits
.v
.value
/4294967296.0;
388 if (input
->scale_ratio_depth
.vinit
< 1.0)
389 input
->scale_ratio_depth
.vinit
= 1;
390 input
->scale_taps
.vtaps
= pipe
->plane_res
.scl_data
.taps
.v_taps
;
391 input
->scale_taps
.vtaps_c
= pipe
->plane_res
.scl_data
.taps
.v_taps_c
;
392 input
->scale_taps
.htaps_c
= pipe
->plane_res
.scl_data
.taps
.h_taps_c
;
393 input
->scale_ratio_depth
.hscl_ratio_c
= pipe
->plane_res
.scl_data
.ratios
.horz_c
.value
/4294967296.0;
394 input
->scale_ratio_depth
.vscl_ratio_c
= pipe
->plane_res
.scl_data
.ratios
.vert_c
.value
/4294967296.0;
395 input
->scale_ratio_depth
.vinit_c
= pipe
->plane_res
.scl_data
.inits
.v_c
.value
/4294967296.0;
396 if (input
->scale_ratio_depth
.vinit_c
< 1.0)
397 input
->scale_ratio_depth
.vinit_c
= 1;
398 switch (pipe
->plane_res
.scl_data
.lb_params
.depth
) {
399 case LB_PIXEL_DEPTH_30BPP
:
400 input
->scale_ratio_depth
.lb_depth
= 30; break;
401 case LB_PIXEL_DEPTH_36BPP
:
402 input
->scale_ratio_depth
.lb_depth
= 36; break;
404 input
->scale_ratio_depth
.lb_depth
= 24; break;
408 input
->dest
.vactive
= pipe
->stream
->timing
.v_addressable
+ pipe
->stream
->timing
.v_border_top
409 + pipe
->stream
->timing
.v_border_bottom
;
411 input
->dest
.recout_width
= pipe
->plane_res
.scl_data
.recout
.width
;
412 input
->dest
.recout_height
= pipe
->plane_res
.scl_data
.recout
.height
;
414 input
->dest
.full_recout_width
= pipe
->plane_res
.scl_data
.recout
.width
;
415 input
->dest
.full_recout_height
= pipe
->plane_res
.scl_data
.recout
.height
;
417 input
->dest
.htotal
= pipe
->stream
->timing
.h_total
;
418 input
->dest
.hblank_start
= input
->dest
.htotal
- pipe
->stream
->timing
.h_front_porch
;
419 input
->dest
.hblank_end
= input
->dest
.hblank_start
420 - pipe
->stream
->timing
.h_addressable
421 - pipe
->stream
->timing
.h_border_left
422 - pipe
->stream
->timing
.h_border_right
;
424 input
->dest
.vtotal
= pipe
->stream
->timing
.v_total
;
425 input
->dest
.vblank_start
= input
->dest
.vtotal
- pipe
->stream
->timing
.v_front_porch
;
426 input
->dest
.vblank_end
= input
->dest
.vblank_start
427 - pipe
->stream
->timing
.v_addressable
428 - pipe
->stream
->timing
.v_border_bottom
429 - pipe
->stream
->timing
.v_border_top
;
430 input
->dest
.pixel_rate_mhz
= pipe
->stream
->timing
.pix_clk_100hz
/10000.0;
431 input
->dest
.vstartup_start
= pipe
->pipe_dlg_param
.vstartup_start
;
432 input
->dest
.vupdate_offset
= pipe
->pipe_dlg_param
.vupdate_offset
;
433 input
->dest
.vupdate_offset
= pipe
->pipe_dlg_param
.vupdate_offset
;
434 input
->dest
.vupdate_width
= pipe
->pipe_dlg_param
.vupdate_width
;
438 static void dcn_bw_calc_rq_dlg_ttu(
440 const struct dcn_bw_internal_vars
*v
,
441 struct pipe_ctx
*pipe
,
444 struct display_mode_lib
*dml
= (struct display_mode_lib
*)(&dc
->dml
);
445 struct _vcs_dpi_display_dlg_regs_st
*dlg_regs
= &pipe
->dlg_regs
;
446 struct _vcs_dpi_display_ttu_regs_st
*ttu_regs
= &pipe
->ttu_regs
;
447 struct _vcs_dpi_display_rq_regs_st
*rq_regs
= &pipe
->rq_regs
;
448 struct _vcs_dpi_display_rq_params_st rq_param
= {0};
449 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param
= {0};
450 struct _vcs_dpi_display_e2e_pipe_params_st input
= { { { 0 } } };
451 float total_active_bw
= 0;
452 float total_prefetch_bw
= 0;
453 int total_flip_bytes
= 0;
456 memset(dlg_regs
, 0, sizeof(*dlg_regs
));
457 memset(ttu_regs
, 0, sizeof(*ttu_regs
));
458 memset(rq_regs
, 0, sizeof(*rq_regs
));
460 for (i
= 0; i
< number_of_planes
; i
++) {
461 total_active_bw
+= v
->read_bandwidth
[i
];
462 total_prefetch_bw
+= v
->prefetch_bandwidth
[i
];
463 total_flip_bytes
+= v
->total_immediate_flip_bytes
[i
];
465 dlg_sys_param
.total_flip_bw
= v
->return_bw
- dcn_bw_max2(total_active_bw
, total_prefetch_bw
);
466 if (dlg_sys_param
.total_flip_bw
< 0.0)
467 dlg_sys_param
.total_flip_bw
= 0;
469 dlg_sys_param
.t_mclk_wm_us
= v
->dram_clock_change_watermark
;
470 dlg_sys_param
.t_sr_wm_us
= v
->stutter_enter_plus_exit_watermark
;
471 dlg_sys_param
.t_urg_wm_us
= v
->urgent_watermark
;
472 dlg_sys_param
.t_extra_us
= v
->urgent_extra_latency
;
473 dlg_sys_param
.deepsleep_dcfclk_mhz
= v
->dcf_clk_deep_sleep
;
474 dlg_sys_param
.total_flip_bytes
= total_flip_bytes
;
476 pipe_ctx_to_e2e_pipe_params(pipe
, &input
.pipe
);
477 input
.clks_cfg
.dcfclk_mhz
= v
->dcfclk
;
478 input
.clks_cfg
.dispclk_mhz
= v
->dispclk
;
479 input
.clks_cfg
.dppclk_mhz
= v
->dppclk
;
480 input
.clks_cfg
.refclk_mhz
= dc
->res_pool
->ref_clocks
.dchub_ref_clock_inKhz
/ 1000.0;
481 input
.clks_cfg
.socclk_mhz
= v
->socclk
;
482 input
.clks_cfg
.voltage
= v
->voltage_level
;
483 // dc->dml.logger = pool->base.logger;
484 input
.dout
.output_format
= (v
->output_format
[in_idx
] == dcn_bw_420
) ? dm_420
: dm_444
;
485 input
.dout
.output_type
= (v
->output
[in_idx
] == dcn_bw_hdmi
) ? dm_hdmi
: dm_dp
;
486 //input[in_idx].dout.output_standard;
488 /*todo: soc->sr_enter_plus_exit_time??*/
489 dlg_sys_param
.t_srx_delay_us
= dc
->dcn_ip
->dcfclk_cstate_latency
/ v
->dcf_clk_deep_sleep
;
491 dml1_rq_dlg_get_rq_params(dml
, &rq_param
, input
.pipe
.src
);
492 dml1_extract_rq_regs(dml
, rq_regs
, rq_param
);
493 dml1_rq_dlg_get_dlg_params(
502 v
->pte_enable
== dcn_bw_yes
,
503 pipe
->plane_state
->flip_immediate
);
506 static void split_stream_across_pipes(
507 struct resource_context
*res_ctx
,
508 const struct resource_pool
*pool
,
509 struct pipe_ctx
*primary_pipe
,
510 struct pipe_ctx
*secondary_pipe
)
512 int pipe_idx
= secondary_pipe
->pipe_idx
;
514 if (!primary_pipe
->plane_state
)
517 *secondary_pipe
= *primary_pipe
;
519 secondary_pipe
->pipe_idx
= pipe_idx
;
520 secondary_pipe
->plane_res
.mi
= pool
->mis
[secondary_pipe
->pipe_idx
];
521 secondary_pipe
->plane_res
.hubp
= pool
->hubps
[secondary_pipe
->pipe_idx
];
522 secondary_pipe
->plane_res
.ipp
= pool
->ipps
[secondary_pipe
->pipe_idx
];
523 secondary_pipe
->plane_res
.xfm
= pool
->transforms
[secondary_pipe
->pipe_idx
];
524 secondary_pipe
->plane_res
.dpp
= pool
->dpps
[secondary_pipe
->pipe_idx
];
525 secondary_pipe
->plane_res
.mpcc_inst
= pool
->dpps
[secondary_pipe
->pipe_idx
]->inst
;
526 if (primary_pipe
->bottom_pipe
) {
527 ASSERT(primary_pipe
->bottom_pipe
!= secondary_pipe
);
528 secondary_pipe
->bottom_pipe
= primary_pipe
->bottom_pipe
;
529 secondary_pipe
->bottom_pipe
->top_pipe
= secondary_pipe
;
531 primary_pipe
->bottom_pipe
= secondary_pipe
;
532 secondary_pipe
->top_pipe
= primary_pipe
;
534 resource_build_scaling_params(primary_pipe
);
535 resource_build_scaling_params(secondary_pipe
);
539 static void calc_wm_sets_and_perf_params(
540 struct dc_state
*context
,
541 struct dcn_bw_internal_vars
*v
)
543 /* Calculate set A last to keep internal var state consistent for required config */
544 if (v
->voltage_level
< 2) {
545 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vnom0p8
;
546 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vnom0p8
;
547 v
->fabric_and_dram_bandwidth
= v
->fabric_and_dram_bandwidth_vnom0p8
;
548 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
550 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.cstate_pstate
.cstate_exit_ns
=
551 v
->stutter_exit_watermark
* 1000;
552 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.cstate_pstate
.cstate_enter_plus_exit_ns
=
553 v
->stutter_enter_plus_exit_watermark
* 1000;
554 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.cstate_pstate
.pstate_change_ns
=
555 v
->dram_clock_change_watermark
* 1000;
556 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
557 context
->bw_ctx
.bw
.dcn
.watermarks
.b
.urgent_ns
= v
->urgent_watermark
* 1000;
559 v
->dcfclk_per_state
[1] = v
->dcfclkv_nom0p8
;
560 v
->dcfclk_per_state
[0] = v
->dcfclkv_nom0p8
;
561 v
->dcfclk
= v
->dcfclkv_nom0p8
;
562 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
564 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.cstate_pstate
.cstate_exit_ns
=
565 v
->stutter_exit_watermark
* 1000;
566 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.cstate_pstate
.cstate_enter_plus_exit_ns
=
567 v
->stutter_enter_plus_exit_watermark
* 1000;
568 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.cstate_pstate
.pstate_change_ns
=
569 v
->dram_clock_change_watermark
* 1000;
570 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
571 context
->bw_ctx
.bw
.dcn
.watermarks
.c
.urgent_ns
= v
->urgent_watermark
* 1000;
574 if (v
->voltage_level
< 3) {
575 v
->fabric_and_dram_bandwidth_per_state
[2] = v
->fabric_and_dram_bandwidth_vmax0p9
;
576 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vmax0p9
;
577 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vmax0p9
;
578 v
->fabric_and_dram_bandwidth
= v
->fabric_and_dram_bandwidth_vmax0p9
;
579 v
->dcfclk_per_state
[2] = v
->dcfclkv_max0p9
;
580 v
->dcfclk_per_state
[1] = v
->dcfclkv_max0p9
;
581 v
->dcfclk_per_state
[0] = v
->dcfclkv_max0p9
;
582 v
->dcfclk
= v
->dcfclkv_max0p9
;
583 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
585 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.cstate_pstate
.cstate_exit_ns
=
586 v
->stutter_exit_watermark
* 1000;
587 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.cstate_pstate
.cstate_enter_plus_exit_ns
=
588 v
->stutter_enter_plus_exit_watermark
* 1000;
589 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.cstate_pstate
.pstate_change_ns
=
590 v
->dram_clock_change_watermark
* 1000;
591 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
592 context
->bw_ctx
.bw
.dcn
.watermarks
.d
.urgent_ns
= v
->urgent_watermark
* 1000;
595 v
->fabric_and_dram_bandwidth_per_state
[2] = v
->fabric_and_dram_bandwidth_vnom0p8
;
596 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vmid0p72
;
597 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vmin0p65
;
598 v
->fabric_and_dram_bandwidth
= v
->fabric_and_dram_bandwidth_per_state
[v
->voltage_level
];
599 v
->dcfclk_per_state
[2] = v
->dcfclkv_nom0p8
;
600 v
->dcfclk_per_state
[1] = v
->dcfclkv_mid0p72
;
601 v
->dcfclk_per_state
[0] = v
->dcfclkv_min0p65
;
602 v
->dcfclk
= v
->dcfclk_per_state
[v
->voltage_level
];
603 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
605 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_exit_ns
=
606 v
->stutter_exit_watermark
* 1000;
607 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_enter_plus_exit_ns
=
608 v
->stutter_enter_plus_exit_watermark
* 1000;
609 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.pstate_change_ns
=
610 v
->dram_clock_change_watermark
* 1000;
611 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
612 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.urgent_ns
= v
->urgent_watermark
* 1000;
613 if (v
->voltage_level
>= 2) {
614 context
->bw_ctx
.bw
.dcn
.watermarks
.b
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
615 context
->bw_ctx
.bw
.dcn
.watermarks
.c
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
617 if (v
->voltage_level
>= 3)
618 context
->bw_ctx
.bw
.dcn
.watermarks
.d
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
622 static bool dcn_bw_apply_registry_override(struct dc
*dc
)
624 bool updated
= false;
627 if ((int)(dc
->dcn_soc
->sr_exit_time
* 1000) != dc
->debug
.sr_exit_time_ns
628 && dc
->debug
.sr_exit_time_ns
) {
630 dc
->dcn_soc
->sr_exit_time
= dc
->debug
.sr_exit_time_ns
/ 1000.0;
633 if ((int)(dc
->dcn_soc
->sr_enter_plus_exit_time
* 1000)
634 != dc
->debug
.sr_enter_plus_exit_time_ns
635 && dc
->debug
.sr_enter_plus_exit_time_ns
) {
637 dc
->dcn_soc
->sr_enter_plus_exit_time
=
638 dc
->debug
.sr_enter_plus_exit_time_ns
/ 1000.0;
641 if ((int)(dc
->dcn_soc
->urgent_latency
* 1000) != dc
->debug
.urgent_latency_ns
642 && dc
->debug
.urgent_latency_ns
) {
644 dc
->dcn_soc
->urgent_latency
= dc
->debug
.urgent_latency_ns
/ 1000.0;
647 if ((int)(dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
* 1000)
648 != dc
->debug
.percent_of_ideal_drambw
649 && dc
->debug
.percent_of_ideal_drambw
) {
651 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
=
652 dc
->debug
.percent_of_ideal_drambw
;
655 if ((int)(dc
->dcn_soc
->dram_clock_change_latency
* 1000)
656 != dc
->debug
.dram_clock_change_latency_ns
657 && dc
->debug
.dram_clock_change_latency_ns
) {
659 dc
->dcn_soc
->dram_clock_change_latency
=
660 dc
->debug
.dram_clock_change_latency_ns
/ 1000.0;
667 static void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars
*v
)
670 * disable optional pipe split by lower dispclk bounding box
673 v
->max_dispclk
[0] = v
->max_dppclk_vmin0p65
;
676 static void hack_force_pipe_split(struct dcn_bw_internal_vars
*v
,
677 unsigned int pixel_rate_100hz
)
679 float pixel_rate_mhz
= pixel_rate_100hz
/ 10000;
682 * force enabling pipe split by lower dpp clock for DPM0 to just
683 * below the specify pixel_rate, so bw calc would split pipe.
685 if (pixel_rate_mhz
< v
->max_dppclk
[0])
686 v
->max_dppclk
[0] = pixel_rate_mhz
;
689 static void hack_bounding_box(struct dcn_bw_internal_vars
*v
,
690 struct dc_debug_options
*dbg
,
691 struct dc_state
*context
)
693 if (dbg
->pipe_split_policy
== MPC_SPLIT_AVOID
)
694 hack_disable_optional_pipe_split(v
);
696 if (dbg
->pipe_split_policy
== MPC_SPLIT_AVOID_MULT_DISP
&&
697 context
->stream_count
>= 2)
698 hack_disable_optional_pipe_split(v
);
700 if (context
->stream_count
== 1 &&
701 dbg
->force_single_disp_pipe_split
)
702 hack_force_pipe_split(v
, context
->streams
[0]->timing
.pix_clk_100hz
);
706 unsigned int get_highest_allowed_voltage_level(uint32_t hw_internal_rev
)
708 /* for dali & pollock, the highest voltage level we want is 0 */
709 if (ASICREV_IS_POLLOCK(hw_internal_rev
) || ASICREV_IS_DALI(hw_internal_rev
))
712 /* we are ok with all levels */
716 bool dcn_validate_bandwidth(
718 struct dc_state
*context
,
722 * we want a breakdown of the various stages of validation, which the
723 * perf_trace macro doesn't support
725 BW_VAL_TRACE_SETUP();
727 const struct resource_pool
*pool
= dc
->res_pool
;
728 struct dcn_bw_internal_vars
*v
= &context
->dcn_bw_vars
;
730 int vesa_sync_start
, asic_blank_end
, asic_blank_start
;
734 PERFORMANCE_TRACE_START();
736 BW_VAL_TRACE_COUNT();
738 if (dcn_bw_apply_registry_override(dc
))
739 dcn_bw_sync_calcs_and_dml(dc
);
741 memset(v
, 0, sizeof(*v
));
744 v
->sr_exit_time
= dc
->dcn_soc
->sr_exit_time
;
745 v
->sr_enter_plus_exit_time
= dc
->dcn_soc
->sr_enter_plus_exit_time
;
746 v
->urgent_latency
= dc
->dcn_soc
->urgent_latency
;
747 v
->write_back_latency
= dc
->dcn_soc
->write_back_latency
;
748 v
->percent_of_ideal_drambw_received_after_urg_latency
=
749 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
;
751 v
->dcfclkv_min0p65
= dc
->dcn_soc
->dcfclkv_min0p65
;
752 v
->dcfclkv_mid0p72
= dc
->dcn_soc
->dcfclkv_mid0p72
;
753 v
->dcfclkv_nom0p8
= dc
->dcn_soc
->dcfclkv_nom0p8
;
754 v
->dcfclkv_max0p9
= dc
->dcn_soc
->dcfclkv_max0p9
;
756 v
->max_dispclk_vmin0p65
= dc
->dcn_soc
->max_dispclk_vmin0p65
;
757 v
->max_dispclk_vmid0p72
= dc
->dcn_soc
->max_dispclk_vmid0p72
;
758 v
->max_dispclk_vnom0p8
= dc
->dcn_soc
->max_dispclk_vnom0p8
;
759 v
->max_dispclk_vmax0p9
= dc
->dcn_soc
->max_dispclk_vmax0p9
;
761 v
->max_dppclk_vmin0p65
= dc
->dcn_soc
->max_dppclk_vmin0p65
;
762 v
->max_dppclk_vmid0p72
= dc
->dcn_soc
->max_dppclk_vmid0p72
;
763 v
->max_dppclk_vnom0p8
= dc
->dcn_soc
->max_dppclk_vnom0p8
;
764 v
->max_dppclk_vmax0p9
= dc
->dcn_soc
->max_dppclk_vmax0p9
;
766 v
->socclk
= dc
->dcn_soc
->socclk
;
768 v
->fabric_and_dram_bandwidth_vmin0p65
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
;
769 v
->fabric_and_dram_bandwidth_vmid0p72
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
;
770 v
->fabric_and_dram_bandwidth_vnom0p8
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
;
771 v
->fabric_and_dram_bandwidth_vmax0p9
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
;
773 v
->phyclkv_min0p65
= dc
->dcn_soc
->phyclkv_min0p65
;
774 v
->phyclkv_mid0p72
= dc
->dcn_soc
->phyclkv_mid0p72
;
775 v
->phyclkv_nom0p8
= dc
->dcn_soc
->phyclkv_nom0p8
;
776 v
->phyclkv_max0p9
= dc
->dcn_soc
->phyclkv_max0p9
;
778 v
->downspreading
= dc
->dcn_soc
->downspreading
;
779 v
->round_trip_ping_latency_cycles
= dc
->dcn_soc
->round_trip_ping_latency_cycles
;
780 v
->urgent_out_of_order_return_per_channel
= dc
->dcn_soc
->urgent_out_of_order_return_per_channel
;
781 v
->number_of_channels
= dc
->dcn_soc
->number_of_channels
;
782 v
->vmm_page_size
= dc
->dcn_soc
->vmm_page_size
;
783 v
->dram_clock_change_latency
= dc
->dcn_soc
->dram_clock_change_latency
;
784 v
->return_bus_width
= dc
->dcn_soc
->return_bus_width
;
786 v
->rob_buffer_size_in_kbyte
= dc
->dcn_ip
->rob_buffer_size_in_kbyte
;
787 v
->det_buffer_size_in_kbyte
= dc
->dcn_ip
->det_buffer_size_in_kbyte
;
788 v
->dpp_output_buffer_pixels
= dc
->dcn_ip
->dpp_output_buffer_pixels
;
789 v
->opp_output_buffer_lines
= dc
->dcn_ip
->opp_output_buffer_lines
;
790 v
->pixel_chunk_size_in_kbyte
= dc
->dcn_ip
->pixel_chunk_size_in_kbyte
;
791 v
->pte_enable
= dc
->dcn_ip
->pte_enable
;
792 v
->pte_chunk_size
= dc
->dcn_ip
->pte_chunk_size
;
793 v
->meta_chunk_size
= dc
->dcn_ip
->meta_chunk_size
;
794 v
->writeback_chunk_size
= dc
->dcn_ip
->writeback_chunk_size
;
795 v
->odm_capability
= dc
->dcn_ip
->odm_capability
;
796 v
->dsc_capability
= dc
->dcn_ip
->dsc_capability
;
797 v
->line_buffer_size
= dc
->dcn_ip
->line_buffer_size
;
798 v
->is_line_buffer_bpp_fixed
= dc
->dcn_ip
->is_line_buffer_bpp_fixed
;
799 v
->line_buffer_fixed_bpp
= dc
->dcn_ip
->line_buffer_fixed_bpp
;
800 v
->max_line_buffer_lines
= dc
->dcn_ip
->max_line_buffer_lines
;
801 v
->writeback_luma_buffer_size
= dc
->dcn_ip
->writeback_luma_buffer_size
;
802 v
->writeback_chroma_buffer_size
= dc
->dcn_ip
->writeback_chroma_buffer_size
;
803 v
->max_num_dpp
= dc
->dcn_ip
->max_num_dpp
;
804 v
->max_num_writeback
= dc
->dcn_ip
->max_num_writeback
;
805 v
->max_dchub_topscl_throughput
= dc
->dcn_ip
->max_dchub_topscl_throughput
;
806 v
->max_pscl_tolb_throughput
= dc
->dcn_ip
->max_pscl_tolb_throughput
;
807 v
->max_lb_tovscl_throughput
= dc
->dcn_ip
->max_lb_tovscl_throughput
;
808 v
->max_vscl_tohscl_throughput
= dc
->dcn_ip
->max_vscl_tohscl_throughput
;
809 v
->max_hscl_ratio
= dc
->dcn_ip
->max_hscl_ratio
;
810 v
->max_vscl_ratio
= dc
->dcn_ip
->max_vscl_ratio
;
811 v
->max_hscl_taps
= dc
->dcn_ip
->max_hscl_taps
;
812 v
->max_vscl_taps
= dc
->dcn_ip
->max_vscl_taps
;
813 v
->under_scan_factor
= dc
->dcn_ip
->under_scan_factor
;
814 v
->pte_buffer_size_in_requests
= dc
->dcn_ip
->pte_buffer_size_in_requests
;
815 v
->dispclk_ramping_margin
= dc
->dcn_ip
->dispclk_ramping_margin
;
816 v
->max_inter_dcn_tile_repeaters
= dc
->dcn_ip
->max_inter_dcn_tile_repeaters
;
817 v
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
=
818 dc
->dcn_ip
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
;
819 v
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
=
820 dc
->dcn_ip
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
;
822 v
->voltage
[5] = dcn_bw_no_support
;
823 v
->voltage
[4] = dcn_bw_v_max0p9
;
824 v
->voltage
[3] = dcn_bw_v_max0p9
;
825 v
->voltage
[2] = dcn_bw_v_nom0p8
;
826 v
->voltage
[1] = dcn_bw_v_mid0p72
;
827 v
->voltage
[0] = dcn_bw_v_min0p65
;
828 v
->fabric_and_dram_bandwidth_per_state
[5] = v
->fabric_and_dram_bandwidth_vmax0p9
;
829 v
->fabric_and_dram_bandwidth_per_state
[4] = v
->fabric_and_dram_bandwidth_vmax0p9
;
830 v
->fabric_and_dram_bandwidth_per_state
[3] = v
->fabric_and_dram_bandwidth_vmax0p9
;
831 v
->fabric_and_dram_bandwidth_per_state
[2] = v
->fabric_and_dram_bandwidth_vnom0p8
;
832 v
->fabric_and_dram_bandwidth_per_state
[1] = v
->fabric_and_dram_bandwidth_vmid0p72
;
833 v
->fabric_and_dram_bandwidth_per_state
[0] = v
->fabric_and_dram_bandwidth_vmin0p65
;
834 v
->dcfclk_per_state
[5] = v
->dcfclkv_max0p9
;
835 v
->dcfclk_per_state
[4] = v
->dcfclkv_max0p9
;
836 v
->dcfclk_per_state
[3] = v
->dcfclkv_max0p9
;
837 v
->dcfclk_per_state
[2] = v
->dcfclkv_nom0p8
;
838 v
->dcfclk_per_state
[1] = v
->dcfclkv_mid0p72
;
839 v
->dcfclk_per_state
[0] = v
->dcfclkv_min0p65
;
840 v
->max_dispclk
[5] = v
->max_dispclk_vmax0p9
;
841 v
->max_dispclk
[4] = v
->max_dispclk_vmax0p9
;
842 v
->max_dispclk
[3] = v
->max_dispclk_vmax0p9
;
843 v
->max_dispclk
[2] = v
->max_dispclk_vnom0p8
;
844 v
->max_dispclk
[1] = v
->max_dispclk_vmid0p72
;
845 v
->max_dispclk
[0] = v
->max_dispclk_vmin0p65
;
846 v
->max_dppclk
[5] = v
->max_dppclk_vmax0p9
;
847 v
->max_dppclk
[4] = v
->max_dppclk_vmax0p9
;
848 v
->max_dppclk
[3] = v
->max_dppclk_vmax0p9
;
849 v
->max_dppclk
[2] = v
->max_dppclk_vnom0p8
;
850 v
->max_dppclk
[1] = v
->max_dppclk_vmid0p72
;
851 v
->max_dppclk
[0] = v
->max_dppclk_vmin0p65
;
852 v
->phyclk_per_state
[5] = v
->phyclkv_max0p9
;
853 v
->phyclk_per_state
[4] = v
->phyclkv_max0p9
;
854 v
->phyclk_per_state
[3] = v
->phyclkv_max0p9
;
855 v
->phyclk_per_state
[2] = v
->phyclkv_nom0p8
;
856 v
->phyclk_per_state
[1] = v
->phyclkv_mid0p72
;
857 v
->phyclk_per_state
[0] = v
->phyclkv_min0p65
;
858 v
->synchronized_vblank
= dcn_bw_no
;
859 v
->ta_pscalculation
= dcn_bw_override
;
860 v
->allow_different_hratio_vratio
= dcn_bw_yes
;
862 for (i
= 0, input_idx
= 0; i
< pool
->pipe_count
; i
++) {
863 struct pipe_ctx
*pipe
= &context
->res_ctx
.pipe_ctx
[i
];
867 /* skip all but first of split pipes */
868 if (pipe
->top_pipe
&& pipe
->top_pipe
->plane_state
== pipe
->plane_state
)
871 v
->underscan_output
[input_idx
] = false; /* taken care of in recout already*/
872 v
->interlace_output
[input_idx
] = false;
874 v
->htotal
[input_idx
] = pipe
->stream
->timing
.h_total
;
875 v
->vtotal
[input_idx
] = pipe
->stream
->timing
.v_total
;
876 v
->vactive
[input_idx
] = pipe
->stream
->timing
.v_addressable
+
877 pipe
->stream
->timing
.v_border_top
+ pipe
->stream
->timing
.v_border_bottom
;
878 v
->v_sync_plus_back_porch
[input_idx
] = pipe
->stream
->timing
.v_total
879 - v
->vactive
[input_idx
]
880 - pipe
->stream
->timing
.v_front_porch
;
881 v
->pixel_clock
[input_idx
] = pipe
->stream
->timing
.pix_clk_100hz
/10000.0;
882 if (pipe
->stream
->timing
.timing_3d_format
== TIMING_3D_FORMAT_HW_FRAME_PACKING
)
883 v
->pixel_clock
[input_idx
] *= 2;
884 if (!pipe
->plane_state
) {
885 v
->dcc_enable
[input_idx
] = dcn_bw_yes
;
886 v
->source_pixel_format
[input_idx
] = dcn_bw_rgb_sub_32
;
887 v
->source_surface_mode
[input_idx
] = dcn_bw_sw_4_kb_s
;
888 v
->lb_bit_per_pixel
[input_idx
] = 30;
889 v
->viewport_width
[input_idx
] = pipe
->stream
->timing
.h_addressable
;
890 v
->viewport_height
[input_idx
] = pipe
->stream
->timing
.v_addressable
;
892 * for cases where we have no plane, we want to validate up to 1080p
893 * source size because here we are only interested in if the output
894 * timing is supported or not. if we cannot support native resolution
895 * of the high res display, we still want to support lower res up scale
898 if (v
->viewport_width
[input_idx
] > 1920)
899 v
->viewport_width
[input_idx
] = 1920;
900 if (v
->viewport_height
[input_idx
] > 1080)
901 v
->viewport_height
[input_idx
] = 1080;
902 v
->scaler_rec_out_width
[input_idx
] = v
->viewport_width
[input_idx
];
903 v
->scaler_recout_height
[input_idx
] = v
->viewport_height
[input_idx
];
904 v
->override_hta_ps
[input_idx
] = 1;
905 v
->override_vta_ps
[input_idx
] = 1;
906 v
->override_hta_pschroma
[input_idx
] = 1;
907 v
->override_vta_pschroma
[input_idx
] = 1;
908 v
->source_scan
[input_idx
] = dcn_bw_hor
;
911 v
->viewport_height
[input_idx
] = pipe
->plane_res
.scl_data
.viewport
.height
;
912 v
->viewport_width
[input_idx
] = pipe
->plane_res
.scl_data
.viewport
.width
;
913 v
->scaler_rec_out_width
[input_idx
] = pipe
->plane_res
.scl_data
.recout
.width
;
914 v
->scaler_recout_height
[input_idx
] = pipe
->plane_res
.scl_data
.recout
.height
;
915 if (pipe
->bottom_pipe
&& pipe
->bottom_pipe
->plane_state
== pipe
->plane_state
) {
916 if (pipe
->plane_state
->rotation
% 2 == 0) {
917 int viewport_end
= pipe
->plane_res
.scl_data
.viewport
.width
918 + pipe
->plane_res
.scl_data
.viewport
.x
;
919 int viewport_b_end
= pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.width
920 + pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.x
;
922 if (viewport_end
> viewport_b_end
)
923 v
->viewport_width
[input_idx
] = viewport_end
924 - pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.x
;
926 v
->viewport_width
[input_idx
] = viewport_b_end
927 - pipe
->plane_res
.scl_data
.viewport
.x
;
929 int viewport_end
= pipe
->plane_res
.scl_data
.viewport
.height
930 + pipe
->plane_res
.scl_data
.viewport
.y
;
931 int viewport_b_end
= pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.height
932 + pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.y
;
934 if (viewport_end
> viewport_b_end
)
935 v
->viewport_height
[input_idx
] = viewport_end
936 - pipe
->bottom_pipe
->plane_res
.scl_data
.viewport
.y
;
938 v
->viewport_height
[input_idx
] = viewport_b_end
939 - pipe
->plane_res
.scl_data
.viewport
.y
;
941 v
->scaler_rec_out_width
[input_idx
] = pipe
->plane_res
.scl_data
.recout
.width
942 + pipe
->bottom_pipe
->plane_res
.scl_data
.recout
.width
;
945 if (pipe
->plane_state
->rotation
% 2 == 0) {
946 ASSERT(pipe
->plane_res
.scl_data
.ratios
.horz
.value
!= dc_fixpt_one
.value
947 || v
->scaler_rec_out_width
[input_idx
] == v
->viewport_width
[input_idx
]);
948 ASSERT(pipe
->plane_res
.scl_data
.ratios
.vert
.value
!= dc_fixpt_one
.value
949 || v
->scaler_recout_height
[input_idx
] == v
->viewport_height
[input_idx
]);
951 ASSERT(pipe
->plane_res
.scl_data
.ratios
.horz
.value
!= dc_fixpt_one
.value
952 || v
->scaler_recout_height
[input_idx
] == v
->viewport_width
[input_idx
]);
953 ASSERT(pipe
->plane_res
.scl_data
.ratios
.vert
.value
!= dc_fixpt_one
.value
954 || v
->scaler_rec_out_width
[input_idx
] == v
->viewport_height
[input_idx
]);
957 if (dc
->debug
.optimized_watermark
) {
959 * this method requires us to always re-calculate watermark when dcc change
962 v
->dcc_enable
[input_idx
] = pipe
->plane_state
->dcc
.enable
? dcn_bw_yes
: dcn_bw_no
;
965 * allow us to disable dcc on the fly without re-calculating WM
967 * extra overhead for DCC is quite small. for 1080p WM without
968 * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us)
972 v
->dcc_enable
[input_idx
] = dc
->res_pool
->hubbub
->funcs
->dcc_support_pixel_format(
973 pipe
->plane_state
->format
, &bpe
) ? dcn_bw_yes
: dcn_bw_no
;
976 v
->source_pixel_format
[input_idx
] = tl_pixel_format_to_bw_defs(
977 pipe
->plane_state
->format
);
978 v
->source_surface_mode
[input_idx
] = tl_sw_mode_to_bw_defs(
979 pipe
->plane_state
->tiling_info
.gfx9
.swizzle
);
980 v
->lb_bit_per_pixel
[input_idx
] = tl_lb_bpp_to_int(pipe
->plane_res
.scl_data
.lb_params
.depth
);
981 v
->override_hta_ps
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.h_taps
;
982 v
->override_vta_ps
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.v_taps
;
983 v
->override_hta_pschroma
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.h_taps_c
;
984 v
->override_vta_pschroma
[input_idx
] = pipe
->plane_res
.scl_data
.taps
.v_taps_c
;
986 * Spreadsheet doesn't handle taps_c is one properly,
987 * need to force Chroma to always be scaled to pass
988 * bandwidth validation.
990 if (v
->override_hta_pschroma
[input_idx
] == 1)
991 v
->override_hta_pschroma
[input_idx
] = 2;
992 if (v
->override_vta_pschroma
[input_idx
] == 1)
993 v
->override_vta_pschroma
[input_idx
] = 2;
994 v
->source_scan
[input_idx
] = (pipe
->plane_state
->rotation
% 2) ? dcn_bw_vert
: dcn_bw_hor
;
996 if (v
->is_line_buffer_bpp_fixed
== dcn_bw_yes
)
997 v
->lb_bit_per_pixel
[input_idx
] = v
->line_buffer_fixed_bpp
;
998 v
->dcc_rate
[input_idx
] = 1; /*TODO: Worst case? does this change?*/
999 v
->output_format
[input_idx
] = pipe
->stream
->timing
.pixel_encoding
==
1000 PIXEL_ENCODING_YCBCR420
? dcn_bw_420
: dcn_bw_444
;
1001 v
->output
[input_idx
] = pipe
->stream
->signal
==
1002 SIGNAL_TYPE_HDMI_TYPE_A
? dcn_bw_hdmi
: dcn_bw_dp
;
1003 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_8bpc
;
1004 if (v
->output
[input_idx
] == dcn_bw_hdmi
) {
1005 switch (pipe
->stream
->timing
.display_color_depth
) {
1006 case COLOR_DEPTH_101010
:
1007 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_10bpc
;
1009 case COLOR_DEPTH_121212
:
1010 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_12bpc
;
1012 case COLOR_DEPTH_161616
:
1013 v
->output_deep_color
[input_idx
] = dcn_bw_encoder_16bpc
;
1022 v
->number_of_active_planes
= input_idx
;
1024 scaler_settings_calculation(v
);
1026 hack_bounding_box(v
, &dc
->debug
, context
);
1028 mode_support_and_system_configuration(v
);
1030 /* Unhack dppclk: dont bother with trying to pipe split if we cannot maintain dpm0 */
1031 if (v
->voltage_level
!= 0
1032 && context
->stream_count
== 1
1033 && dc
->debug
.force_single_disp_pipe_split
) {
1034 v
->max_dppclk
[0] = v
->max_dppclk_vmin0p65
;
1035 mode_support_and_system_configuration(v
);
1038 if (v
->voltage_level
== 0 &&
1039 (dc
->debug
.sr_exit_time_dpm0_ns
1040 || dc
->debug
.sr_enter_plus_exit_time_dpm0_ns
)) {
1042 if (dc
->debug
.sr_enter_plus_exit_time_dpm0_ns
)
1043 v
->sr_enter_plus_exit_time
=
1044 dc
->debug
.sr_enter_plus_exit_time_dpm0_ns
/ 1000.0f
;
1045 if (dc
->debug
.sr_exit_time_dpm0_ns
)
1046 v
->sr_exit_time
= dc
->debug
.sr_exit_time_dpm0_ns
/ 1000.0f
;
1047 context
->bw_ctx
.dml
.soc
.sr_enter_plus_exit_time_us
= v
->sr_enter_plus_exit_time
;
1048 context
->bw_ctx
.dml
.soc
.sr_exit_time_us
= v
->sr_exit_time
;
1049 mode_support_and_system_configuration(v
);
1052 display_pipe_configuration(v
);
1054 for (k
= 0; k
<= v
->number_of_active_planes
- 1; k
++) {
1055 if (v
->source_scan
[k
] == dcn_bw_hor
)
1056 v
->swath_width_y
[k
] = v
->viewport_width
[k
] / v
->dpp_per_plane
[k
];
1058 v
->swath_width_y
[k
] = v
->viewport_height
[k
] / v
->dpp_per_plane
[k
];
1060 for (k
= 0; k
<= v
->number_of_active_planes
- 1; k
++) {
1061 if (v
->source_pixel_format
[k
] == dcn_bw_rgb_sub_64
) {
1062 v
->byte_per_pixel_dety
[k
] = 8.0;
1063 v
->byte_per_pixel_detc
[k
] = 0.0;
1064 } else if (v
->source_pixel_format
[k
] == dcn_bw_rgb_sub_32
) {
1065 v
->byte_per_pixel_dety
[k
] = 4.0;
1066 v
->byte_per_pixel_detc
[k
] = 0.0;
1067 } else if (v
->source_pixel_format
[k
] == dcn_bw_rgb_sub_16
) {
1068 v
->byte_per_pixel_dety
[k
] = 2.0;
1069 v
->byte_per_pixel_detc
[k
] = 0.0;
1070 } else if (v
->source_pixel_format
[k
] == dcn_bw_yuv420_sub_8
) {
1071 v
->byte_per_pixel_dety
[k
] = 1.0;
1072 v
->byte_per_pixel_detc
[k
] = 2.0;
1074 v
->byte_per_pixel_dety
[k
] = 4.0f
/ 3.0f
;
1075 v
->byte_per_pixel_detc
[k
] = 8.0f
/ 3.0f
;
1079 v
->total_data_read_bandwidth
= 0.0;
1080 for (k
= 0; k
<= v
->number_of_active_planes
- 1; k
++) {
1081 v
->read_bandwidth_plane_luma
[k
] = v
->swath_width_y
[k
] * v
->dpp_per_plane
[k
] *
1082 dcn_bw_ceil2(v
->byte_per_pixel_dety
[k
], 1.0) / (v
->htotal
[k
] / v
->pixel_clock
[k
]) * v
->v_ratio
[k
];
1083 v
->read_bandwidth_plane_chroma
[k
] = v
->swath_width_y
[k
] / 2.0 * v
->dpp_per_plane
[k
] *
1084 dcn_bw_ceil2(v
->byte_per_pixel_detc
[k
], 2.0) / (v
->htotal
[k
] / v
->pixel_clock
[k
]) * v
->v_ratio
[k
] / 2.0;
1085 v
->total_data_read_bandwidth
= v
->total_data_read_bandwidth
+
1086 v
->read_bandwidth_plane_luma
[k
] + v
->read_bandwidth_plane_chroma
[k
];
1089 BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1091 if (v
->voltage_level
!= number_of_states_plus_one
&& !fast_validate
) {
1092 float bw_consumed
= v
->total_bandwidth_consumed_gbyte_per_second
;
1094 if (bw_consumed
< v
->fabric_and_dram_bandwidth_vmin0p65
)
1095 bw_consumed
= v
->fabric_and_dram_bandwidth_vmin0p65
;
1096 else if (bw_consumed
< v
->fabric_and_dram_bandwidth_vmid0p72
)
1097 bw_consumed
= v
->fabric_and_dram_bandwidth_vmid0p72
;
1098 else if (bw_consumed
< v
->fabric_and_dram_bandwidth_vnom0p8
)
1099 bw_consumed
= v
->fabric_and_dram_bandwidth_vnom0p8
;
1101 bw_consumed
= v
->fabric_and_dram_bandwidth_vmax0p9
;
1103 if (bw_consumed
< v
->fabric_and_dram_bandwidth
)
1104 if (dc
->debug
.voltage_align_fclk
)
1105 bw_consumed
= v
->fabric_and_dram_bandwidth
;
1107 display_pipe_configuration(v
);
1108 /*calc_wm_sets_and_perf_params(context, v);*/
1109 /* Only 1 set is used by dcn since no noticeable
1110 * performance improvement was measured and due to hw bug DEGVIDCN10-254
1112 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v
);
1114 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_exit_ns
=
1115 v
->stutter_exit_watermark
* 1000;
1116 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.cstate_enter_plus_exit_ns
=
1117 v
->stutter_enter_plus_exit_watermark
* 1000;
1118 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.cstate_pstate
.pstate_change_ns
=
1119 v
->dram_clock_change_watermark
* 1000;
1120 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.pte_meta_urgent_ns
= v
->ptemeta_urgent_watermark
* 1000;
1121 context
->bw_ctx
.bw
.dcn
.watermarks
.a
.urgent_ns
= v
->urgent_watermark
* 1000;
1122 context
->bw_ctx
.bw
.dcn
.watermarks
.b
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
1123 context
->bw_ctx
.bw
.dcn
.watermarks
.c
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
1124 context
->bw_ctx
.bw
.dcn
.watermarks
.d
= context
->bw_ctx
.bw
.dcn
.watermarks
.a
;
1126 context
->bw_ctx
.bw
.dcn
.clk
.fclk_khz
= (int)(bw_consumed
* 1000000 /
1127 (ddr4_dram_factor_single_Channel
* v
->number_of_channels
));
1128 if (bw_consumed
== v
->fabric_and_dram_bandwidth_vmin0p65
)
1129 context
->bw_ctx
.bw
.dcn
.clk
.fclk_khz
= (int)(bw_consumed
* 1000000 / 32);
1131 context
->bw_ctx
.bw
.dcn
.clk
.dcfclk_deep_sleep_khz
= (int)(v
->dcf_clk_deep_sleep
* 1000);
1132 context
->bw_ctx
.bw
.dcn
.clk
.dcfclk_khz
= (int)(v
->dcfclk
* 1000);
1134 context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
= (int)(v
->dispclk
* 1000);
1135 if (dc
->debug
.max_disp_clk
== true)
1136 context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
= (int)(dc
->dcn_soc
->max_dispclk_vmax0p9
* 1000);
1138 if (context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
<
1139 dc
->debug
.min_disp_clk_khz
) {
1140 context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
=
1141 dc
->debug
.min_disp_clk_khz
;
1144 context
->bw_ctx
.bw
.dcn
.clk
.dppclk_khz
= context
->bw_ctx
.bw
.dcn
.clk
.dispclk_khz
/
1145 v
->dispclk_dppclk_ratio
;
1146 context
->bw_ctx
.bw
.dcn
.clk
.phyclk_khz
= v
->phyclk_per_state
[v
->voltage_level
];
1147 switch (v
->voltage_level
) {
1149 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1150 (int)(dc
->dcn_soc
->max_dppclk_vmin0p65
* 1000);
1153 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1154 (int)(dc
->dcn_soc
->max_dppclk_vmid0p72
* 1000);
1157 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1158 (int)(dc
->dcn_soc
->max_dppclk_vnom0p8
* 1000);
1161 context
->bw_ctx
.bw
.dcn
.clk
.max_supported_dppclk_khz
=
1162 (int)(dc
->dcn_soc
->max_dppclk_vmax0p9
* 1000);
1166 BW_VAL_TRACE_END_WATERMARKS();
1168 for (i
= 0, input_idx
= 0; i
< pool
->pipe_count
; i
++) {
1169 struct pipe_ctx
*pipe
= &context
->res_ctx
.pipe_ctx
[i
];
1171 /* skip inactive pipe */
1174 /* skip all but first of split pipes */
1175 if (pipe
->top_pipe
&& pipe
->top_pipe
->plane_state
== pipe
->plane_state
)
1178 pipe
->pipe_dlg_param
.vupdate_width
= v
->v_update_width_pix
[input_idx
];
1179 pipe
->pipe_dlg_param
.vupdate_offset
= v
->v_update_offset_pix
[input_idx
];
1180 pipe
->pipe_dlg_param
.vready_offset
= v
->v_ready_offset_pix
[input_idx
];
1181 pipe
->pipe_dlg_param
.vstartup_start
= v
->v_startup
[input_idx
];
1183 pipe
->pipe_dlg_param
.htotal
= pipe
->stream
->timing
.h_total
;
1184 pipe
->pipe_dlg_param
.vtotal
= pipe
->stream
->timing
.v_total
;
1185 vesa_sync_start
= pipe
->stream
->timing
.v_addressable
+
1186 pipe
->stream
->timing
.v_border_bottom
+
1187 pipe
->stream
->timing
.v_front_porch
;
1189 asic_blank_end
= (pipe
->stream
->timing
.v_total
-
1191 pipe
->stream
->timing
.v_border_top
)
1192 * (pipe
->stream
->timing
.flags
.INTERLACE
? 1 : 0);
1194 asic_blank_start
= asic_blank_end
+
1195 (pipe
->stream
->timing
.v_border_top
+
1196 pipe
->stream
->timing
.v_addressable
+
1197 pipe
->stream
->timing
.v_border_bottom
)
1198 * (pipe
->stream
->timing
.flags
.INTERLACE
? 1 : 0);
1200 pipe
->pipe_dlg_param
.vblank_start
= asic_blank_start
;
1201 pipe
->pipe_dlg_param
.vblank_end
= asic_blank_end
;
1203 if (pipe
->plane_state
) {
1204 struct pipe_ctx
*hsplit_pipe
= pipe
->bottom_pipe
;
1206 pipe
->plane_state
->update_flags
.bits
.full_update
= 1;
1208 if (v
->dpp_per_plane
[input_idx
] == 2 ||
1209 ((pipe
->stream
->view_format
==
1210 VIEW_3D_FORMAT_SIDE_BY_SIDE
||
1211 pipe
->stream
->view_format
==
1212 VIEW_3D_FORMAT_TOP_AND_BOTTOM
) &&
1213 (pipe
->stream
->timing
.timing_3d_format
==
1214 TIMING_3D_FORMAT_TOP_AND_BOTTOM
||
1215 pipe
->stream
->timing
.timing_3d_format
==
1216 TIMING_3D_FORMAT_SIDE_BY_SIDE
))) {
1217 if (hsplit_pipe
&& hsplit_pipe
->plane_state
== pipe
->plane_state
) {
1218 /* update previously split pipe */
1219 hsplit_pipe
->pipe_dlg_param
.vupdate_width
= v
->v_update_width_pix
[input_idx
];
1220 hsplit_pipe
->pipe_dlg_param
.vupdate_offset
= v
->v_update_offset_pix
[input_idx
];
1221 hsplit_pipe
->pipe_dlg_param
.vready_offset
= v
->v_ready_offset_pix
[input_idx
];
1222 hsplit_pipe
->pipe_dlg_param
.vstartup_start
= v
->v_startup
[input_idx
];
1224 hsplit_pipe
->pipe_dlg_param
.htotal
= pipe
->stream
->timing
.h_total
;
1225 hsplit_pipe
->pipe_dlg_param
.vtotal
= pipe
->stream
->timing
.v_total
;
1226 hsplit_pipe
->pipe_dlg_param
.vblank_start
= pipe
->pipe_dlg_param
.vblank_start
;
1227 hsplit_pipe
->pipe_dlg_param
.vblank_end
= pipe
->pipe_dlg_param
.vblank_end
;
1229 /* pipe not split previously needs split */
1230 hsplit_pipe
= find_idle_secondary_pipe(&context
->res_ctx
, pool
, pipe
);
1231 ASSERT(hsplit_pipe
);
1232 split_stream_across_pipes(&context
->res_ctx
, pool
, pipe
, hsplit_pipe
);
1235 dcn_bw_calc_rq_dlg_ttu(dc
, v
, hsplit_pipe
, input_idx
);
1236 } else if (hsplit_pipe
&& hsplit_pipe
->plane_state
== pipe
->plane_state
) {
1237 /* merge previously split pipe */
1238 pipe
->bottom_pipe
= hsplit_pipe
->bottom_pipe
;
1239 if (hsplit_pipe
->bottom_pipe
)
1240 hsplit_pipe
->bottom_pipe
->top_pipe
= pipe
;
1241 hsplit_pipe
->plane_state
= NULL
;
1242 hsplit_pipe
->stream
= NULL
;
1243 hsplit_pipe
->top_pipe
= NULL
;
1244 hsplit_pipe
->bottom_pipe
= NULL
;
1245 /* Clear plane_res and stream_res */
1246 memset(&hsplit_pipe
->plane_res
, 0, sizeof(hsplit_pipe
->plane_res
));
1247 memset(&hsplit_pipe
->stream_res
, 0, sizeof(hsplit_pipe
->stream_res
));
1248 resource_build_scaling_params(pipe
);
1250 /* for now important to do this after pipe split for building e2e params */
1251 dcn_bw_calc_rq_dlg_ttu(dc
, v
, pipe
, input_idx
);
1256 } else if (v
->voltage_level
== number_of_states_plus_one
) {
1257 BW_VAL_TRACE_SKIP(fail
);
1258 } else if (fast_validate
) {
1259 BW_VAL_TRACE_SKIP(fast
);
1262 if (v
->voltage_level
== 0) {
1263 context
->bw_ctx
.dml
.soc
.sr_enter_plus_exit_time_us
=
1264 dc
->dcn_soc
->sr_enter_plus_exit_time
;
1265 context
->bw_ctx
.dml
.soc
.sr_exit_time_us
= dc
->dcn_soc
->sr_exit_time
;
1269 * BW limit is set to prevent display from impacting other system functions
1272 bw_limit
= dc
->dcn_soc
->percent_disp_bw_limit
* v
->fabric_and_dram_bandwidth_vmax0p9
;
1273 bw_limit_pass
= (v
->total_data_read_bandwidth
/ 1000.0) < bw_limit
;
1277 PERFORMANCE_TRACE_END();
1278 BW_VAL_TRACE_FINISH();
1280 if (bw_limit_pass
&& v
->voltage_level
<= get_highest_allowed_voltage_level(dc
->ctx
->asic_id
.hw_internal_rev
))
1286 static unsigned int dcn_find_normalized_clock_vdd_Level(
1287 const struct dc
*dc
,
1288 enum dm_pp_clock_type clocks_type
,
1291 int vdd_level
= dcn_bw_v_min0p65
;
1293 if (clocks_in_khz
== 0)/*todo some clock not in the considerations*/
1296 switch (clocks_type
) {
1297 case DM_PP_CLOCK_TYPE_DISPLAY_CLK
:
1298 if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vmax0p9
*1000) {
1299 vdd_level
= dcn_bw_v_max0p91
;
1300 BREAK_TO_DEBUGGER();
1301 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vnom0p8
*1000) {
1302 vdd_level
= dcn_bw_v_max0p9
;
1303 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vmid0p72
*1000) {
1304 vdd_level
= dcn_bw_v_nom0p8
;
1305 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dispclk_vmin0p65
*1000) {
1306 vdd_level
= dcn_bw_v_mid0p72
;
1308 vdd_level
= dcn_bw_v_min0p65
;
1310 case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK
:
1311 if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_max0p9
*1000) {
1312 vdd_level
= dcn_bw_v_max0p91
;
1313 BREAK_TO_DEBUGGER();
1314 } else if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_nom0p8
*1000) {
1315 vdd_level
= dcn_bw_v_max0p9
;
1316 } else if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_mid0p72
*1000) {
1317 vdd_level
= dcn_bw_v_nom0p8
;
1318 } else if (clocks_in_khz
> dc
->dcn_soc
->phyclkv_min0p65
*1000) {
1319 vdd_level
= dcn_bw_v_mid0p72
;
1321 vdd_level
= dcn_bw_v_min0p65
;
1324 case DM_PP_CLOCK_TYPE_DPPCLK
:
1325 if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vmax0p9
*1000) {
1326 vdd_level
= dcn_bw_v_max0p91
;
1327 BREAK_TO_DEBUGGER();
1328 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vnom0p8
*1000) {
1329 vdd_level
= dcn_bw_v_max0p9
;
1330 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vmid0p72
*1000) {
1331 vdd_level
= dcn_bw_v_nom0p8
;
1332 } else if (clocks_in_khz
> dc
->dcn_soc
->max_dppclk_vmin0p65
*1000) {
1333 vdd_level
= dcn_bw_v_mid0p72
;
1335 vdd_level
= dcn_bw_v_min0p65
;
1338 case DM_PP_CLOCK_TYPE_MEMORY_CLK
:
1340 unsigned factor
= (ddr4_dram_factor_single_Channel
* dc
->dcn_soc
->number_of_channels
);
1342 if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
*1000000/factor
) {
1343 vdd_level
= dcn_bw_v_max0p91
;
1344 BREAK_TO_DEBUGGER();
1345 } else if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
*1000000/factor
) {
1346 vdd_level
= dcn_bw_v_max0p9
;
1347 } else if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
*1000000/factor
) {
1348 vdd_level
= dcn_bw_v_nom0p8
;
1349 } else if (clocks_in_khz
> dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
*1000000/factor
) {
1350 vdd_level
= dcn_bw_v_mid0p72
;
1352 vdd_level
= dcn_bw_v_min0p65
;
1356 case DM_PP_CLOCK_TYPE_DCFCLK
:
1357 if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_max0p9
*1000) {
1358 vdd_level
= dcn_bw_v_max0p91
;
1359 BREAK_TO_DEBUGGER();
1360 } else if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_nom0p8
*1000) {
1361 vdd_level
= dcn_bw_v_max0p9
;
1362 } else if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_mid0p72
*1000) {
1363 vdd_level
= dcn_bw_v_nom0p8
;
1364 } else if (clocks_in_khz
> dc
->dcn_soc
->dcfclkv_min0p65
*1000) {
1365 vdd_level
= dcn_bw_v_mid0p72
;
1367 vdd_level
= dcn_bw_v_min0p65
;
1376 unsigned int dcn_find_dcfclk_suits_all(
1377 const struct dc
*dc
,
1378 struct dc_clocks
*clocks
)
1380 unsigned vdd_level
, vdd_level_temp
;
1383 /*find a common supported voltage level*/
1384 vdd_level
= dcn_find_normalized_clock_vdd_Level(
1385 dc
, DM_PP_CLOCK_TYPE_DISPLAY_CLK
, clocks
->dispclk_khz
);
1386 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1387 dc
, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK
, clocks
->phyclk_khz
);
1389 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1390 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1391 dc
, DM_PP_CLOCK_TYPE_DPPCLK
, clocks
->dppclk_khz
);
1392 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1394 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1395 dc
, DM_PP_CLOCK_TYPE_MEMORY_CLK
, clocks
->fclk_khz
);
1396 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1397 vdd_level_temp
= dcn_find_normalized_clock_vdd_Level(
1398 dc
, DM_PP_CLOCK_TYPE_DCFCLK
, clocks
->dcfclk_khz
);
1400 /*find that level conresponding dcfclk*/
1401 vdd_level
= dcn_bw_max(vdd_level
, vdd_level_temp
);
1402 if (vdd_level
== dcn_bw_v_max0p91
) {
1403 BREAK_TO_DEBUGGER();
1404 dcf_clk
= dc
->dcn_soc
->dcfclkv_max0p9
*1000;
1405 } else if (vdd_level
== dcn_bw_v_max0p9
)
1406 dcf_clk
= dc
->dcn_soc
->dcfclkv_max0p9
*1000;
1407 else if (vdd_level
== dcn_bw_v_nom0p8
)
1408 dcf_clk
= dc
->dcn_soc
->dcfclkv_nom0p8
*1000;
1409 else if (vdd_level
== dcn_bw_v_mid0p72
)
1410 dcf_clk
= dc
->dcn_soc
->dcfclkv_mid0p72
*1000;
1412 dcf_clk
= dc
->dcn_soc
->dcfclkv_min0p65
*1000;
1414 DC_LOG_BANDWIDTH_CALCS("\tdcf_clk for voltage = %d\n", dcf_clk
);
1418 static bool verify_clock_values(struct dm_pp_clock_levels_with_voltage
*clks
)
1422 if (clks
->num_levels
== 0)
1425 for (i
= 0; i
< clks
->num_levels
; i
++)
1426 /* Ensure that the result is sane */
1427 if (clks
->data
[i
].clocks_in_khz
== 0)
1433 void dcn_bw_update_from_pplib(struct dc
*dc
)
1435 struct dc_context
*ctx
= dc
->ctx
;
1436 struct dm_pp_clock_levels_with_voltage fclks
= {0}, dcfclks
= {0};
1439 /* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
1440 res
= dm_pp_get_clock_levels_by_type_with_voltage(
1441 ctx
, DM_PP_CLOCK_TYPE_FCLK
, &fclks
);
1446 res
= verify_clock_values(&fclks
);
1449 ASSERT(fclks
.num_levels
>= 3);
1450 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
= 32 * (fclks
.data
[0].clocks_in_khz
/ 1000.0) / 1000.0;
1451 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
= dc
->dcn_soc
->number_of_channels
*
1452 (fclks
.data
[fclks
.num_levels
- (fclks
.num_levels
> 2 ? 3 : 2)].clocks_in_khz
/ 1000.0)
1453 * ddr4_dram_factor_single_Channel
/ 1000.0;
1454 dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
= dc
->dcn_soc
->number_of_channels
*
1455 (fclks
.data
[fclks
.num_levels
- 2].clocks_in_khz
/ 1000.0)
1456 * ddr4_dram_factor_single_Channel
/ 1000.0;
1457 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= dc
->dcn_soc
->number_of_channels
*
1458 (fclks
.data
[fclks
.num_levels
- 1].clocks_in_khz
/ 1000.0)
1459 * ddr4_dram_factor_single_Channel
/ 1000.0;
1461 BREAK_TO_DEBUGGER();
1465 res
= dm_pp_get_clock_levels_by_type_with_voltage(
1466 ctx
, DM_PP_CLOCK_TYPE_DCFCLK
, &dcfclks
);
1471 res
= verify_clock_values(&dcfclks
);
1473 if (res
&& dcfclks
.num_levels
>= 3) {
1474 dc
->dcn_soc
->dcfclkv_min0p65
= dcfclks
.data
[0].clocks_in_khz
/ 1000.0;
1475 dc
->dcn_soc
->dcfclkv_mid0p72
= dcfclks
.data
[dcfclks
.num_levels
- 3].clocks_in_khz
/ 1000.0;
1476 dc
->dcn_soc
->dcfclkv_nom0p8
= dcfclks
.data
[dcfclks
.num_levels
- 2].clocks_in_khz
/ 1000.0;
1477 dc
->dcn_soc
->dcfclkv_max0p9
= dcfclks
.data
[dcfclks
.num_levels
- 1].clocks_in_khz
/ 1000.0;
1479 BREAK_TO_DEBUGGER();
1484 void dcn_bw_notify_pplib_of_wm_ranges(struct dc
*dc
)
1486 struct pp_smu_funcs_rv
*pp
= NULL
;
1487 struct pp_smu_wm_range_sets ranges
= {0};
1488 int min_fclk_khz
, min_dcfclk_khz
, socclk_khz
;
1489 const int overdrive
= 5000000; /* 5 GHz to cover Overdrive */
1491 if (dc
->res_pool
->pp_smu
)
1492 pp
= &dc
->res_pool
->pp_smu
->rv_funcs
;
1493 if (!pp
|| !pp
->set_wm_ranges
)
1497 min_fclk_khz
= dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
* 1000000 / 32;
1498 min_dcfclk_khz
= dc
->dcn_soc
->dcfclkv_min0p65
* 1000;
1499 socclk_khz
= dc
->dcn_soc
->socclk
* 1000;
1502 /* Now notify PPLib/SMU about which Watermarks sets they should select
1503 * depending on DPM state they are in. And update BW MGR GFX Engine and
1504 * Memory clock member variables for Watermarks calculations for each
1505 * Watermark Set. Only one watermark set for dcn1 due to hw bug DEGVIDCN10-254.
1507 /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont
1508 * care what the value is, hence min to overdrive level
1510 ranges
.num_reader_wm_sets
= WM_SET_COUNT
;
1511 ranges
.num_writer_wm_sets
= WM_SET_COUNT
;
1512 ranges
.reader_wm_sets
[0].wm_inst
= WM_A
;
1513 ranges
.reader_wm_sets
[0].min_drain_clk_mhz
= min_dcfclk_khz
/ 1000;
1514 ranges
.reader_wm_sets
[0].max_drain_clk_mhz
= overdrive
/ 1000;
1515 ranges
.reader_wm_sets
[0].min_fill_clk_mhz
= min_fclk_khz
/ 1000;
1516 ranges
.reader_wm_sets
[0].max_fill_clk_mhz
= overdrive
/ 1000;
1517 ranges
.writer_wm_sets
[0].wm_inst
= WM_A
;
1518 ranges
.writer_wm_sets
[0].min_fill_clk_mhz
= socclk_khz
/ 1000;
1519 ranges
.writer_wm_sets
[0].max_fill_clk_mhz
= overdrive
/ 1000;
1520 ranges
.writer_wm_sets
[0].min_drain_clk_mhz
= min_fclk_khz
/ 1000;
1521 ranges
.writer_wm_sets
[0].max_drain_clk_mhz
= overdrive
/ 1000;
1523 if (dc
->debug
.pplib_wm_report_mode
== WM_REPORT_OVERRIDE
) {
1524 ranges
.reader_wm_sets
[0].wm_inst
= WM_A
;
1525 ranges
.reader_wm_sets
[0].min_drain_clk_mhz
= 300;
1526 ranges
.reader_wm_sets
[0].max_drain_clk_mhz
= 5000;
1527 ranges
.reader_wm_sets
[0].min_fill_clk_mhz
= 800;
1528 ranges
.reader_wm_sets
[0].max_fill_clk_mhz
= 5000;
1529 ranges
.writer_wm_sets
[0].wm_inst
= WM_A
;
1530 ranges
.writer_wm_sets
[0].min_fill_clk_mhz
= 200;
1531 ranges
.writer_wm_sets
[0].max_fill_clk_mhz
= 5000;
1532 ranges
.writer_wm_sets
[0].min_drain_clk_mhz
= 800;
1533 ranges
.writer_wm_sets
[0].max_drain_clk_mhz
= 5000;
1536 ranges
.reader_wm_sets
[1] = ranges
.writer_wm_sets
[0];
1537 ranges
.reader_wm_sets
[1].wm_inst
= WM_B
;
1539 ranges
.reader_wm_sets
[2] = ranges
.writer_wm_sets
[0];
1540 ranges
.reader_wm_sets
[2].wm_inst
= WM_C
;
1542 ranges
.reader_wm_sets
[3] = ranges
.writer_wm_sets
[0];
1543 ranges
.reader_wm_sets
[3].wm_inst
= WM_D
;
1545 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1546 pp
->set_wm_ranges(&pp
->pp_smu
, &ranges
);
1549 void dcn_bw_sync_calcs_and_dml(struct dc
*dc
)
1552 DC_LOG_BANDWIDTH_CALCS("sr_exit_time: %f ns\n"
1553 "sr_enter_plus_exit_time: %f ns\n"
1554 "urgent_latency: %f ns\n"
1555 "write_back_latency: %f ns\n"
1556 "percent_of_ideal_drambw_received_after_urg_latency: %f %%\n"
1557 "max_request_size: %d bytes\n"
1558 "dcfclkv_max0p9: %f kHz\n"
1559 "dcfclkv_nom0p8: %f kHz\n"
1560 "dcfclkv_mid0p72: %f kHz\n"
1561 "dcfclkv_min0p65: %f kHz\n"
1562 "max_dispclk_vmax0p9: %f kHz\n"
1563 "max_dispclk_vnom0p8: %f kHz\n"
1564 "max_dispclk_vmid0p72: %f kHz\n"
1565 "max_dispclk_vmin0p65: %f kHz\n"
1566 "max_dppclk_vmax0p9: %f kHz\n"
1567 "max_dppclk_vnom0p8: %f kHz\n"
1568 "max_dppclk_vmid0p72: %f kHz\n"
1569 "max_dppclk_vmin0p65: %f kHz\n"
1571 "fabric_and_dram_bandwidth_vmax0p9: %f MB/s\n"
1572 "fabric_and_dram_bandwidth_vnom0p8: %f MB/s\n"
1573 "fabric_and_dram_bandwidth_vmid0p72: %f MB/s\n"
1574 "fabric_and_dram_bandwidth_vmin0p65: %f MB/s\n"
1575 "phyclkv_max0p9: %f kHz\n"
1576 "phyclkv_nom0p8: %f kHz\n"
1577 "phyclkv_mid0p72: %f kHz\n"
1578 "phyclkv_min0p65: %f kHz\n"
1579 "downspreading: %f %%\n"
1580 "round_trip_ping_latency_cycles: %d DCFCLK Cycles\n"
1581 "urgent_out_of_order_return_per_channel: %d Bytes\n"
1582 "number_of_channels: %d\n"
1583 "vmm_page_size: %d Bytes\n"
1584 "dram_clock_change_latency: %f ns\n"
1585 "return_bus_width: %d Bytes\n",
1586 dc
->dcn_soc
->sr_exit_time
* 1000,
1587 dc
->dcn_soc
->sr_enter_plus_exit_time
* 1000,
1588 dc
->dcn_soc
->urgent_latency
* 1000,
1589 dc
->dcn_soc
->write_back_latency
* 1000,
1590 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
,
1591 dc
->dcn_soc
->max_request_size
,
1592 dc
->dcn_soc
->dcfclkv_max0p9
* 1000,
1593 dc
->dcn_soc
->dcfclkv_nom0p8
* 1000,
1594 dc
->dcn_soc
->dcfclkv_mid0p72
* 1000,
1595 dc
->dcn_soc
->dcfclkv_min0p65
* 1000,
1596 dc
->dcn_soc
->max_dispclk_vmax0p9
* 1000,
1597 dc
->dcn_soc
->max_dispclk_vnom0p8
* 1000,
1598 dc
->dcn_soc
->max_dispclk_vmid0p72
* 1000,
1599 dc
->dcn_soc
->max_dispclk_vmin0p65
* 1000,
1600 dc
->dcn_soc
->max_dppclk_vmax0p9
* 1000,
1601 dc
->dcn_soc
->max_dppclk_vnom0p8
* 1000,
1602 dc
->dcn_soc
->max_dppclk_vmid0p72
* 1000,
1603 dc
->dcn_soc
->max_dppclk_vmin0p65
* 1000,
1604 dc
->dcn_soc
->socclk
* 1000,
1605 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
* 1000,
1606 dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
* 1000,
1607 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
* 1000,
1608 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
* 1000,
1609 dc
->dcn_soc
->phyclkv_max0p9
* 1000,
1610 dc
->dcn_soc
->phyclkv_nom0p8
* 1000,
1611 dc
->dcn_soc
->phyclkv_mid0p72
* 1000,
1612 dc
->dcn_soc
->phyclkv_min0p65
* 1000,
1613 dc
->dcn_soc
->downspreading
* 100,
1614 dc
->dcn_soc
->round_trip_ping_latency_cycles
,
1615 dc
->dcn_soc
->urgent_out_of_order_return_per_channel
,
1616 dc
->dcn_soc
->number_of_channels
,
1617 dc
->dcn_soc
->vmm_page_size
,
1618 dc
->dcn_soc
->dram_clock_change_latency
* 1000,
1619 dc
->dcn_soc
->return_bus_width
);
1620 DC_LOG_BANDWIDTH_CALCS("rob_buffer_size_in_kbyte: %f\n"
1621 "det_buffer_size_in_kbyte: %f\n"
1622 "dpp_output_buffer_pixels: %f\n"
1623 "opp_output_buffer_lines: %f\n"
1624 "pixel_chunk_size_in_kbyte: %f\n"
1626 "pte_chunk_size: %d kbytes\n"
1627 "meta_chunk_size: %d kbytes\n"
1628 "writeback_chunk_size: %d kbytes\n"
1629 "odm_capability: %d\n"
1630 "dsc_capability: %d\n"
1631 "line_buffer_size: %d bits\n"
1632 "max_line_buffer_lines: %d\n"
1633 "is_line_buffer_bpp_fixed: %d\n"
1634 "line_buffer_fixed_bpp: %d\n"
1635 "writeback_luma_buffer_size: %d kbytes\n"
1636 "writeback_chroma_buffer_size: %d kbytes\n"
1638 "max_num_writeback: %d\n"
1639 "max_dchub_topscl_throughput: %d pixels/dppclk\n"
1640 "max_pscl_tolb_throughput: %d pixels/dppclk\n"
1641 "max_lb_tovscl_throughput: %d pixels/dppclk\n"
1642 "max_vscl_tohscl_throughput: %d pixels/dppclk\n"
1643 "max_hscl_ratio: %f\n"
1644 "max_vscl_ratio: %f\n"
1645 "max_hscl_taps: %d\n"
1646 "max_vscl_taps: %d\n"
1647 "pte_buffer_size_in_requests: %d\n"
1648 "dispclk_ramping_margin: %f %%\n"
1649 "under_scan_factor: %f %%\n"
1650 "max_inter_dcn_tile_repeaters: %d\n"
1651 "can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one: %d\n"
1652 "bug_forcing_luma_and_chroma_request_to_same_size_fixed: %d\n"
1653 "dcfclk_cstate_latency: %d\n",
1654 dc
->dcn_ip
->rob_buffer_size_in_kbyte
,
1655 dc
->dcn_ip
->det_buffer_size_in_kbyte
,
1656 dc
->dcn_ip
->dpp_output_buffer_pixels
,
1657 dc
->dcn_ip
->opp_output_buffer_lines
,
1658 dc
->dcn_ip
->pixel_chunk_size_in_kbyte
,
1659 dc
->dcn_ip
->pte_enable
,
1660 dc
->dcn_ip
->pte_chunk_size
,
1661 dc
->dcn_ip
->meta_chunk_size
,
1662 dc
->dcn_ip
->writeback_chunk_size
,
1663 dc
->dcn_ip
->odm_capability
,
1664 dc
->dcn_ip
->dsc_capability
,
1665 dc
->dcn_ip
->line_buffer_size
,
1666 dc
->dcn_ip
->max_line_buffer_lines
,
1667 dc
->dcn_ip
->is_line_buffer_bpp_fixed
,
1668 dc
->dcn_ip
->line_buffer_fixed_bpp
,
1669 dc
->dcn_ip
->writeback_luma_buffer_size
,
1670 dc
->dcn_ip
->writeback_chroma_buffer_size
,
1671 dc
->dcn_ip
->max_num_dpp
,
1672 dc
->dcn_ip
->max_num_writeback
,
1673 dc
->dcn_ip
->max_dchub_topscl_throughput
,
1674 dc
->dcn_ip
->max_pscl_tolb_throughput
,
1675 dc
->dcn_ip
->max_lb_tovscl_throughput
,
1676 dc
->dcn_ip
->max_vscl_tohscl_throughput
,
1677 dc
->dcn_ip
->max_hscl_ratio
,
1678 dc
->dcn_ip
->max_vscl_ratio
,
1679 dc
->dcn_ip
->max_hscl_taps
,
1680 dc
->dcn_ip
->max_vscl_taps
,
1681 dc
->dcn_ip
->pte_buffer_size_in_requests
,
1682 dc
->dcn_ip
->dispclk_ramping_margin
,
1683 dc
->dcn_ip
->under_scan_factor
* 100,
1684 dc
->dcn_ip
->max_inter_dcn_tile_repeaters
,
1685 dc
->dcn_ip
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
,
1686 dc
->dcn_ip
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
,
1687 dc
->dcn_ip
->dcfclk_cstate_latency
);
1689 dc
->dml
.soc
.sr_exit_time_us
= dc
->dcn_soc
->sr_exit_time
;
1690 dc
->dml
.soc
.sr_enter_plus_exit_time_us
= dc
->dcn_soc
->sr_enter_plus_exit_time
;
1691 dc
->dml
.soc
.urgent_latency_us
= dc
->dcn_soc
->urgent_latency
;
1692 dc
->dml
.soc
.writeback_latency_us
= dc
->dcn_soc
->write_back_latency
;
1693 dc
->dml
.soc
.ideal_dram_bw_after_urgent_percent
=
1694 dc
->dcn_soc
->percent_of_ideal_drambw_received_after_urg_latency
;
1695 dc
->dml
.soc
.max_request_size_bytes
= dc
->dcn_soc
->max_request_size
;
1696 dc
->dml
.soc
.downspread_percent
= dc
->dcn_soc
->downspreading
;
1697 dc
->dml
.soc
.round_trip_ping_latency_dcfclk_cycles
=
1698 dc
->dcn_soc
->round_trip_ping_latency_cycles
;
1699 dc
->dml
.soc
.urgent_out_of_order_return_per_channel_bytes
=
1700 dc
->dcn_soc
->urgent_out_of_order_return_per_channel
;
1701 dc
->dml
.soc
.num_chans
= dc
->dcn_soc
->number_of_channels
;
1702 dc
->dml
.soc
.vmm_page_size_bytes
= dc
->dcn_soc
->vmm_page_size
;
1703 dc
->dml
.soc
.dram_clock_change_latency_us
= dc
->dcn_soc
->dram_clock_change_latency
;
1704 dc
->dml
.soc
.return_bus_width_bytes
= dc
->dcn_soc
->return_bus_width
;
1706 dc
->dml
.ip
.rob_buffer_size_kbytes
= dc
->dcn_ip
->rob_buffer_size_in_kbyte
;
1707 dc
->dml
.ip
.det_buffer_size_kbytes
= dc
->dcn_ip
->det_buffer_size_in_kbyte
;
1708 dc
->dml
.ip
.dpp_output_buffer_pixels
= dc
->dcn_ip
->dpp_output_buffer_pixels
;
1709 dc
->dml
.ip
.opp_output_buffer_lines
= dc
->dcn_ip
->opp_output_buffer_lines
;
1710 dc
->dml
.ip
.pixel_chunk_size_kbytes
= dc
->dcn_ip
->pixel_chunk_size_in_kbyte
;
1711 dc
->dml
.ip
.pte_enable
= dc
->dcn_ip
->pte_enable
== dcn_bw_yes
;
1712 dc
->dml
.ip
.pte_chunk_size_kbytes
= dc
->dcn_ip
->pte_chunk_size
;
1713 dc
->dml
.ip
.meta_chunk_size_kbytes
= dc
->dcn_ip
->meta_chunk_size
;
1714 dc
->dml
.ip
.writeback_chunk_size_kbytes
= dc
->dcn_ip
->writeback_chunk_size
;
1715 dc
->dml
.ip
.line_buffer_size_bits
= dc
->dcn_ip
->line_buffer_size
;
1716 dc
->dml
.ip
.max_line_buffer_lines
= dc
->dcn_ip
->max_line_buffer_lines
;
1717 dc
->dml
.ip
.IsLineBufferBppFixed
= dc
->dcn_ip
->is_line_buffer_bpp_fixed
== dcn_bw_yes
;
1718 dc
->dml
.ip
.LineBufferFixedBpp
= dc
->dcn_ip
->line_buffer_fixed_bpp
;
1719 dc
->dml
.ip
.writeback_luma_buffer_size_kbytes
= dc
->dcn_ip
->writeback_luma_buffer_size
;
1720 dc
->dml
.ip
.writeback_chroma_buffer_size_kbytes
= dc
->dcn_ip
->writeback_chroma_buffer_size
;
1721 dc
->dml
.ip
.max_num_dpp
= dc
->dcn_ip
->max_num_dpp
;
1722 dc
->dml
.ip
.max_num_wb
= dc
->dcn_ip
->max_num_writeback
;
1723 dc
->dml
.ip
.max_dchub_pscl_bw_pix_per_clk
= dc
->dcn_ip
->max_dchub_topscl_throughput
;
1724 dc
->dml
.ip
.max_pscl_lb_bw_pix_per_clk
= dc
->dcn_ip
->max_pscl_tolb_throughput
;
1725 dc
->dml
.ip
.max_lb_vscl_bw_pix_per_clk
= dc
->dcn_ip
->max_lb_tovscl_throughput
;
1726 dc
->dml
.ip
.max_vscl_hscl_bw_pix_per_clk
= dc
->dcn_ip
->max_vscl_tohscl_throughput
;
1727 dc
->dml
.ip
.max_hscl_ratio
= dc
->dcn_ip
->max_hscl_ratio
;
1728 dc
->dml
.ip
.max_vscl_ratio
= dc
->dcn_ip
->max_vscl_ratio
;
1729 dc
->dml
.ip
.max_hscl_taps
= dc
->dcn_ip
->max_hscl_taps
;
1730 dc
->dml
.ip
.max_vscl_taps
= dc
->dcn_ip
->max_vscl_taps
;
1731 /*pte_buffer_size_in_requests missing in dml*/
1732 dc
->dml
.ip
.dispclk_ramp_margin_percent
= dc
->dcn_ip
->dispclk_ramping_margin
;
1733 dc
->dml
.ip
.underscan_factor
= dc
->dcn_ip
->under_scan_factor
;
1734 dc
->dml
.ip
.max_inter_dcn_tile_repeaters
= dc
->dcn_ip
->max_inter_dcn_tile_repeaters
;
1735 dc
->dml
.ip
.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
=
1736 dc
->dcn_ip
->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
== dcn_bw_yes
;
1737 dc
->dml
.ip
.bug_forcing_LC_req_same_size_fixed
=
1738 dc
->dcn_ip
->bug_forcing_luma_and_chroma_request_to_same_size_fixed
== dcn_bw_yes
;
1739 dc
->dml
.ip
.dcfclk_cstate_latency
= dc
->dcn_ip
->dcfclk_cstate_latency
;