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