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