FILE
display_rq_dlg_calc_30.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
1/* 2 * Copyright 2020 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26#include "../display_mode_lib.h" 27#include "../display_mode_vba.h" 28#include "../dml_inline_defs.h" 29#include "display_rq_dlg_calc_30.h" 30#include "display_mode_vba_30.h" 31 32static bool is_dual_plane(enum source_format_class source_format) 33{ 34 bool ret_val = 0; 35 36 if ((source_format == dm_420_12) || (source_format == dm_420_8) || (source_format == dm_420_10) || (source_format == dm_rgbe_alpha)) 37 ret_val = 1; 38 39 return ret_val; 40} 41 42static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib, 43 double refclk_freq_in_mhz, 44 double pclk_freq_in_mhz, 45 unsigned int odm_combine, 46 unsigned int recout_width, 47 unsigned int hactive, 48 double vratio, 49 double hscale_pixel_rate, 50 unsigned int delivery_width, 51 unsigned int req_per_swath_ub) 52{ 53 double refcyc_per_delivery = 0.0; 54 55 if (vratio <= 1.0) { 56 if (odm_combine) 57 refcyc_per_delivery = (double)refclk_freq_in_mhz * (double)((unsigned int)odm_combine*2) 58 * dml_min((double)recout_width, (double)hactive / ((unsigned int)odm_combine*2)) 59 / pclk_freq_in_mhz / (double)req_per_swath_ub; 60 else 61 refcyc_per_delivery = (double)refclk_freq_in_mhz * (double)recout_width 62 / pclk_freq_in_mhz / (double)req_per_swath_ub; 63 } else { 64 refcyc_per_delivery = (double)refclk_freq_in_mhz * (double)delivery_width 65 / (double)hscale_pixel_rate / (double)req_per_swath_ub; 66 } 67 68 dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz); 69 dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz); 70 dml_print("DML_DLG: %s: recout_width = %d\n", __func__, recout_width); 71 dml_print("DML_DLG: %s: vratio = %3.2f\n", __func__, vratio); 72 dml_print("DML_DLG: %s: req_per_swath_ub = %d\n", __func__, req_per_swath_ub); 73 dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery); 74 75 return refcyc_per_delivery; 76 77} 78 79static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size) 80{ 81 if (tile_size == dm_256k_tile) 82 return (256 * 1024); 83 else if (tile_size == dm_64k_tile) 84 return (64 * 1024); 85 else 86 return (4 * 1024); 87} 88 89static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, 90 display_data_rq_regs_st *rq_regs, 91 const display_data_rq_sizing_params_st *rq_sizing) 92{ 93 dml_print("DML_DLG: %s: rq_sizing param\n", __func__); 94 print__data_rq_sizing_params_st(mode_lib, rq_sizing); 95 96 rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; 97 98 if (rq_sizing->min_chunk_bytes == 0) 99 rq_regs->min_chunk_size = 0; 100 else 101 rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; 102 103 rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; 104 if (rq_sizing->min_meta_chunk_bytes == 0) 105 rq_regs->min_meta_chunk_size = 0; 106 else 107 rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; 108 109 rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; 110 rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; 111} 112 113static void extract_rq_regs(struct display_mode_lib *mode_lib, 114 display_rq_regs_st *rq_regs, 115 const display_rq_params_st *rq_param) 116{ 117 unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; 118 unsigned int detile_buf_plane1_addr = 0; 119 120 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); 121 122 rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_l.dpte_row_height), 123 1) - 3; 124 125 if (rq_param->yuv420) { 126 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); 127 rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_c.dpte_row_height), 128 1) - 3; 129 } 130 131 rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); 132 rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); 133 134 // FIXME: take the max between luma, chroma chunk size? 135 // okay for now, as we are setting chunk_bytes to 8kb anyways 136 if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024 || (rq_param->yuv420 && rq_param->sizing.rq_c.chunk_bytes >= 32 * 1024)) { //32kb 137 rq_regs->drq_expansion_mode = 0; 138 } else { 139 rq_regs->drq_expansion_mode = 2; 140 } 141 rq_regs->prq_expansion_mode = 1; 142 rq_regs->mrq_expansion_mode = 1; 143 rq_regs->crq_expansion_mode = 1; 144 145 if (rq_param->yuv420) { 146 if ((double)rq_param->misc.rq_l.stored_swath_bytes 147 / (double)rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { 148 detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma 149 } else { 150 detile_buf_plane1_addr = dml_round_to_multiple((unsigned int)((2.0 * detile_buf_size_in_bytes) / 3.0), 151 256, 152 0) / 64.0; // 2/3 to chroma 153 } 154 } 155 rq_regs->plane1_base_address = detile_buf_plane1_addr; 156} 157 158static void handle_det_buf_split(struct display_mode_lib *mode_lib, 159 display_rq_params_st *rq_param, 160 const display_pipe_source_params_st *pipe_src_param) 161{ 162 unsigned int total_swath_bytes = 0; 163 unsigned int swath_bytes_l = 0; 164 unsigned int swath_bytes_c = 0; 165 unsigned int full_swath_bytes_packed_l = 0; 166 unsigned int full_swath_bytes_packed_c = 0; 167 bool req128_l = false; 168 bool req128_c = false; 169 bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); 170 bool surf_vert = (pipe_src_param->source_scan == dm_vert); 171 unsigned int log2_swath_height_l = 0; 172 unsigned int log2_swath_height_c = 0; 173 unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; 174 175 full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes; 176 full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes; 177 178 if (rq_param->yuv420_10bpc) { 179 full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2.0 / 3.0, 180 256, 181 1) + 256; 182 full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2.0 / 3.0, 183 256, 184 1) + 256; 185 } 186 187 if (rq_param->yuv420) 188 total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c; 189 else 190 total_swath_bytes = 2 * full_swath_bytes_packed_l; 191 192 if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request 193 req128_l = false; 194 req128_c = false; 195 swath_bytes_l = full_swath_bytes_packed_l; 196 swath_bytes_c = full_swath_bytes_packed_c; 197 } else if (!rq_param->yuv420) { 198 req128_l = true; 199 req128_c = false; 200 swath_bytes_c = full_swath_bytes_packed_c; 201 swath_bytes_l = full_swath_bytes_packed_l / 2; 202 } else if ((double)full_swath_bytes_packed_l / (double)full_swath_bytes_packed_c < 1.5) { 203 req128_l = false; 204 req128_c = true; 205 swath_bytes_l = full_swath_bytes_packed_l; 206 swath_bytes_c = full_swath_bytes_packed_c / 2; 207 208 total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c; 209 210 if (total_swath_bytes > detile_buf_size_in_bytes) { 211 req128_l = true; 212 swath_bytes_l = full_swath_bytes_packed_l / 2; 213 } 214 } else { 215 req128_l = true; 216 req128_c = false; 217 swath_bytes_l = full_swath_bytes_packed_l/2; 218 swath_bytes_c = full_swath_bytes_packed_c; 219 220 total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c; 221 222 if (total_swath_bytes > detile_buf_size_in_bytes) { 223 req128_c = true; 224 swath_bytes_c = full_swath_bytes_packed_c/2; 225 } 226 } 227 228 if (rq_param->yuv420) 229 total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c; 230 else 231 total_swath_bytes = 2 * swath_bytes_l; 232 233 rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l; 234 rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c; 235 236 if (surf_linear) { 237 log2_swath_height_l = 0; 238 log2_swath_height_c = 0; 239 } else { 240 unsigned int swath_height_l; 241 unsigned int swath_height_c; 242 243 if (!surf_vert) { 244 swath_height_l = rq_param->misc.rq_l.blk256_height; 245 swath_height_c = rq_param->misc.rq_c.blk256_height; 246 } else { 247 swath_height_l = rq_param->misc.rq_l.blk256_width; 248 swath_height_c = rq_param->misc.rq_c.blk256_width; 249 } 250 251 if (swath_height_l > 0) 252 log2_swath_height_l = dml_log2(swath_height_l); 253 254 if (req128_l && log2_swath_height_l > 0) 255 log2_swath_height_l -= 1; 256 257 if (swath_height_c > 0) 258 log2_swath_height_c = dml_log2(swath_height_c); 259 260 if (req128_c && log2_swath_height_c > 0) 261 log2_swath_height_c -= 1; 262 } 263 264 rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; 265 rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; 266 267 dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l); 268 dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c); 269 dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n", 270 __func__, 271 full_swath_bytes_packed_l); 272 dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n", 273 __func__, 274 full_swath_bytes_packed_c); 275} 276 277static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib, 278 display_data_rq_dlg_params_st *rq_dlg_param, 279 display_data_rq_misc_params_st *rq_misc_param, 280 display_data_rq_sizing_params_st *rq_sizing_param, 281 unsigned int vp_width, 282 unsigned int vp_height, 283 unsigned int data_pitch, 284 unsigned int meta_pitch, 285 unsigned int source_format, 286 unsigned int tiling, 287 unsigned int macro_tile_size, 288 unsigned int source_scan, 289 unsigned int hostvm_enable, 290 unsigned int is_chroma, 291 unsigned int surface_height) 292{ 293 bool surf_linear = (tiling == dm_sw_linear); 294 bool surf_vert = (source_scan == dm_vert); 295 296 unsigned int bytes_per_element = 0; 297 unsigned int bytes_per_element_y = 0; 298 unsigned int bytes_per_element_c = 0; 299 300 unsigned int blk256_width = 0; 301 unsigned int blk256_height = 0; 302 303 unsigned int blk256_width_y = 0; 304 unsigned int blk256_height_y = 0; 305 unsigned int blk256_width_c = 0; 306 unsigned int blk256_height_c = 0; 307 unsigned int log2_bytes_per_element = 0; 308 unsigned int log2_blk256_width = 0; 309 unsigned int log2_blk256_height = 0; 310 unsigned int blk_bytes = 0; 311 unsigned int log2_blk_bytes = 0; 312 unsigned int log2_blk_height = 0; 313 unsigned int log2_blk_width = 0; 314 unsigned int log2_meta_req_bytes = 0; 315 unsigned int log2_meta_req_height = 0; 316 unsigned int log2_meta_req_width = 0; 317 unsigned int meta_req_width = 0; 318 unsigned int meta_req_height = 0; 319 unsigned int log2_meta_row_height = 0; 320 unsigned int meta_row_width_ub = 0; 321 unsigned int log2_meta_chunk_bytes = 0; 322 unsigned int log2_meta_chunk_height = 0; 323 324 //full sized meta chunk width in unit of data elements 325 unsigned int log2_meta_chunk_width = 0; 326 unsigned int log2_min_meta_chunk_bytes = 0; 327 unsigned int min_meta_chunk_width = 0; 328 unsigned int meta_chunk_width = 0; 329 unsigned int meta_chunk_per_row_int = 0; 330 unsigned int meta_row_remainder = 0; 331 unsigned int meta_chunk_threshold = 0; 332 unsigned int meta_blk_bytes = 0; 333 unsigned int meta_blk_height = 0; 334 unsigned int meta_blk_width = 0; 335 unsigned int meta_surface_bytes = 0; 336 unsigned int vmpg_bytes = 0; 337 unsigned int meta_pte_req_per_frame_ub = 0; 338 unsigned int meta_pte_bytes_per_frame_ub = 0; 339 const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.gpuvm_min_page_size_bytes); 340 const bool dual_plane_en = is_dual_plane((enum source_format_class)(source_format)); 341 const unsigned int dpte_buf_in_pte_reqs = dual_plane_en ? 342 (is_chroma ? mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma : mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma) 343 : (mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma + mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma); 344 345 unsigned int log2_vmpg_height = 0; 346 unsigned int log2_vmpg_width = 0; 347 unsigned int log2_dpte_req_height_ptes = 0; 348 unsigned int log2_dpte_req_height = 0; 349 unsigned int log2_dpte_req_width = 0; 350 unsigned int log2_dpte_row_height_linear = 0; 351 unsigned int log2_dpte_row_height = 0; 352 unsigned int log2_dpte_group_width = 0; 353 unsigned int dpte_row_width_ub = 0; 354 unsigned int dpte_req_height = 0; 355 unsigned int dpte_req_width = 0; 356 unsigned int dpte_group_width = 0; 357 unsigned int log2_dpte_group_bytes = 0; 358 unsigned int log2_dpte_group_length = 0; 359 double byte_per_pixel_det_y = 0; 360 double byte_per_pixel_det_c = 0; 361 362 dml30_CalculateBytePerPixelAnd256BBlockSizes((enum source_format_class)(source_format), 363 (enum dm_swizzle_mode)(tiling), 364 &bytes_per_element_y, 365 &bytes_per_element_c, 366 &byte_per_pixel_det_y, 367 &byte_per_pixel_det_c, 368 &blk256_height_y, 369 &blk256_height_c, 370 &blk256_width_y, 371 &blk256_width_c); 372 373 if (!is_chroma) { 374 blk256_width = blk256_width_y; 375 blk256_height = blk256_height_y; 376 bytes_per_element = bytes_per_element_y; 377 } else { 378 blk256_width = blk256_width_c; 379 blk256_height = blk256_height_c; 380 bytes_per_element = bytes_per_element_c; 381 } 382 383 log2_bytes_per_element = dml_log2(bytes_per_element); 384 385 dml_print("DML_DLG: %s: surf_linear = %d\n", __func__, surf_linear); 386 dml_print("DML_DLG: %s: surf_vert = %d\n", __func__, surf_vert); 387 dml_print("DML_DLG: %s: blk256_width = %d\n", __func__, blk256_width); 388 dml_print("DML_DLG: %s: blk256_height = %d\n", __func__, blk256_height); 389 390 log2_blk256_width = dml_log2((double)blk256_width); 391 log2_blk256_height = dml_log2((double)blk256_height); 392 blk_bytes = surf_linear ? 393 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); 394 log2_blk_bytes = dml_log2((double)blk_bytes); 395 396 // remember log rule 397 // "+" in log is multiply 398 // "-" in log is divide 399 // "/2" is like square root 400 // blk is vertical biased 401 if (tiling != dm_sw_linear) 402 log2_blk_height = log2_blk256_height 403 + dml_ceil((double)(log2_blk_bytes - 8) / 2.0, 1); 404 else 405 log2_blk_height = 0; // blk height of 1 406 407 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; 408 409 if (!surf_vert) { 410 int unsigned temp = 0; 411 412 temp = dml_round_to_multiple(vp_width - 1, blk256_width, 1) + blk256_width; 413 if (data_pitch < blk256_width) { 414 dml_print("WARNING: DML_DLG: %s: swath_size calculation ignoring data_pitch=%u < blk256_width=%u\n", __func__, data_pitch, blk256_width); 415 } else { 416 if (temp > data_pitch) { 417 if (data_pitch >= vp_width) 418 temp = data_pitch; 419 else 420 dml_print("WARNING: DML_DLG: %s: swath_size calculation ignoring data_pitch=%u < vp_width=%u\n", __func__, data_pitch, vp_width); 421 } 422 } 423 rq_dlg_param->swath_width_ub = temp; 424 rq_dlg_param->req_per_swath_ub = temp >> log2_blk256_width; 425 } else { 426 int unsigned temp = 0; 427 428 temp = dml_round_to_multiple(vp_height - 1, blk256_height, 1) + blk256_height; 429 if (surface_height < blk256_height) { 430 dml_print("WARNING: DML_DLG: %s swath_size calculation ignored surface_height=%u < blk256_height=%u\n", __func__, surface_height, blk256_height); 431 } else { 432 if (temp > surface_height) { 433 if (surface_height >= vp_height) 434 temp = surface_height; 435 else 436 dml_print("WARNING: DML_DLG: %s swath_size calculation ignored surface_height=%u < vp_height=%u\n", __func__, surface_height, vp_height); 437 } 438 } 439 rq_dlg_param->swath_width_ub = temp; 440 rq_dlg_param->req_per_swath_ub = temp >> log2_blk256_height; 441 } 442 443 if (!surf_vert) 444 rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height 445 * bytes_per_element; 446 else 447 rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width 448 * bytes_per_element; 449 450 rq_misc_param->blk256_height = blk256_height; 451 rq_misc_param->blk256_width = blk256_width; 452 453 // ------- 454 // meta 455 // ------- 456 log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element 457 458 // each 64b meta request for dcn is 8x8 meta elements and 459 // a meta element covers one 256b block of the data surface. 460 log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256 461 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element 462 - log2_meta_req_height; 463 meta_req_width = 1 << log2_meta_req_width; 464 meta_req_height = 1 << log2_meta_req_height; 465 466 // the dimensions of a meta row are meta_row_width x meta_row_height in elements. 467 // calculate upper bound of the meta_row_width 468 if (!surf_vert) { 469 log2_meta_row_height = log2_meta_req_height; 470 meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) 471 + meta_req_width; 472 rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width; 473 } else { 474 log2_meta_row_height = log2_meta_req_width; 475 meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1) 476 + meta_req_height; 477 rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height; 478 } 479 rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64; 480 481 rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; 482 483 log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes); 484 log2_meta_chunk_height = log2_meta_row_height; 485 486 //full sized meta chunk width in unit of data elements 487 log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element 488 - log2_meta_chunk_height; 489 log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes); 490 min_meta_chunk_width = 1 491 << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element 492 - log2_meta_chunk_height); 493 meta_chunk_width = 1 << log2_meta_chunk_width; 494 meta_chunk_per_row_int = (unsigned int)(meta_row_width_ub / meta_chunk_width); 495 meta_row_remainder = meta_row_width_ub % meta_chunk_width; 496 meta_chunk_threshold = 0; 497 meta_blk_bytes = 4096; 498 meta_blk_height = blk256_height * 64; 499 meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height; 500 meta_surface_bytes = meta_pitch 501 * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height) 502 * bytes_per_element / 256; 503 vmpg_bytes = mode_lib->soc.gpuvm_min_page_size_bytes; 504 meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes, 505 8 * vmpg_bytes, 506 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes); 507 meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request 508 rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub; 509 510 dml_print("DML_DLG: %s: meta_blk_height = %d\n", __func__, meta_blk_height); 511 dml_print("DML_DLG: %s: meta_blk_width = %d\n", __func__, meta_blk_width); 512 dml_print("DML_DLG: %s: meta_surface_bytes = %d\n", __func__, meta_surface_bytes); 513 dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub = %d\n", 514 __func__, 515 meta_pte_req_per_frame_ub); 516 dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n", 517 __func__, 518 meta_pte_bytes_per_frame_ub); 519 520 if (!surf_vert) 521 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width; 522 else 523 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height; 524 525 if (meta_row_remainder <= meta_chunk_threshold) 526 rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1; 527 else 528 rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; 529 530 // ------ 531 // dpte 532 // ------ 533 if (surf_linear) { 534 log2_vmpg_height = 0; // one line high 535 } else { 536 log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; 537 } 538 log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; 539 540 // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. 541 if (surf_linear) { //one 64B PTE request returns 8 PTEs 542 log2_dpte_req_height_ptes = 0; 543 log2_dpte_req_width = log2_vmpg_width + 3; 544 log2_dpte_req_height = 0; 545 } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size 546 //one 64B req gives 8x1 PTEs for 4KB tile 547 log2_dpte_req_height_ptes = 0; 548 log2_dpte_req_width = log2_blk_width + 3; 549 log2_dpte_req_height = log2_blk_height + 0; 550 } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB 551 //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB 552 log2_dpte_req_height_ptes = 4; 553 log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width 554 log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height 555 } else { //64KB page size and must 64KB tile block 556 //one 64B req gives 8x1 PTEs for 64KB tile 557 log2_dpte_req_height_ptes = 0; 558 log2_dpte_req_width = log2_blk_width + 3; 559 log2_dpte_req_height = log2_blk_height + 0; 560 } 561 562 // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height 563 // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent 564 // That depends on the pte shape (i.e. 8x1, 4x2, 2x4) 565 //log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; 566 //log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; 567 dpte_req_height = 1 << log2_dpte_req_height; 568 dpte_req_width = 1 << log2_dpte_req_width; 569 570 // calculate pitch dpte row buffer can hold 571 // round the result down to a power of two. 572 if (surf_linear) { 573 unsigned int dpte_row_height = 0; 574 575 log2_dpte_row_height_linear = dml_floor(dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch), 1); 576 577 dml_print("DML_DLG: %s: is_chroma = %d\n", __func__, is_chroma); 578 dml_print("DML_DLG: %s: dpte_buf_in_pte_reqs = %d\n", __func__, dpte_buf_in_pte_reqs); 579 dml_print("DML_DLG: %s: log2_dpte_row_height_linear = %d\n", __func__, log2_dpte_row_height_linear); 580 581 ASSERT(log2_dpte_row_height_linear >= 3); 582 583 if (log2_dpte_row_height_linear > 7) 584 log2_dpte_row_height_linear = 7; 585 586 log2_dpte_row_height = log2_dpte_row_height_linear; 587 // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. 588 // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. 589 dpte_row_height = 1 << log2_dpte_row_height; 590 dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1, 591 dpte_req_width, 592 1) + dpte_req_width; 593 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; 594 } else { 595 // the upper bound of the dpte_row_width without dependency on viewport position follows. 596 // for tiled mode, row height is the same as req height and row store up to vp size upper bound 597 if (!surf_vert) { 598 log2_dpte_row_height = log2_dpte_req_height; 599 dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) 600 + dpte_req_width; 601 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; 602 } else { 603 log2_dpte_row_height = 604 (log2_blk_width < log2_dpte_req_width) ? 605 log2_blk_width : log2_dpte_req_width; 606 dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1) 607 + dpte_req_height; 608 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height; 609 } 610 } 611 if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB 612 rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request 613 else 614 rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request 615 616 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; 617 618 // the dpte_group_bytes is reduced for the specific case of vertical 619 // access of a tile surface that has dpte request of 8x1 ptes. 620 if (hostvm_enable) 621 rq_sizing_param->dpte_group_bytes = 512; 622 else { 623 if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 624 rq_sizing_param->dpte_group_bytes = 512; 625 else 626 rq_sizing_param->dpte_group_bytes = 2048; 627 } 628 629 //since pte request size is 64byte, the number of data pte requests per full sized group is as follows. 630 log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes); 631 log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests 632 633 // full sized data pte group width in elements 634 if (!surf_vert) 635 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width; 636 else 637 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height; 638 639 //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B 640 if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB 641 log2_dpte_group_width = log2_dpte_group_width - 1; 642 643 dpte_group_width = 1 << log2_dpte_group_width; 644 645 // since dpte groups are only aligned to dpte_req_width and not dpte_group_width, 646 // the upper bound for the dpte groups per row is as follows. 647 rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double)dpte_row_width_ub / dpte_group_width, 648 1); 649} 650 651static void get_surf_rq_param(struct display_mode_lib *mode_lib, 652 display_data_rq_sizing_params_st *rq_sizing_param, 653 display_data_rq_dlg_params_st *rq_dlg_param, 654 display_data_rq_misc_params_st *rq_misc_param, 655 const display_pipe_params_st *pipe_param, 656 bool is_chroma, 657 bool is_alpha) 658{ 659 unsigned int vp_width = 0; 660 unsigned int vp_height = 0; 661 unsigned int data_pitch = 0; 662 unsigned int meta_pitch = 0; 663 unsigned int surface_height = 0; 664 unsigned int ppe = 1; 665 666 // FIXME check if ppe apply for both luma and chroma in 422 case 667 if (is_chroma | is_alpha) { 668 vp_width = pipe_param->src.viewport_width_c / ppe; 669 vp_height = pipe_param->src.viewport_height_c; 670 data_pitch = pipe_param->src.data_pitch_c; 671 meta_pitch = pipe_param->src.meta_pitch_c; 672 surface_height = pipe_param->src.surface_height_y / 2.0; 673 } else { 674 vp_width = pipe_param->src.viewport_width / ppe; 675 vp_height = pipe_param->src.viewport_height; 676 data_pitch = pipe_param->src.data_pitch; 677 meta_pitch = pipe_param->src.meta_pitch; 678 surface_height = pipe_param->src.surface_height_y; 679 } 680 681 if (pipe_param->dest.odm_combine) { 682 unsigned int access_dir = 0; 683 unsigned int full_src_vp_width = 0; 684 unsigned int hactive_odm = 0; 685 unsigned int src_hactive_odm = 0; 686 access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed 687 hactive_odm = pipe_param->dest.hactive / ((unsigned int) pipe_param->dest.odm_combine*2); 688 if (is_chroma) { 689 full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; 690 src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_odm; 691 } else { 692 full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; 693 src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio * hactive_odm; 694 } 695 696 if (access_dir == 0) { 697 vp_width = dml_min(full_src_vp_width, src_hactive_odm); 698 dml_print("DML_DLG: %s: vp_width = %d\n", __func__, vp_width); 699 } else { 700 vp_height = dml_min(full_src_vp_width, src_hactive_odm); 701 dml_print("DML_DLG: %s: vp_height = %d\n", __func__, vp_height); 702 } 703 dml_print("DML_DLG: %s: full_src_vp_width = %d\n", __func__, full_src_vp_width); 704 dml_print("DML_DLG: %s: hactive_odm = %d\n", __func__, hactive_odm); 705 dml_print("DML_DLG: %s: src_hactive_odm = %d\n", __func__, src_hactive_odm); 706 } 707 708 rq_sizing_param->chunk_bytes = 8192; 709 710 if (is_alpha) { 711 rq_sizing_param->chunk_bytes = 4096; 712 } 713 714 if (rq_sizing_param->chunk_bytes == 64 * 1024) 715 rq_sizing_param->min_chunk_bytes = 0; 716 else 717 rq_sizing_param->min_chunk_bytes = 1024; 718 719 rq_sizing_param->meta_chunk_bytes = 2048; 720 rq_sizing_param->min_meta_chunk_bytes = 256; 721 722 if (pipe_param->src.hostvm) 723 rq_sizing_param->mpte_group_bytes = 512; 724 else 725 rq_sizing_param->mpte_group_bytes = 2048; 726 727 get_meta_and_pte_attr(mode_lib, 728 rq_dlg_param, 729 rq_misc_param, 730 rq_sizing_param, 731 vp_width, 732 vp_height, 733 data_pitch, 734 meta_pitch, 735 pipe_param->src.source_format, 736 pipe_param->src.sw_mode, 737 pipe_param->src.macro_tile_size, 738 pipe_param->src.source_scan, 739 pipe_param->src.hostvm, 740 is_chroma, 741 surface_height); 742} 743 744static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, 745 display_rq_params_st *rq_param, 746 const display_pipe_params_st *pipe_param) 747{ 748 // get param for luma surface 749 rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 750 || pipe_param->src.source_format == dm_420_10 751 || pipe_param->src.source_format == dm_rgbe_alpha 752 || pipe_param->src.source_format == dm_420_12; 753 754 rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10; 755 756 rq_param->rgbe_alpha = (pipe_param->src.source_format == dm_rgbe_alpha)?1:0; 757 758 get_surf_rq_param(mode_lib, 759 &(rq_param->sizing.rq_l), 760 &(rq_param->dlg.rq_l), 761 &(rq_param->misc.rq_l), 762 pipe_param, 763 0, 764 0); 765 766 if (is_dual_plane((enum source_format_class)(pipe_param->src.source_format))) { 767 // get param for chroma surface 768 get_surf_rq_param(mode_lib, 769 &(rq_param->sizing.rq_c), 770 &(rq_param->dlg.rq_c), 771 &(rq_param->misc.rq_c), 772 pipe_param, 773 1, 774 rq_param->rgbe_alpha); 775 } 776 777 // calculate how to split the det buffer space between luma and chroma 778 handle_det_buf_split(mode_lib, rq_param, &pipe_param->src); 779 print__rq_params_st(mode_lib, rq_param); 780} 781 782void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, 783 display_rq_regs_st *rq_regs, 784 const display_pipe_params_st *pipe_param) 785{ 786 display_rq_params_st rq_param = { 0 }; 787 788 memset(rq_regs, 0, sizeof(*rq_regs)); 789 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param); 790 extract_rq_regs(mode_lib, rq_regs, &rq_param); 791 792 print__rq_regs_st(mode_lib, rq_regs); 793} 794 795static void calculate_ttu_cursor(struct display_mode_lib *mode_lib, 796 double *refcyc_per_req_delivery_pre_cur, 797 double *refcyc_per_req_delivery_cur, 798 double refclk_freq_in_mhz, 799 double ref_freq_to_pix_freq, 800 double hscale_pixel_rate_l, 801 double hscl_ratio, 802 double vratio_pre_l, 803 double vratio_l, 804 unsigned int cur_width, 805 enum cursor_bpp cur_bpp) 806{ 807 unsigned int cur_src_width = cur_width; 808 unsigned int cur_req_size = 0; 809 unsigned int cur_req_width = 0; 810 double cur_width_ub = 0.0; 811 double cur_req_per_width = 0.0; 812 double hactive_cur = 0.0; 813 814 ASSERT(cur_src_width <= 256); 815 816 *refcyc_per_req_delivery_pre_cur = 0.0; 817 *refcyc_per_req_delivery_cur = 0.0; 818 if (cur_src_width > 0) { 819 unsigned int cur_bit_per_pixel = 0; 820 821 if (cur_bpp == dm_cur_2bit) { 822 cur_req_size = 64; // byte 823 cur_bit_per_pixel = 2; 824 } else { // 32bit 825 cur_bit_per_pixel = 32; 826 if (cur_src_width >= 1 && cur_src_width <= 16) 827 cur_req_size = 64; 828 else if (cur_src_width >= 17 && cur_src_width <= 31) 829 cur_req_size = 128; 830 else 831 cur_req_size = 256; 832 } 833 834 cur_req_width = (double)cur_req_size / ((double)cur_bit_per_pixel / 8.0); 835 cur_width_ub = dml_ceil((double)cur_src_width / (double)cur_req_width, 1) 836 * (double)cur_req_width; 837 cur_req_per_width = cur_width_ub / (double)cur_req_width; 838 hactive_cur = (double)cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor 839 840 if (vratio_pre_l <= 1.0) { 841 *refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq 842 / (double)cur_req_per_width; 843 } else { 844 *refcyc_per_req_delivery_pre_cur = (double)refclk_freq_in_mhz 845 * (double)cur_src_width / hscale_pixel_rate_l 846 / (double)cur_req_per_width; 847 } 848 849 ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13)); 850 851 if (vratio_l <= 1.0) { 852 *refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq 853 / (double)cur_req_per_width; 854 } else { 855 *refcyc_per_req_delivery_cur = (double)refclk_freq_in_mhz 856 * (double)cur_src_width / hscale_pixel_rate_l 857 / (double)cur_req_per_width; 858 } 859 860 dml_print("DML_DLG: %s: cur_req_width = %d\n", 861 __func__, 862 cur_req_width); 863 dml_print("DML_DLG: %s: cur_width_ub = %3.2f\n", 864 __func__, 865 cur_width_ub); 866 dml_print("DML_DLG: %s: cur_req_per_width = %3.2f\n", 867 __func__, 868 cur_req_per_width); 869 dml_print("DML_DLG: %s: hactive_cur = %3.2f\n", 870 __func__, 871 hactive_cur); 872 dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur = %3.2f\n", 873 __func__, 874 *refcyc_per_req_delivery_pre_cur); 875 dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur = %3.2f\n", 876 __func__, 877 *refcyc_per_req_delivery_cur); 878 879 ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13)); 880 } 881} 882 883// Note: currently taken in as is. 884// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. 885static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, 886 const display_e2e_pipe_params_st *e2e_pipe_param, 887 const unsigned int num_pipes, 888 const unsigned int pipe_idx, 889 display_dlg_regs_st *disp_dlg_regs, 890 display_ttu_regs_st *disp_ttu_regs, 891 const display_rq_dlg_params_st rq_dlg_param, 892 const display_dlg_sys_params_st dlg_sys_param, 893 const bool cstate_en, 894 const bool pstate_en, 895 const bool vm_en, 896 const bool ignore_viewport_pos, 897 const bool immediate_flip_support) 898{ 899 const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src; 900 const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest; 901 const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout; 902 const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg; 903 const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth; 904 const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps; 905 906 // ------------------------- 907 // Section 1.15.2.1: OTG dependent Params 908 // ------------------------- 909 // Timing 910 unsigned int htotal = dst->htotal; 911 // unsigned int hblank_start = dst.hblank_start; // TODO: Remove 912 unsigned int hblank_end = dst->hblank_end; 913 unsigned int vblank_start = dst->vblank_start; 914 unsigned int vblank_end = dst->vblank_end; 915 unsigned int min_vblank = mode_lib->ip.min_vblank_lines; 916 917 double dppclk_freq_in_mhz = clks->dppclk_mhz; 918 double dispclk_freq_in_mhz = clks->dispclk_mhz; 919 double refclk_freq_in_mhz = clks->refclk_mhz; 920 double pclk_freq_in_mhz = dst->pixel_rate_mhz; 921 bool interlaced = dst->interlaced; 922 923 double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; 924 925 double min_dcfclk_mhz = 0; 926 double t_calc_us = 0; 927 double min_ttu_vblank = 0; 928 929 double min_dst_y_ttu_vblank = 0; 930 unsigned int dlg_vblank_start = 0; 931 bool dual_plane = false; 932 unsigned int access_dir = 0; 933 unsigned int vp_height_l = 0; 934 unsigned int vp_width_l = 0; 935 unsigned int vp_height_c = 0; 936 unsigned int vp_width_c = 0; 937 938 // Scaling 939 unsigned int htaps_l = 0; 940 unsigned int htaps_c = 0; 941 double hratio_l = 0; 942 double hratio_c = 0; 943 double vratio_l = 0; 944 double vratio_c = 0; 945 bool scl_enable = false; 946 947 double line_time_in_us = 0; 948 // double vinit_l; 949 // double vinit_c; 950 // double vinit_bot_l; 951 // double vinit_bot_c; 952 953 // unsigned int swath_height_l; 954 unsigned int swath_width_ub_l = 0; 955 // unsigned int dpte_bytes_per_row_ub_l; 956 unsigned int dpte_groups_per_row_ub_l = 0; 957 // unsigned int meta_pte_bytes_per_frame_ub_l; 958 // unsigned int meta_bytes_per_row_ub_l; 959 960 // unsigned int swath_height_c; 961 unsigned int swath_width_ub_c = 0; 962 // unsigned int dpte_bytes_per_row_ub_c; 963 unsigned int dpte_groups_per_row_ub_c = 0; 964 965 unsigned int meta_chunks_per_row_ub_l = 0; 966 unsigned int meta_chunks_per_row_ub_c = 0; 967 unsigned int vupdate_offset = 0; 968 unsigned int vupdate_width = 0; 969 unsigned int vready_offset = 0; 970 971 unsigned int dppclk_delay_subtotal = 0; 972 unsigned int dispclk_delay_subtotal = 0; 973 unsigned int pixel_rate_delay_subtotal = 0; 974 975 unsigned int vstartup_start = 0; 976 unsigned int dst_x_after_scaler = 0; 977 int dst_y_after_scaler = 0; 978 double line_wait = 0; 979 double dst_y_prefetch = 0; 980 double dst_y_per_vm_vblank = 0; 981 double dst_y_per_row_vblank = 0; 982 double dst_y_per_vm_flip = 0; 983 double dst_y_per_row_flip = 0; 984 double max_dst_y_per_vm_vblank = 0; 985 double max_dst_y_per_row_vblank = 0; 986 double lsw = 0; 987 double vratio_pre_l = 0; 988 double vratio_pre_c = 0; 989 unsigned int req_per_swath_ub_l = 0; 990 unsigned int req_per_swath_ub_c = 0; 991 unsigned int meta_row_height_l = 0; 992 unsigned int meta_row_height_c = 0; 993 unsigned int swath_width_pixels_ub_l = 0; 994 unsigned int swath_width_pixels_ub_c = 0; 995 unsigned int scaler_rec_in_width_l = 0; 996 unsigned int scaler_rec_in_width_c = 0; 997 unsigned int dpte_row_height_l = 0; 998 unsigned int dpte_row_height_c = 0; 999 double hscale_pixel_rate_l = 0; 1000 double hscale_pixel_rate_c = 0; 1001 double min_hratio_fact_l = 0; 1002 double min_hratio_fact_c = 0; 1003 double refcyc_per_line_delivery_pre_l = 0; 1004 double refcyc_per_line_delivery_pre_c = 0; 1005 double refcyc_per_line_delivery_l = 0; 1006 double refcyc_per_line_delivery_c = 0; 1007 1008 double refcyc_per_req_delivery_pre_l = 0; 1009 double refcyc_per_req_delivery_pre_c = 0; 1010 double refcyc_per_req_delivery_l = 0; 1011 double refcyc_per_req_delivery_c = 0; 1012 1013 unsigned int full_recout_width = 0; 1014 double refcyc_per_req_delivery_pre_cur0 = 0; 1015 double refcyc_per_req_delivery_cur0 = 0; 1016 double refcyc_per_req_delivery_pre_cur1 = 0; 1017 double refcyc_per_req_delivery_cur1 = 0; 1018 1019 unsigned int pipe_index_in_combine[DC__NUM_PIPES__MAX] = { 0 }; 1020 1021 memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs)); 1022 memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs)); 1023 1024 dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en); 1025 dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en); 1026 dml_print("DML_DLG: %s: vm_en = %d\n", __func__, vm_en); 1027 dml_print("DML_DLG: %s: ignore_viewport_pos = %d\n", __func__, ignore_viewport_pos); 1028 dml_print("DML_DLG: %s: immediate_flip_support = %d\n", __func__, immediate_flip_support); 1029 1030 dml_print("DML_DLG: %s: dppclk_freq_in_mhz = %3.2f\n", __func__, dppclk_freq_in_mhz); 1031 dml_print("DML_DLG: %s: dispclk_freq_in_mhz = %3.2f\n", __func__, dispclk_freq_in_mhz); 1032 dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz); 1033 dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz); 1034 dml_print("DML_DLG: %s: interlaced = %d\n", __func__, interlaced); 1035 ASSERT(ref_freq_to_pix_freq < 4.0); 1036 1037 disp_dlg_regs->ref_freq_to_pix_freq = 1038 (unsigned int)(ref_freq_to_pix_freq * dml_pow(2, 19)); 1039 disp_dlg_regs->refcyc_per_htotal = (unsigned int)(ref_freq_to_pix_freq * (double)htotal 1040 * dml_pow(2, 8)); 1041 disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits 1042 1043 min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; 1044 t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes); 1045 min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1046 1047 min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double)htotal; 1048 dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start; 1049 1050 disp_dlg_regs->min_dst_y_next_start = (unsigned int)(((double)dlg_vblank_start 1051 ) * dml_pow(2, 2)); 1052 ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int)dml_pow(2, 18)); 1053 1054 dml_print("DML_DLG: %s: min_dcfclk_mhz = %3.2f\n", 1055 __func__, 1056 min_dcfclk_mhz); 1057 dml_print("DML_DLG: %s: min_ttu_vblank = %3.2f\n", 1058 __func__, 1059 min_ttu_vblank); 1060 dml_print("DML_DLG: %s: min_dst_y_ttu_vblank = %3.2f\n", 1061 __func__, 1062 min_dst_y_ttu_vblank); 1063 dml_print("DML_DLG: %s: t_calc_us = %3.2f\n", 1064 __func__, 1065 t_calc_us); 1066 dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x\n", 1067 __func__, 1068 disp_dlg_regs->min_dst_y_next_start); 1069 dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", 1070 __func__, 1071 ref_freq_to_pix_freq); 1072 1073 // ------------------------- 1074 // Section 1.15.2.2: Prefetch, Active and TTU 1075 // ------------------------- 1076 // Prefetch Calc 1077 // Source 1078 // dcc_en = src.dcc; 1079 dual_plane = is_dual_plane((enum source_format_class)(src->source_format)); 1080 access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed 1081 vp_height_l = src->viewport_height; 1082 vp_width_l = src->viewport_width; 1083 vp_height_c = src->viewport_height_c; 1084 vp_width_c = src->viewport_width_c; 1085 1086 // Scaling 1087 htaps_l = taps->htaps; 1088 htaps_c = taps->htaps_c; 1089 hratio_l = scl->hscl_ratio; 1090 hratio_c = scl->hscl_ratio_c; 1091 vratio_l = scl->vscl_ratio; 1092 vratio_c = scl->vscl_ratio_c; 1093 scl_enable = scl->scl_enable; 1094 1095 line_time_in_us = (htotal / pclk_freq_in_mhz); 1096 swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; 1097 dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; 1098 swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; 1099 dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; 1100 1101 meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; 1102 meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; 1103 vupdate_offset = dst->vupdate_offset; 1104 vupdate_width = dst->vupdate_width; 1105 vready_offset = dst->vready_offset; 1106 1107 dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; 1108 dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; 1109 1110 if (scl_enable) 1111 dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl; 1112 else 1113 dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only; 1114 1115 dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter 1116 + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor; 1117 1118 if (dout->dsc_enable) { 1119 double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1120 1121 dispclk_delay_subtotal += dsc_delay; 1122 } 1123 1124 pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz 1125 + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; 1126 1127 vstartup_start = dst->vstartup_start; 1128 if (interlaced) { 1129 if (vstartup_start / 2.0 1130 - (double)(vready_offset + vupdate_width + vupdate_offset) / htotal 1131 <= vblank_end / 2.0) 1132 disp_dlg_regs->vready_after_vcount0 = 1; 1133 else 1134 disp_dlg_regs->vready_after_vcount0 = 0; 1135 } else { 1136 if (vstartup_start 1137 - (double)(vready_offset + vupdate_width + vupdate_offset) / htotal 1138 <= vblank_end) 1139 disp_dlg_regs->vready_after_vcount0 = 1; 1140 else 1141 disp_dlg_regs->vready_after_vcount0 = 0; 1142 } 1143 1144 // TODO: Where is this coming from? 1145 if (interlaced) 1146 vstartup_start = vstartup_start / 2; 1147 1148 // TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp? 1149 if (vstartup_start >= min_vblank) { 1150 dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n", 1151 __func__, 1152 vblank_start, 1153 vblank_end); 1154 dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n", 1155 __func__, 1156 vstartup_start, 1157 min_vblank); 1158 min_vblank = vstartup_start + 1; 1159 dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n", 1160 __func__, 1161 vstartup_start, 1162 min_vblank); 1163 } 1164 1165 dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1166 dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1167 if (dst_y_after_scaler < 0) 1168 dst_y_after_scaler = 0; 1169 1170 // do some adjustment on the dst_after scaler to account for odm combine mode 1171 dml_print("DML_DLG: %s: input dst_x_after_scaler = %d\n", 1172 __func__, 1173 dst_x_after_scaler); 1174 dml_print("DML_DLG: %s: input dst_y_after_scaler = %d\n", 1175 __func__, 1176 dst_y_after_scaler); 1177 1178 // need to figure out which side of odm combine we're in 1179 if (dst->odm_combine) { 1180 // figure out which pipes go together 1181 bool visited[DC__NUM_PIPES__MAX] = { false }; 1182 unsigned int i, j, k; 1183 1184 for (k = 0; k < num_pipes; ++k) { 1185 visited[k] = false; 1186 pipe_index_in_combine[k] = 0; 1187 } 1188 1189 for (i = 0; i < num_pipes; i++) { 1190 if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) { 1191 1192 unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp; 1193 unsigned int grp_idx = 0; 1194 1195 for (j = i; j < num_pipes; j++) { 1196 if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp 1197 && e2e_pipe_param[j].pipe.src.is_hsplit && !visited[j]) { 1198 pipe_index_in_combine[j] = grp_idx; 1199 dml_print("DML_DLG: %s: pipe[%d] is in grp %d idx %d\n", __func__, j, grp, grp_idx); 1200 grp_idx++; 1201 visited[j] = true; 1202 } 1203 } 1204 } 1205 } 1206 1207 } 1208 1209 if (dst->odm_combine == dm_odm_combine_mode_disabled) { 1210 disp_dlg_regs->refcyc_h_blank_end = (unsigned int)((double) hblank_end * ref_freq_to_pix_freq); 1211 } else { 1212 unsigned int odm_combine_factor = (dst->odm_combine == dm_odm_combine_mode_2to1 ? 2 : 4); // TODO: We should really check that 4to1 is supported before setting it to 4 1213 unsigned int odm_pipe_index = pipe_index_in_combine[pipe_idx]; 1214 disp_dlg_regs->refcyc_h_blank_end = (unsigned int)(((double) hblank_end + odm_pipe_index * (double) dst->hactive / odm_combine_factor) * ref_freq_to_pix_freq); 1215 } 1216 ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int)dml_pow(2, 13)); 1217 1218 dml_print("DML_DLG: %s: htotal = %d\n", __func__, htotal); 1219 dml_print("DML_DLG: %s: pixel_rate_delay_subtotal = %d\n", 1220 __func__, 1221 pixel_rate_delay_subtotal); 1222 dml_print("DML_DLG: %s: dst_x_after_scaler[%d] = %d\n", 1223 __func__, 1224 pipe_idx, 1225 dst_x_after_scaler); 1226 dml_print("DML_DLG: %s: dst_y_after_scaler[%d] = %d\n", 1227 __func__, 1228 pipe_idx, 1229 dst_y_after_scaler); 1230 1231 // Lwait 1232 // TODO: Should this be urgent_latency_pixel_mixed_with_vm_data_us? 1233 line_wait = mode_lib->soc.urgent_latency_pixel_data_only_us; 1234 if (cstate_en) 1235 line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); 1236 if (pstate_en) 1237 line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us 1238 + mode_lib->soc.urgent_latency_pixel_data_only_us, // TODO: Should this be urgent_latency_pixel_mixed_with_vm_data_us? 1239 line_wait); 1240 line_wait = line_wait / line_time_in_us; 1241 1242 dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1243 dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch); 1244 1245 dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib, 1246 e2e_pipe_param, 1247 num_pipes, 1248 pipe_idx); 1249 dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib, 1250 e2e_pipe_param, 1251 num_pipes, 1252 pipe_idx); 1253 dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1254 dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1255 1256 max_dst_y_per_vm_vblank = 32.0; //U5.2 1257 max_dst_y_per_row_vblank = 16.0; //U4.2 1258 1259 // magic! 1260 if (htotal <= 75) { 1261 min_vblank = 300; 1262 max_dst_y_per_vm_vblank = 100.0; 1263 max_dst_y_per_row_vblank = 100.0; 1264 } 1265 1266 dml_print("DML_DLG: %s: dst_y_per_vm_flip = %3.2f\n", __func__, dst_y_per_vm_flip); 1267 dml_print("DML_DLG: %s: dst_y_per_row_flip = %3.2f\n", __func__, dst_y_per_row_flip); 1268 dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank); 1269 dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank); 1270 1271 ASSERT(dst_y_per_vm_vblank < max_dst_y_per_vm_vblank); 1272 ASSERT(dst_y_per_row_vblank < max_dst_y_per_row_vblank); 1273 1274 ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank)); 1275 lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank); 1276 1277 dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw); 1278 1279 vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1280 vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); 1281 1282 dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l); 1283 dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c); 1284 1285 // Active 1286 req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; 1287 req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; 1288 meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; 1289 meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; 1290 swath_width_pixels_ub_l = 0; 1291 swath_width_pixels_ub_c = 0; 1292 scaler_rec_in_width_l = 0; 1293 scaler_rec_in_width_c = 0; 1294 dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; 1295 dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; 1296 1297 swath_width_pixels_ub_l = swath_width_ub_l; 1298 swath_width_pixels_ub_c = swath_width_ub_c; 1299 1300 if (hratio_l <= 1) 1301 min_hratio_fact_l = 2.0; 1302 else if (htaps_l <= 6) { 1303 if ((hratio_l * 2.0) > 4.0) 1304 min_hratio_fact_l = 4.0; 1305 else 1306 min_hratio_fact_l = hratio_l * 2.0; 1307 } else { 1308 if (hratio_l > 4.0) 1309 min_hratio_fact_l = 4.0; 1310 else 1311 min_hratio_fact_l = hratio_l; 1312 } 1313 1314 hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; 1315 1316 if (hratio_c <= 1) 1317 min_hratio_fact_c = 2.0; 1318 else if (htaps_c <= 6) { 1319 if ((hratio_c * 2.0) > 4.0) 1320 min_hratio_fact_c = 4.0; 1321 else 1322 min_hratio_fact_c = hratio_c * 2.0; 1323 } else { 1324 if (hratio_c > 4.0) 1325 min_hratio_fact_c = 4.0; 1326 else 1327 min_hratio_fact_c = hratio_c; 1328 } 1329 1330 hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz; 1331 1332 refcyc_per_line_delivery_pre_l = 0.; 1333 refcyc_per_line_delivery_pre_c = 0.; 1334 refcyc_per_line_delivery_l = 0.; 1335 refcyc_per_line_delivery_c = 0.; 1336 1337 refcyc_per_req_delivery_pre_l = 0.; 1338 refcyc_per_req_delivery_pre_c = 0.; 1339 refcyc_per_req_delivery_l = 0.; 1340 refcyc_per_req_delivery_c = 0.; 1341 1342 full_recout_width = 0; 1343 // In ODM 1344 if (src->is_hsplit) { 1345 // This "hack" is only allowed (and valid) for MPC combine. In ODM 1346 // combine, you MUST specify the full_recout_width...according to Oswin 1347 if (dst->full_recout_width == 0 && !dst->odm_combine) { 1348 dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n", 1349 __func__); 1350 full_recout_width = dst->recout_width * 2; // assume half split for dcn1 1351 } else 1352 full_recout_width = dst->full_recout_width; 1353 } else 1354 full_recout_width = dst->recout_width; 1355 1356 // As of DCN2, mpc_combine and odm_combine are mutually exclusive 1357 refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib, 1358 refclk_freq_in_mhz, 1359 pclk_freq_in_mhz, 1360 dst->odm_combine, 1361 full_recout_width, 1362 dst->hactive, 1363 vratio_pre_l, 1364 hscale_pixel_rate_l, 1365 swath_width_pixels_ub_l, 1366 1); // per line 1367 1368 refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib, 1369 refclk_freq_in_mhz, 1370 pclk_freq_in_mhz, 1371 dst->odm_combine, 1372 full_recout_width, 1373 dst->hactive, 1374 vratio_l, 1375 hscale_pixel_rate_l, 1376 swath_width_pixels_ub_l, 1377 1); // per line 1378 1379 dml_print("DML_DLG: %s: full_recout_width = %d\n", 1380 __func__, 1381 full_recout_width); 1382 dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n", 1383 __func__, 1384 hscale_pixel_rate_l); 1385 dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", 1386 __func__, 1387 refcyc_per_line_delivery_pre_l); 1388 dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n", 1389 __func__, 1390 refcyc_per_line_delivery_l); 1391 1392 if (dual_plane) { 1393 refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib, 1394 refclk_freq_in_mhz, 1395 pclk_freq_in_mhz, 1396 dst->odm_combine, 1397 full_recout_width, 1398 dst->hactive, 1399 vratio_pre_c, 1400 hscale_pixel_rate_c, 1401 swath_width_pixels_ub_c, 1402 1); // per line 1403 1404 refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib, 1405 refclk_freq_in_mhz, 1406 pclk_freq_in_mhz, 1407 dst->odm_combine, 1408 full_recout_width, 1409 dst->hactive, 1410 vratio_c, 1411 hscale_pixel_rate_c, 1412 swath_width_pixels_ub_c, 1413 1); // per line 1414 1415 dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n", 1416 __func__, 1417 refcyc_per_line_delivery_pre_c); 1418 dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n", 1419 __func__, 1420 refcyc_per_line_delivery_c); 1421 } 1422 1423 // smehta: this is a hack added until we get the real dml, sorry, need to make progress 1424 if (src->dynamic_metadata_enable && src->gpuvm) { 1425 unsigned int levels = mode_lib->ip.gpuvm_max_page_table_levels; 1426 double ref_cycles; 1427 1428 if (src->hostvm) 1429 levels = levels * (mode_lib->ip.hostvm_max_page_table_levels+1); 1430 1431 ref_cycles = (levels * mode_lib->soc.urgent_latency_vm_data_only_us) * refclk_freq_in_mhz; 1432 dml_print("BENyamin: dst_y_prefetch = %f %d %f %f \n", 1433 ref_cycles, levels, mode_lib->soc.urgent_latency_vm_data_only_us, refclk_freq_in_mhz); 1434 disp_dlg_regs->refcyc_per_vm_dmdata = (unsigned int) ref_cycles; 1435 } 1436 dml_print("BENyamin: dmdta_en vm = %d %d \n", 1437 src->dynamic_metadata_enable, src->vm); 1438 // TTU - Luma / Chroma 1439 if (access_dir) { // vertical access 1440 scaler_rec_in_width_l = vp_height_l; 1441 scaler_rec_in_width_c = vp_height_c; 1442 } else { 1443 scaler_rec_in_width_l = vp_width_l; 1444 scaler_rec_in_width_c = vp_width_c; 1445 } 1446 1447 refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib, 1448 refclk_freq_in_mhz, 1449 pclk_freq_in_mhz, 1450 dst->odm_combine, 1451 full_recout_width, 1452 dst->hactive, 1453 vratio_pre_l, 1454 hscale_pixel_rate_l, 1455 scaler_rec_in_width_l, 1456 req_per_swath_ub_l); // per req 1457 refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib, 1458 refclk_freq_in_mhz, 1459 pclk_freq_in_mhz, 1460 dst->odm_combine, 1461 full_recout_width, 1462 dst->hactive, 1463 vratio_l, 1464 hscale_pixel_rate_l, 1465 scaler_rec_in_width_l, 1466 req_per_swath_ub_l); // per req 1467 1468 dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", 1469 __func__, 1470 refcyc_per_req_delivery_pre_l); 1471 dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n", 1472 __func__, 1473 refcyc_per_req_delivery_l); 1474 1475 ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); 1476 ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13)); 1477 1478 if (dual_plane) { 1479 refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib, 1480 refclk_freq_in_mhz, 1481 pclk_freq_in_mhz, 1482 dst->odm_combine, 1483 full_recout_width, 1484 dst->hactive, 1485 vratio_pre_c, 1486 hscale_pixel_rate_c, 1487 scaler_rec_in_width_c, 1488 req_per_swath_ub_c); // per req 1489 refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib, 1490 refclk_freq_in_mhz, 1491 pclk_freq_in_mhz, 1492 dst->odm_combine, 1493 full_recout_width, 1494 dst->hactive, 1495 vratio_c, 1496 hscale_pixel_rate_c, 1497 scaler_rec_in_width_c, 1498 req_per_swath_ub_c); // per req 1499 1500 dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n", 1501 __func__, 1502 refcyc_per_req_delivery_pre_c); 1503 dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n", 1504 __func__, 1505 refcyc_per_req_delivery_c); 1506 1507 ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); 1508 ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13)); 1509 } 1510 1511 // TTU - Cursor 1512 refcyc_per_req_delivery_pre_cur0 = 0.0; 1513 refcyc_per_req_delivery_cur0 = 0.0; 1514 if (src->num_cursors > 0) { 1515 calculate_ttu_cursor(mode_lib, 1516 &refcyc_per_req_delivery_pre_cur0, 1517 &refcyc_per_req_delivery_cur0, 1518 refclk_freq_in_mhz, 1519 ref_freq_to_pix_freq, 1520 hscale_pixel_rate_l, 1521 scl->hscl_ratio, 1522 vratio_pre_l, 1523 vratio_l, 1524 src->cur0_src_width, 1525 (enum cursor_bpp)(src->cur0_bpp)); 1526 } 1527 1528 refcyc_per_req_delivery_pre_cur1 = 0.0; 1529 refcyc_per_req_delivery_cur1 = 0.0; 1530 if (src->num_cursors > 1) { 1531 calculate_ttu_cursor(mode_lib, 1532 &refcyc_per_req_delivery_pre_cur1, 1533 &refcyc_per_req_delivery_cur1, 1534 refclk_freq_in_mhz, 1535 ref_freq_to_pix_freq, 1536 hscale_pixel_rate_l, 1537 scl->hscl_ratio, 1538 vratio_pre_l, 1539 vratio_l, 1540 src->cur1_src_width, 1541 (enum cursor_bpp)(src->cur1_bpp)); 1542 } 1543 1544 // TTU - Misc 1545 // all hard-coded 1546 1547 // Assignment to register structures 1548 disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line 1549 ASSERT(disp_dlg_regs->dst_y_after_scaler < (unsigned int)8); 1550 disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk 1551 ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int)dml_pow(2, 13)); 1552 disp_dlg_regs->dst_y_prefetch = (unsigned int)(dst_y_prefetch * dml_pow(2, 2)); 1553 disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int)(dst_y_per_vm_vblank * dml_pow(2, 2)); 1554 disp_dlg_regs->dst_y_per_row_vblank = (unsigned int)(dst_y_per_row_vblank * dml_pow(2, 2)); 1555 disp_dlg_regs->dst_y_per_vm_flip = (unsigned int)(dst_y_per_vm_flip * dml_pow(2, 2)); 1556 disp_dlg_regs->dst_y_per_row_flip = (unsigned int)(dst_y_per_row_flip * dml_pow(2, 2)); 1557 1558 disp_dlg_regs->vratio_prefetch = (unsigned int)(vratio_pre_l * dml_pow(2, 19)); 1559 disp_dlg_regs->vratio_prefetch_c = (unsigned int)(vratio_pre_c * dml_pow(2, 19)); 1560 1561 dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_vblank); 1562 dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_vblank); 1563 dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_flip = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_flip); 1564 dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_flip = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_flip); 1565 1566 disp_dlg_regs->refcyc_per_pte_group_vblank_l = 1567 (unsigned int)(dst_y_per_row_vblank * (double)htotal 1568 * ref_freq_to_pix_freq / (double)dpte_groups_per_row_ub_l); 1569 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int)dml_pow(2, 13)); 1570 1571 if (dual_plane) { 1572 disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int)(dst_y_per_row_vblank 1573 * (double)htotal * ref_freq_to_pix_freq 1574 / (double)dpte_groups_per_row_ub_c); 1575 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c 1576 < (unsigned int)dml_pow(2, 13)); 1577 } 1578 1579 disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = 1580 (unsigned int)(dst_y_per_row_vblank * (double)htotal 1581 * ref_freq_to_pix_freq / (double)meta_chunks_per_row_ub_l); 1582 ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int)dml_pow(2, 13)); 1583 1584 disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = 1585 disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now 1586 1587 disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int)(dst_y_per_row_flip * htotal 1588 * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l; 1589 disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int)(dst_y_per_row_flip * htotal 1590 * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l; 1591 1592 if (dual_plane) { 1593 disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int)(dst_y_per_row_flip 1594 * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c; 1595 disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int)(dst_y_per_row_flip 1596 * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c; 1597 } 1598 1599 disp_dlg_regs->refcyc_per_vm_group_vblank = get_refcyc_per_vm_group_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; 1600 disp_dlg_regs->refcyc_per_vm_group_flip = get_refcyc_per_vm_group_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; 1601 disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10); 1602 disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10); 1603 1604 // Clamp to max for now 1605 if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int)dml_pow(2, 23)) 1606 disp_dlg_regs->refcyc_per_vm_group_vblank = dml_pow(2, 23) - 1; 1607 1608 if (disp_dlg_regs->refcyc_per_vm_group_flip >= (unsigned int)dml_pow(2, 23)) 1609 disp_dlg_regs->refcyc_per_vm_group_flip = dml_pow(2, 23) - 1; 1610 1611 if (disp_dlg_regs->refcyc_per_vm_req_vblank >= (unsigned int)dml_pow(2, 23)) 1612 disp_dlg_regs->refcyc_per_vm_req_vblank = dml_pow(2, 23) - 1; 1613 1614 if (disp_dlg_regs->refcyc_per_vm_req_flip >= (unsigned int)dml_pow(2, 23)) 1615 disp_dlg_regs->refcyc_per_vm_req_flip = dml_pow(2, 23) - 1; 1616 1617 disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int)((double)dpte_row_height_l 1618 / (double)vratio_l * dml_pow(2, 2)); 1619 ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int)dml_pow(2, 17)); 1620 1621 if (dual_plane) { 1622 disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int)((double)dpte_row_height_c 1623 / (double)vratio_c * dml_pow(2, 2)); 1624 if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int)dml_pow(2, 17)) { 1625 dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n", 1626 __func__, 1627 disp_dlg_regs->dst_y_per_pte_row_nom_c, 1628 (unsigned int)dml_pow(2, 17) - 1); 1629 } 1630 } 1631 1632 disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int)((double)meta_row_height_l 1633 / (double)vratio_l * dml_pow(2, 2)); 1634 ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int)dml_pow(2, 17)); 1635 1636 disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now 1637 1638 dml_print("DML: Trow: %fus\n", line_time_in_us * (double)dpte_row_height_l / (double)vratio_l); 1639 1640 disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)((double)dpte_row_height_l 1641 / (double)vratio_l * (double)htotal * ref_freq_to_pix_freq 1642 / (double)dpte_groups_per_row_ub_l); 1643 if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int)dml_pow(2, 23)) 1644 disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; 1645 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int)((double)meta_row_height_l 1646 / (double)vratio_l * (double)htotal * ref_freq_to_pix_freq 1647 / (double)meta_chunks_per_row_ub_l); 1648 if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int)dml_pow(2, 23)) 1649 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; 1650 1651 if (dual_plane) { 1652 disp_dlg_regs->refcyc_per_pte_group_nom_c = 1653 (unsigned int)((double)dpte_row_height_c / (double)vratio_c 1654 * (double)htotal * ref_freq_to_pix_freq 1655 / (double)dpte_groups_per_row_ub_c); 1656 if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int)dml_pow(2, 23)) 1657 disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; 1658 1659 // TODO: Is this the right calculation? Does htotal need to be halved? 1660 disp_dlg_regs->refcyc_per_meta_chunk_nom_c = 1661 (unsigned int)((double)meta_row_height_c / (double)vratio_c 1662 * (double)htotal * ref_freq_to_pix_freq 1663 / (double)meta_chunks_per_row_ub_c); 1664 if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int)dml_pow(2, 23)) 1665 disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1; 1666 } 1667 1668 disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int)dml_floor(refcyc_per_line_delivery_pre_l, 1669 1); 1670 disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int)dml_floor(refcyc_per_line_delivery_l, 1671 1); 1672 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int)dml_pow(2, 13)); 1673 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int)dml_pow(2, 13)); 1674 1675 disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int)dml_floor(refcyc_per_line_delivery_pre_c, 1676 1); 1677 disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int)dml_floor(refcyc_per_line_delivery_c, 1678 1); 1679 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int)dml_pow(2, 13)); 1680 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int)dml_pow(2, 13)); 1681 1682 disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; 1683 disp_dlg_regs->dst_y_offset_cur0 = 0; 1684 disp_dlg_regs->chunk_hdl_adjust_cur1 = 3; 1685 disp_dlg_regs->dst_y_offset_cur1 = 0; 1686 1687 disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off 1688 1689 disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int)(refcyc_per_req_delivery_pre_l 1690 * dml_pow(2, 10)); 1691 disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int)(refcyc_per_req_delivery_l 1692 * dml_pow(2, 10)); 1693 disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int)(refcyc_per_req_delivery_pre_c 1694 * dml_pow(2, 10)); 1695 disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int)(refcyc_per_req_delivery_c 1696 * dml_pow(2, 10)); 1697 disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 1698 (unsigned int)(refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); 1699 disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int)(refcyc_per_req_delivery_cur0 1700 * dml_pow(2, 10)); 1701 disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 = 1702 (unsigned int)(refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10)); 1703 disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int)(refcyc_per_req_delivery_cur1 1704 * dml_pow(2, 10)); 1705 disp_ttu_regs->qos_level_low_wm = 0; 1706 ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14)); 1707 disp_ttu_regs->qos_level_high_wm = (unsigned int)(4.0 * (double)htotal 1708 * ref_freq_to_pix_freq); 1709 ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14)); 1710 1711 disp_ttu_regs->qos_level_flip = 14; 1712 disp_ttu_regs->qos_level_fixed_l = 8; 1713 disp_ttu_regs->qos_level_fixed_c = 8; 1714 disp_ttu_regs->qos_level_fixed_cur0 = 8; 1715 disp_ttu_regs->qos_ramp_disable_l = 0; 1716 disp_ttu_regs->qos_ramp_disable_c = 0; 1717 disp_ttu_regs->qos_ramp_disable_cur0 = 0; 1718 1719 disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; 1720 ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); 1721 1722 print__ttu_regs_st(mode_lib, disp_ttu_regs); 1723 print__dlg_regs_st(mode_lib, disp_dlg_regs); 1724} 1725 1726void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, 1727 display_dlg_regs_st *dlg_regs, 1728 display_ttu_regs_st *ttu_regs, 1729 const display_e2e_pipe_params_st *e2e_pipe_param, 1730 const unsigned int num_pipes, 1731 const unsigned int pipe_idx, 1732 const bool cstate_en, 1733 const bool pstate_en, 1734 const bool vm_en, 1735 const bool ignore_viewport_pos, 1736 const bool immediate_flip_support) 1737{ 1738 display_rq_params_st rq_param = { 0 }; 1739 display_dlg_sys_params_st dlg_sys_param = { 0 }; 1740 1741 // Get watermark and Tex. 1742 dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes); 1743 dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib, 1744 e2e_pipe_param, 1745 num_pipes); 1746 dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes); 1747 dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes); 1748 dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes); 1749 dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes); 1750 dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib, 1751 e2e_pipe_param, 1752 num_pipes); 1753 dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, 1754 e2e_pipe_param, 1755 num_pipes); 1756 1757 print__dlg_sys_params_st(mode_lib, &dlg_sys_param); 1758 1759 // system parameter calculation done 1760 1761 dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); 1762 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); 1763 dml_rq_dlg_get_dlg_params(mode_lib, 1764 e2e_pipe_param, 1765 num_pipes, 1766 pipe_idx, 1767 dlg_regs, 1768 ttu_regs, 1769 rq_param.dlg, 1770 dlg_sys_param, 1771 cstate_en, 1772 pstate_en, 1773 vm_en, 1774 ignore_viewport_pos, 1775 immediate_flip_support); 1776 dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); 1777} 1778
~/
Read-only file preview.