FILE
dce110_mem_input_v.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
1/* 2 * Copyright 2012-16 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#include "dm_services.h" 26 27#include "dce/dce_11_0_d.h" 28#include "dce/dce_11_0_sh_mask.h" 29/* TODO: this needs to be looked at, used by Stella's workaround*/ 30#include "gmc/gmc_8_2_d.h" 31#include "gmc/gmc_8_2_sh_mask.h" 32 33#include "include/logger_interface.h" 34#include "inc/dce_calcs.h" 35 36#include "dce/dce_mem_input.h" 37#include "dce110_mem_input_v.h" 38 39static void set_flip_control( 40 struct dce_mem_input *mem_input110, 41 bool immediate) 42{ 43 uint32_t value = 0; 44 45 value = dm_read_reg( 46 mem_input110->base.ctx, 47 mmUNP_FLIP_CONTROL); 48 49 set_reg_field_value(value, 1, 50 UNP_FLIP_CONTROL, 51 GRPH_SURFACE_UPDATE_PENDING_MODE); 52 53 dm_write_reg( 54 mem_input110->base.ctx, 55 mmUNP_FLIP_CONTROL, 56 value); 57} 58 59/* chroma part */ 60static void program_pri_addr_c( 61 struct dce_mem_input *mem_input110, 62 PHYSICAL_ADDRESS_LOC address) 63{ 64 uint32_t value = 0; 65 uint32_t temp = 0; 66 /*high register MUST be programmed first*/ 67 temp = address.high_part & 68UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK; 69 70 set_reg_field_value(value, temp, 71 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 72 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C); 73 74 dm_write_reg( 75 mem_input110->base.ctx, 76 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 77 value); 78 79 value = 0; 80 temp = address.low_part >> 81 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT; 82 83 set_reg_field_value(value, temp, 84 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C, 85 GRPH_PRIMARY_SURFACE_ADDRESS_C); 86 87 dm_write_reg( 88 mem_input110->base.ctx, 89 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C, 90 value); 91} 92 93/* luma part */ 94static void program_pri_addr_l( 95 struct dce_mem_input *mem_input110, 96 PHYSICAL_ADDRESS_LOC address) 97{ 98 uint32_t value = 0; 99 uint32_t temp = 0; 100 101 /*high register MUST be programmed first*/ 102 temp = address.high_part & 103UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK; 104 105 set_reg_field_value(value, temp, 106 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L, 107 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L); 108 109 dm_write_reg( 110 mem_input110->base.ctx, 111 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L, 112 value); 113 114 value = 0; 115 temp = address.low_part >> 116 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT; 117 118 set_reg_field_value(value, temp, 119 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, 120 GRPH_PRIMARY_SURFACE_ADDRESS_L); 121 122 dm_write_reg( 123 mem_input110->base.ctx, 124 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, 125 value); 126} 127 128static void program_addr( 129 struct dce_mem_input *mem_input110, 130 const struct dc_plane_address *addr) 131{ 132 switch (addr->type) { 133 case PLN_ADDR_TYPE_GRAPHICS: 134 program_pri_addr_l( 135 mem_input110, 136 addr->grph.addr); 137 break; 138 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: 139 program_pri_addr_c( 140 mem_input110, 141 addr->video_progressive.chroma_addr); 142 program_pri_addr_l( 143 mem_input110, 144 addr->video_progressive.luma_addr); 145 break; 146 default: 147 /* not supported */ 148 BREAK_TO_DEBUGGER(); 149 } 150} 151 152static void enable(struct dce_mem_input *mem_input110) 153{ 154 uint32_t value = 0; 155 156 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE); 157 set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE); 158 dm_write_reg(mem_input110->base.ctx, 159 mmUNP_GRPH_ENABLE, 160 value); 161} 162 163static void program_tiling( 164 struct dce_mem_input *mem_input110, 165 const struct dc_tiling_info *info, 166 const enum surface_pixel_format pixel_format) 167{ 168 uint32_t value = 0; 169 170 set_reg_field_value(value, info->gfx8.num_banks, 171 UNP_GRPH_CONTROL, GRPH_NUM_BANKS); 172 173 set_reg_field_value(value, info->gfx8.bank_width, 174 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L); 175 176 set_reg_field_value(value, info->gfx8.bank_height, 177 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L); 178 179 set_reg_field_value(value, info->gfx8.tile_aspect, 180 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L); 181 182 set_reg_field_value(value, info->gfx8.tile_split, 183 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L); 184 185 set_reg_field_value(value, info->gfx8.tile_mode, 186 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L); 187 188 set_reg_field_value(value, info->gfx8.pipe_config, 189 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG); 190 191 set_reg_field_value(value, info->gfx8.array_mode, 192 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE); 193 194 set_reg_field_value(value, 1, 195 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE); 196 197 set_reg_field_value(value, 0, 198 UNP_GRPH_CONTROL, GRPH_Z); 199 200 dm_write_reg( 201 mem_input110->base.ctx, 202 mmUNP_GRPH_CONTROL, 203 value); 204 205 value = 0; 206 207 set_reg_field_value(value, info->gfx8.bank_width_c, 208 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C); 209 210 set_reg_field_value(value, info->gfx8.bank_height_c, 211 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C); 212 213 set_reg_field_value(value, info->gfx8.tile_aspect_c, 214 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C); 215 216 set_reg_field_value(value, info->gfx8.tile_split_c, 217 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C); 218 219 set_reg_field_value(value, info->gfx8.tile_mode_c, 220 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C); 221 222 dm_write_reg( 223 mem_input110->base.ctx, 224 mmUNP_GRPH_CONTROL_C, 225 value); 226} 227 228static void program_size_and_rotation( 229 struct dce_mem_input *mem_input110, 230 enum dc_rotation_angle rotation, 231 const struct plane_size *plane_size) 232{ 233 uint32_t value = 0; 234 struct plane_size local_size = *plane_size; 235 236 if (rotation == ROTATION_ANGLE_90 || 237 rotation == ROTATION_ANGLE_270) { 238 239 swap(local_size.surface_size.x, 240 local_size.surface_size.y); 241 swap(local_size.surface_size.width, 242 local_size.surface_size.height); 243 swap(local_size.chroma_size.x, 244 local_size.chroma_size.y); 245 swap(local_size.chroma_size.width, 246 local_size.chroma_size.height); 247 } 248 249 value = 0; 250 set_reg_field_value(value, local_size.surface_pitch, 251 UNP_GRPH_PITCH_L, GRPH_PITCH_L); 252 253 dm_write_reg( 254 mem_input110->base.ctx, 255 mmUNP_GRPH_PITCH_L, 256 value); 257 258 value = 0; 259 set_reg_field_value(value, local_size.chroma_pitch, 260 UNP_GRPH_PITCH_C, GRPH_PITCH_C); 261 dm_write_reg( 262 mem_input110->base.ctx, 263 mmUNP_GRPH_PITCH_C, 264 value); 265 266 value = 0; 267 set_reg_field_value(value, 0, 268 UNP_GRPH_X_START_L, GRPH_X_START_L); 269 dm_write_reg( 270 mem_input110->base.ctx, 271 mmUNP_GRPH_X_START_L, 272 value); 273 274 value = 0; 275 set_reg_field_value(value, 0, 276 UNP_GRPH_X_START_C, GRPH_X_START_C); 277 dm_write_reg( 278 mem_input110->base.ctx, 279 mmUNP_GRPH_X_START_C, 280 value); 281 282 value = 0; 283 set_reg_field_value(value, 0, 284 UNP_GRPH_Y_START_L, GRPH_Y_START_L); 285 dm_write_reg( 286 mem_input110->base.ctx, 287 mmUNP_GRPH_Y_START_L, 288 value); 289 290 value = 0; 291 set_reg_field_value(value, 0, 292 UNP_GRPH_Y_START_C, GRPH_Y_START_C); 293 dm_write_reg( 294 mem_input110->base.ctx, 295 mmUNP_GRPH_Y_START_C, 296 value); 297 298 value = 0; 299 set_reg_field_value(value, local_size.surface_size.x + 300 local_size.surface_size.width, 301 UNP_GRPH_X_END_L, GRPH_X_END_L); 302 dm_write_reg( 303 mem_input110->base.ctx, 304 mmUNP_GRPH_X_END_L, 305 value); 306 307 value = 0; 308 set_reg_field_value(value, local_size.chroma_size.x + 309 local_size.chroma_size.width, 310 UNP_GRPH_X_END_C, GRPH_X_END_C); 311 dm_write_reg( 312 mem_input110->base.ctx, 313 mmUNP_GRPH_X_END_C, 314 value); 315 316 value = 0; 317 set_reg_field_value(value, local_size.surface_size.y + 318 local_size.surface_size.height, 319 UNP_GRPH_Y_END_L, GRPH_Y_END_L); 320 dm_write_reg( 321 mem_input110->base.ctx, 322 mmUNP_GRPH_Y_END_L, 323 value); 324 325 value = 0; 326 set_reg_field_value(value, local_size.chroma_size.y + 327 local_size.chroma_size.height, 328 UNP_GRPH_Y_END_C, GRPH_Y_END_C); 329 dm_write_reg( 330 mem_input110->base.ctx, 331 mmUNP_GRPH_Y_END_C, 332 value); 333 334 value = 0; 335 switch (rotation) { 336 case ROTATION_ANGLE_90: 337 set_reg_field_value(value, 3, 338 UNP_HW_ROTATION, ROTATION_ANGLE); 339 break; 340 case ROTATION_ANGLE_180: 341 set_reg_field_value(value, 2, 342 UNP_HW_ROTATION, ROTATION_ANGLE); 343 break; 344 case ROTATION_ANGLE_270: 345 set_reg_field_value(value, 1, 346 UNP_HW_ROTATION, ROTATION_ANGLE); 347 break; 348 default: 349 set_reg_field_value(value, 0, 350 UNP_HW_ROTATION, ROTATION_ANGLE); 351 break; 352 } 353 354 dm_write_reg( 355 mem_input110->base.ctx, 356 mmUNP_HW_ROTATION, 357 value); 358} 359 360static void program_pixel_format( 361 struct dce_mem_input *mem_input110, 362 enum surface_pixel_format format) 363{ 364 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { 365 uint32_t value; 366 uint8_t grph_depth; 367 uint8_t grph_format; 368 369 value = dm_read_reg( 370 mem_input110->base.ctx, 371 mmUNP_GRPH_CONTROL); 372 373 switch (format) { 374 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: 375 grph_depth = 0; 376 grph_format = 0; 377 break; 378 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 379 grph_depth = 1; 380 grph_format = 1; 381 break; 382 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 383 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 384 grph_depth = 2; 385 grph_format = 0; 386 break; 387 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 388 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 389 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: 390 grph_depth = 2; 391 grph_format = 1; 392 break; 393 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 394 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: 395 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 396 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 397 grph_depth = 3; 398 grph_format = 0; 399 break; 400 default: 401 grph_depth = 2; 402 grph_format = 0; 403 break; 404 } 405 406 set_reg_field_value( 407 value, 408 grph_depth, 409 UNP_GRPH_CONTROL, 410 GRPH_DEPTH); 411 set_reg_field_value( 412 value, 413 grph_format, 414 UNP_GRPH_CONTROL, 415 GRPH_FORMAT); 416 417 dm_write_reg( 418 mem_input110->base.ctx, 419 mmUNP_GRPH_CONTROL, 420 value); 421 422 value = dm_read_reg( 423 mem_input110->base.ctx, 424 mmUNP_GRPH_CONTROL_EXP); 425 426 /* VIDEO FORMAT 0 */ 427 set_reg_field_value( 428 value, 429 0, 430 UNP_GRPH_CONTROL_EXP, 431 VIDEO_FORMAT); 432 dm_write_reg( 433 mem_input110->base.ctx, 434 mmUNP_GRPH_CONTROL_EXP, 435 value); 436 437 } else { 438 /* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */ 439 uint32_t value; 440 uint8_t video_format; 441 442 value = dm_read_reg( 443 mem_input110->base.ctx, 444 mmUNP_GRPH_CONTROL_EXP); 445 446 switch (format) { 447 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 448 video_format = 2; 449 break; 450 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 451 video_format = 3; 452 break; 453 default: 454 video_format = 0; 455 break; 456 } 457 458 set_reg_field_value( 459 value, 460 video_format, 461 UNP_GRPH_CONTROL_EXP, 462 VIDEO_FORMAT); 463 464 dm_write_reg( 465 mem_input110->base.ctx, 466 mmUNP_GRPH_CONTROL_EXP, 467 value); 468 } 469} 470 471static bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input) 472{ 473 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 474 uint32_t value; 475 476 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE); 477 478 if (get_reg_field_value(value, UNP_GRPH_UPDATE, 479 GRPH_SURFACE_UPDATE_PENDING)) 480 return true; 481 482 mem_input->current_address = mem_input->request_address; 483 return false; 484} 485 486static bool dce_mem_input_v_program_surface_flip_and_addr( 487 struct mem_input *mem_input, 488 const struct dc_plane_address *address, 489 bool flip_immediate) 490{ 491 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 492 493 set_flip_control(mem_input110, flip_immediate); 494 program_addr(mem_input110, 495 address); 496 497 mem_input->request_address = *address; 498 499 return true; 500} 501 502/* Scatter Gather param tables */ 503static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = { 504 { 8, 64, 64, 8, 8, 1, 4, 0, 0}, 505 { 16, 64, 32, 8, 16, 1, 8, 0, 0}, 506 { 32, 32, 32, 16, 16, 1, 8, 0, 0}, 507 { 64, 8, 32, 16, 16, 1, 8, 0, 0}, /* fake */ 508}; 509 510static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = { 511 { 8, 512, 8, 1, 0, 1, 0, 0, 0}, /* 0 for invalid */ 512 { 16, 256, 8, 2, 0, 1, 0, 0, 0}, 513 { 32, 128, 8, 4, 0, 1, 0, 0, 0}, 514 { 64, 64, 8, 4, 0, 1, 0, 0, 0}, /* fake */ 515}; 516 517static const unsigned int dvmm_Hw_Setting_Linear[4][9] = { 518 { 8, 4096, 1, 8, 0, 1, 0, 0, 0}, 519 { 16, 2048, 1, 8, 0, 1, 0, 0, 0}, 520 { 32, 1024, 1, 8, 0, 1, 0, 0, 0}, 521 { 64, 512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */ 522}; 523 524/* Helper to get table entry from surface info */ 525static const unsigned int *get_dvmm_hw_setting( 526 struct dc_tiling_info *tiling_info, 527 enum surface_pixel_format format, 528 bool chroma) 529{ 530 enum bits_per_pixel { 531 bpp_8 = 0, 532 bpp_16, 533 bpp_32, 534 bpp_64 535 } bpp; 536 537 if (format >= SURFACE_PIXEL_FORMAT_INVALID) 538 bpp = bpp_32; 539 else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 540 bpp = chroma ? bpp_16 : bpp_8; 541 else 542 bpp = bpp_8; 543 544 switch (tiling_info->gfx8.array_mode) { 545 case DC_ARRAY_1D_TILED_THIN1: 546 case DC_ARRAY_1D_TILED_THICK: 547 case DC_ARRAY_PRT_TILED_THIN1: 548 return dvmm_Hw_Setting_1DTiling[bpp]; 549 case DC_ARRAY_2D_TILED_THIN1: 550 case DC_ARRAY_2D_TILED_THICK: 551 case DC_ARRAY_2D_TILED_X_THICK: 552 case DC_ARRAY_PRT_2D_TILED_THIN1: 553 case DC_ARRAY_PRT_2D_TILED_THICK: 554 return dvmm_Hw_Setting_2DTiling[bpp]; 555 case DC_ARRAY_LINEAR_GENERAL: 556 case DC_ARRAY_LINEAR_ALLIGNED: 557 return dvmm_Hw_Setting_Linear[bpp]; 558 default: 559 return dvmm_Hw_Setting_2DTiling[bpp]; 560 } 561} 562 563static void dce_mem_input_v_program_pte_vm( 564 struct mem_input *mem_input, 565 enum surface_pixel_format format, 566 struct dc_tiling_info *tiling_info, 567 enum dc_rotation_angle rotation) 568{ 569 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 570 const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false); 571 const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true); 572 573 unsigned int page_width = 0; 574 unsigned int page_height = 0; 575 unsigned int page_width_chroma = 0; 576 unsigned int page_height_chroma = 0; 577 unsigned int temp_page_width = pte[1]; 578 unsigned int temp_page_height = pte[2]; 579 unsigned int min_pte_before_flip = 0; 580 unsigned int min_pte_before_flip_chroma = 0; 581 uint32_t value = 0; 582 583 while ((temp_page_width >>= 1) != 0) 584 page_width++; 585 while ((temp_page_height >>= 1) != 0) 586 page_height++; 587 588 temp_page_width = pte_chroma[1]; 589 temp_page_height = pte_chroma[2]; 590 while ((temp_page_width >>= 1) != 0) 591 page_width_chroma++; 592 while ((temp_page_height >>= 1) != 0) 593 page_height_chroma++; 594 595 switch (rotation) { 596 case ROTATION_ANGLE_90: 597 case ROTATION_ANGLE_270: 598 min_pte_before_flip = pte[4]; 599 min_pte_before_flip_chroma = pte_chroma[4]; 600 break; 601 default: 602 min_pte_before_flip = pte[3]; 603 min_pte_before_flip_chroma = pte_chroma[3]; 604 break; 605 } 606 607 value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT); 608 /* TODO: un-hardcode requestlimit */ 609 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L); 610 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C); 611 dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value); 612 613 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL); 614 set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH); 615 set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT); 616 set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP); 617 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value); 618 619 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL); 620 set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK); 621 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING); 622 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value); 623 624 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C); 625 set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C); 626 set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C); 627 set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C); 628 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value); 629 630 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C); 631 set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C); 632 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C); 633 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value); 634} 635 636static void dce_mem_input_v_program_surface_config( 637 struct mem_input *mem_input, 638 enum surface_pixel_format format, 639 struct dc_tiling_info *tiling_info, 640 struct plane_size *plane_size, 641 enum dc_rotation_angle rotation, 642 struct dc_plane_dcc_param *dcc, 643 bool horizotal_mirror) 644{ 645 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 646 647 enable(mem_input110); 648 program_tiling(mem_input110, tiling_info, format); 649 program_size_and_rotation(mem_input110, rotation, plane_size); 650 program_pixel_format(mem_input110, format); 651} 652 653static void program_urgency_watermark( 654 const struct dc_context *ctx, 655 const uint32_t urgency_addr, 656 const uint32_t wm_addr, 657 struct dce_watermarks marks_low, 658 uint32_t total_dest_line_time_ns) 659{ 660 /* register value */ 661 uint32_t urgency_cntl = 0; 662 uint32_t wm_mask_cntl = 0; 663 664 /*Write mask to enable reading/writing of watermark set A*/ 665 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 666 set_reg_field_value(wm_mask_cntl, 667 1, 668 DPGV0_WATERMARK_MASK_CONTROL, 669 URGENCY_WATERMARK_MASK); 670 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 671 672 urgency_cntl = dm_read_reg(ctx, urgency_addr); 673 674 set_reg_field_value( 675 urgency_cntl, 676 marks_low.a_mark, 677 DPGV0_PIPE_URGENCY_CONTROL, 678 URGENCY_LOW_WATERMARK); 679 680 set_reg_field_value( 681 urgency_cntl, 682 total_dest_line_time_ns, 683 DPGV0_PIPE_URGENCY_CONTROL, 684 URGENCY_HIGH_WATERMARK); 685 dm_write_reg(ctx, urgency_addr, urgency_cntl); 686 687 /*Write mask to enable reading/writing of watermark set B*/ 688 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 689 set_reg_field_value(wm_mask_cntl, 690 2, 691 DPGV0_WATERMARK_MASK_CONTROL, 692 URGENCY_WATERMARK_MASK); 693 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 694 695 urgency_cntl = dm_read_reg(ctx, urgency_addr); 696 697 set_reg_field_value(urgency_cntl, 698 marks_low.b_mark, 699 DPGV0_PIPE_URGENCY_CONTROL, 700 URGENCY_LOW_WATERMARK); 701 702 set_reg_field_value(urgency_cntl, 703 total_dest_line_time_ns, 704 DPGV0_PIPE_URGENCY_CONTROL, 705 URGENCY_HIGH_WATERMARK); 706 707 dm_write_reg(ctx, urgency_addr, urgency_cntl); 708} 709 710static void program_urgency_watermark_l( 711 const struct dc_context *ctx, 712 struct dce_watermarks marks_low, 713 uint32_t total_dest_line_time_ns) 714{ 715 program_urgency_watermark( 716 ctx, 717 mmDPGV0_PIPE_URGENCY_CONTROL, 718 mmDPGV0_WATERMARK_MASK_CONTROL, 719 marks_low, 720 total_dest_line_time_ns); 721} 722 723static void program_urgency_watermark_c( 724 const struct dc_context *ctx, 725 struct dce_watermarks marks_low, 726 uint32_t total_dest_line_time_ns) 727{ 728 program_urgency_watermark( 729 ctx, 730 mmDPGV1_PIPE_URGENCY_CONTROL, 731 mmDPGV1_WATERMARK_MASK_CONTROL, 732 marks_low, 733 total_dest_line_time_ns); 734} 735 736static void program_stutter_watermark( 737 const struct dc_context *ctx, 738 const uint32_t stutter_addr, 739 const uint32_t wm_addr, 740 struct dce_watermarks marks) 741{ 742 /* register value */ 743 uint32_t stutter_cntl = 0; 744 uint32_t wm_mask_cntl = 0; 745 746 /*Write mask to enable reading/writing of watermark set A*/ 747 748 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 749 set_reg_field_value(wm_mask_cntl, 750 1, 751 DPGV0_WATERMARK_MASK_CONTROL, 752 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK); 753 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 754 755 stutter_cntl = dm_read_reg(ctx, stutter_addr); 756 757 if (ctx->dc->debug.disable_stutter) { 758 set_reg_field_value(stutter_cntl, 759 0, 760 DPGV0_PIPE_STUTTER_CONTROL, 761 STUTTER_ENABLE); 762 } else { 763 set_reg_field_value(stutter_cntl, 764 1, 765 DPGV0_PIPE_STUTTER_CONTROL, 766 STUTTER_ENABLE); 767 } 768 769 set_reg_field_value(stutter_cntl, 770 1, 771 DPGV0_PIPE_STUTTER_CONTROL, 772 STUTTER_IGNORE_FBC); 773 774 /*Write watermark set A*/ 775 set_reg_field_value(stutter_cntl, 776 marks.a_mark, 777 DPGV0_PIPE_STUTTER_CONTROL, 778 STUTTER_EXIT_SELF_REFRESH_WATERMARK); 779 dm_write_reg(ctx, stutter_addr, stutter_cntl); 780 781 /*Write mask to enable reading/writing of watermark set B*/ 782 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 783 set_reg_field_value(wm_mask_cntl, 784 2, 785 DPGV0_WATERMARK_MASK_CONTROL, 786 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK); 787 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 788 789 stutter_cntl = dm_read_reg(ctx, stutter_addr); 790 /*Write watermark set B*/ 791 set_reg_field_value(stutter_cntl, 792 marks.b_mark, 793 DPGV0_PIPE_STUTTER_CONTROL, 794 STUTTER_EXIT_SELF_REFRESH_WATERMARK); 795 dm_write_reg(ctx, stutter_addr, stutter_cntl); 796} 797 798static void program_stutter_watermark_l( 799 const struct dc_context *ctx, 800 struct dce_watermarks marks) 801{ 802 program_stutter_watermark(ctx, 803 mmDPGV0_PIPE_STUTTER_CONTROL, 804 mmDPGV0_WATERMARK_MASK_CONTROL, 805 marks); 806} 807 808static void program_stutter_watermark_c( 809 const struct dc_context *ctx, 810 struct dce_watermarks marks) 811{ 812 program_stutter_watermark(ctx, 813 mmDPGV1_PIPE_STUTTER_CONTROL, 814 mmDPGV1_WATERMARK_MASK_CONTROL, 815 marks); 816} 817 818static void program_nbp_watermark( 819 const struct dc_context *ctx, 820 const uint32_t wm_mask_ctrl_addr, 821 const uint32_t nbp_pstate_ctrl_addr, 822 struct dce_watermarks marks) 823{ 824 uint32_t value; 825 826 /* Write mask to enable reading/writing of watermark set A */ 827 828 value = dm_read_reg(ctx, wm_mask_ctrl_addr); 829 830 set_reg_field_value( 831 value, 832 1, 833 DPGV0_WATERMARK_MASK_CONTROL, 834 NB_PSTATE_CHANGE_WATERMARK_MASK); 835 dm_write_reg(ctx, wm_mask_ctrl_addr, value); 836 837 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 838 839 set_reg_field_value( 840 value, 841 1, 842 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 843 NB_PSTATE_CHANGE_ENABLE); 844 set_reg_field_value( 845 value, 846 1, 847 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 848 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST); 849 set_reg_field_value( 850 value, 851 1, 852 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 853 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST); 854 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 855 856 /* Write watermark set A */ 857 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 858 set_reg_field_value( 859 value, 860 marks.a_mark, 861 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 862 NB_PSTATE_CHANGE_WATERMARK); 863 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 864 865 /* Write mask to enable reading/writing of watermark set B */ 866 value = dm_read_reg(ctx, wm_mask_ctrl_addr); 867 set_reg_field_value( 868 value, 869 2, 870 DPGV0_WATERMARK_MASK_CONTROL, 871 NB_PSTATE_CHANGE_WATERMARK_MASK); 872 dm_write_reg(ctx, wm_mask_ctrl_addr, value); 873 874 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 875 set_reg_field_value( 876 value, 877 1, 878 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 879 NB_PSTATE_CHANGE_ENABLE); 880 set_reg_field_value( 881 value, 882 1, 883 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 884 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST); 885 set_reg_field_value( 886 value, 887 1, 888 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 889 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST); 890 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 891 892 /* Write watermark set B */ 893 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 894 set_reg_field_value( 895 value, 896 marks.b_mark, 897 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 898 NB_PSTATE_CHANGE_WATERMARK); 899 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 900} 901 902static void program_nbp_watermark_l( 903 const struct dc_context *ctx, 904 struct dce_watermarks marks) 905{ 906 program_nbp_watermark(ctx, 907 mmDPGV0_WATERMARK_MASK_CONTROL, 908 mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 909 marks); 910} 911 912static void program_nbp_watermark_c( 913 const struct dc_context *ctx, 914 struct dce_watermarks marks) 915{ 916 program_nbp_watermark(ctx, 917 mmDPGV1_WATERMARK_MASK_CONTROL, 918 mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL, 919 marks); 920} 921 922static void dce_mem_input_v_program_display_marks( 923 struct mem_input *mem_input, 924 struct dce_watermarks nbp, 925 struct dce_watermarks stutter, 926 struct dce_watermarks stutter_enter, 927 struct dce_watermarks urgent, 928 uint32_t total_dest_line_time_ns) 929{ 930 program_urgency_watermark_l( 931 mem_input->ctx, 932 urgent, 933 total_dest_line_time_ns); 934 935 program_nbp_watermark_l( 936 mem_input->ctx, 937 nbp); 938 939 program_stutter_watermark_l( 940 mem_input->ctx, 941 stutter); 942 943} 944 945static void dce_mem_input_program_chroma_display_marks( 946 struct mem_input *mem_input, 947 struct dce_watermarks nbp, 948 struct dce_watermarks stutter, 949 struct dce_watermarks urgent, 950 uint32_t total_dest_line_time_ns) 951{ 952 program_urgency_watermark_c( 953 mem_input->ctx, 954 urgent, 955 total_dest_line_time_ns); 956 957 program_nbp_watermark_c( 958 mem_input->ctx, 959 nbp); 960 961 program_stutter_watermark_c( 962 mem_input->ctx, 963 stutter); 964} 965 966static void dce110_allocate_mem_input_v( 967 struct mem_input *mi, 968 uint32_t h_total,/* for current stream */ 969 uint32_t v_total,/* for current stream */ 970 uint32_t pix_clk_khz,/* for current stream */ 971 uint32_t total_stream_num) 972{ 973 uint32_t addr; 974 uint32_t value; 975 uint32_t pix_dur; 976 if (pix_clk_khz != 0) { 977 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1; 978 value = dm_read_reg(mi->ctx, addr); 979 pix_dur = 1000000000ULL / pix_clk_khz; 980 set_reg_field_value( 981 value, 982 pix_dur, 983 DPGV0_PIPE_ARBITRATION_CONTROL1, 984 PIXEL_DURATION); 985 dm_write_reg(mi->ctx, addr, value); 986 987 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1; 988 value = dm_read_reg(mi->ctx, addr); 989 pix_dur = 1000000000ULL / pix_clk_khz; 990 set_reg_field_value( 991 value, 992 pix_dur, 993 DPGV1_PIPE_ARBITRATION_CONTROL1, 994 PIXEL_DURATION); 995 dm_write_reg(mi->ctx, addr, value); 996 997 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2; 998 value = 0x4000800; 999 dm_write_reg(mi->ctx, addr, value); 1000 1001 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2; 1002 value = 0x4000800; 1003 dm_write_reg(mi->ctx, addr, value); 1004 } 1005 1006} 1007 1008static void dce110_free_mem_input_v( 1009 struct mem_input *mi, 1010 uint32_t total_stream_num) 1011{ 1012} 1013 1014static const struct mem_input_funcs dce110_mem_input_v_funcs = { 1015 .mem_input_program_display_marks = 1016 dce_mem_input_v_program_display_marks, 1017 .mem_input_program_chroma_display_marks = 1018 dce_mem_input_program_chroma_display_marks, 1019 .allocate_mem_input = dce110_allocate_mem_input_v, 1020 .free_mem_input = dce110_free_mem_input_v, 1021 .mem_input_program_surface_flip_and_addr = 1022 dce_mem_input_v_program_surface_flip_and_addr, 1023 .mem_input_program_pte_vm = 1024 dce_mem_input_v_program_pte_vm, 1025 .mem_input_program_surface_config = 1026 dce_mem_input_v_program_surface_config, 1027 .mem_input_is_flip_pending = 1028 dce_mem_input_v_is_surface_pending 1029}; 1030/*****************************************/ 1031/* Constructor, Destructor */ 1032/*****************************************/ 1033 1034void dce110_mem_input_v_construct( 1035 struct dce_mem_input *dce_mi, 1036 struct dc_context *ctx) 1037{ 1038 dce_mi->base.funcs = &dce110_mem_input_v_funcs; 1039 dce_mi->base.ctx = ctx; 1040} 1041
~/
Read-only file preview.