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 38 #include "dce110/dce110_mem_input_v.h" 39 40 static void set_flip_control( 41 struct dce_mem_input *mem_input110, 42 bool immediate) 43 { 44 uint32_t value = 0; 45 46 value = dm_read_reg( 47 mem_input110->base.ctx, 48 mmUNP_FLIP_CONTROL); 49 50 set_reg_field_value(value, 1, 51 UNP_FLIP_CONTROL, 52 GRPH_SURFACE_UPDATE_PENDING_MODE); 53 54 dm_write_reg( 55 mem_input110->base.ctx, 56 mmUNP_FLIP_CONTROL, 57 value); 58 } 59 60 /* chroma part */ 61 static void program_pri_addr_c( 62 struct dce_mem_input *mem_input110, 63 PHYSICAL_ADDRESS_LOC address) 64 { 65 uint32_t value = 0; 66 uint32_t temp = 0; 67 /*high register MUST be programmed first*/ 68 temp = address.high_part & 69 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK; 70 71 set_reg_field_value(value, temp, 72 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 73 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C); 74 75 dm_write_reg( 76 mem_input110->base.ctx, 77 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 78 value); 79 80 temp = 0; 81 value = 0; 82 temp = address.low_part >> 83 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT; 84 85 set_reg_field_value(value, temp, 86 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C, 87 GRPH_PRIMARY_SURFACE_ADDRESS_C); 88 89 dm_write_reg( 90 mem_input110->base.ctx, 91 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C, 92 value); 93 } 94 95 /* luma part */ 96 static void program_pri_addr_l( 97 struct dce_mem_input *mem_input110, 98 PHYSICAL_ADDRESS_LOC address) 99 { 100 uint32_t value = 0; 101 uint32_t temp = 0; 102 103 /*high register MUST be programmed first*/ 104 temp = address.high_part & 105 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK; 106 107 set_reg_field_value(value, temp, 108 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L, 109 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L); 110 111 dm_write_reg( 112 mem_input110->base.ctx, 113 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L, 114 value); 115 116 temp = 0; 117 value = 0; 118 temp = address.low_part >> 119 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT; 120 121 set_reg_field_value(value, temp, 122 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, 123 GRPH_PRIMARY_SURFACE_ADDRESS_L); 124 125 dm_write_reg( 126 mem_input110->base.ctx, 127 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, 128 value); 129 } 130 131 static void program_addr( 132 struct dce_mem_input *mem_input110, 133 const struct dc_plane_address *addr) 134 { 135 switch (addr->type) { 136 case PLN_ADDR_TYPE_GRAPHICS: 137 program_pri_addr_l( 138 mem_input110, 139 addr->grph.addr); 140 break; 141 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: 142 program_pri_addr_c( 143 mem_input110, 144 addr->video_progressive.chroma_addr); 145 program_pri_addr_l( 146 mem_input110, 147 addr->video_progressive.luma_addr); 148 break; 149 default: 150 /* not supported */ 151 BREAK_TO_DEBUGGER(); 152 } 153 } 154 155 static void enable(struct dce_mem_input *mem_input110) 156 { 157 uint32_t value = 0; 158 159 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE); 160 set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE); 161 dm_write_reg(mem_input110->base.ctx, 162 mmUNP_GRPH_ENABLE, 163 value); 164 } 165 166 static void program_tiling( 167 struct dce_mem_input *mem_input110, 168 const union dc_tiling_info *info, 169 const enum surface_pixel_format pixel_format) 170 { 171 uint32_t value = 0; 172 173 set_reg_field_value(value, info->gfx8.num_banks, 174 UNP_GRPH_CONTROL, GRPH_NUM_BANKS); 175 176 set_reg_field_value(value, info->gfx8.bank_width, 177 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L); 178 179 set_reg_field_value(value, info->gfx8.bank_height, 180 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L); 181 182 set_reg_field_value(value, info->gfx8.tile_aspect, 183 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L); 184 185 set_reg_field_value(value, info->gfx8.tile_split, 186 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L); 187 188 set_reg_field_value(value, info->gfx8.tile_mode, 189 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L); 190 191 set_reg_field_value(value, info->gfx8.pipe_config, 192 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG); 193 194 set_reg_field_value(value, info->gfx8.array_mode, 195 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE); 196 197 set_reg_field_value(value, 1, 198 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE); 199 200 set_reg_field_value(value, 0, 201 UNP_GRPH_CONTROL, GRPH_Z); 202 203 dm_write_reg( 204 mem_input110->base.ctx, 205 mmUNP_GRPH_CONTROL, 206 value); 207 208 value = 0; 209 210 set_reg_field_value(value, info->gfx8.bank_width_c, 211 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C); 212 213 set_reg_field_value(value, info->gfx8.bank_height_c, 214 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C); 215 216 set_reg_field_value(value, info->gfx8.tile_aspect_c, 217 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C); 218 219 set_reg_field_value(value, info->gfx8.tile_split_c, 220 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C); 221 222 set_reg_field_value(value, info->gfx8.tile_mode_c, 223 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C); 224 225 dm_write_reg( 226 mem_input110->base.ctx, 227 mmUNP_GRPH_CONTROL_C, 228 value); 229 } 230 231 static void program_size_and_rotation( 232 struct dce_mem_input *mem_input110, 233 enum dc_rotation_angle rotation, 234 const union plane_size *plane_size) 235 { 236 uint32_t value = 0; 237 union plane_size local_size = *plane_size; 238 239 if (rotation == ROTATION_ANGLE_90 || 240 rotation == ROTATION_ANGLE_270) { 241 242 swap(local_size.video.luma_size.x, 243 local_size.video.luma_size.y); 244 swap(local_size.video.luma_size.width, 245 local_size.video.luma_size.height); 246 swap(local_size.video.chroma_size.x, 247 local_size.video.chroma_size.y); 248 swap(local_size.video.chroma_size.width, 249 local_size.video.chroma_size.height); 250 } 251 252 value = 0; 253 set_reg_field_value(value, local_size.video.luma_pitch, 254 UNP_GRPH_PITCH_L, GRPH_PITCH_L); 255 256 dm_write_reg( 257 mem_input110->base.ctx, 258 mmUNP_GRPH_PITCH_L, 259 value); 260 261 value = 0; 262 set_reg_field_value(value, local_size.video.chroma_pitch, 263 UNP_GRPH_PITCH_C, GRPH_PITCH_C); 264 dm_write_reg( 265 mem_input110->base.ctx, 266 mmUNP_GRPH_PITCH_C, 267 value); 268 269 value = 0; 270 set_reg_field_value(value, 0, 271 UNP_GRPH_X_START_L, GRPH_X_START_L); 272 dm_write_reg( 273 mem_input110->base.ctx, 274 mmUNP_GRPH_X_START_L, 275 value); 276 277 value = 0; 278 set_reg_field_value(value, 0, 279 UNP_GRPH_X_START_C, GRPH_X_START_C); 280 dm_write_reg( 281 mem_input110->base.ctx, 282 mmUNP_GRPH_X_START_C, 283 value); 284 285 value = 0; 286 set_reg_field_value(value, 0, 287 UNP_GRPH_Y_START_L, GRPH_Y_START_L); 288 dm_write_reg( 289 mem_input110->base.ctx, 290 mmUNP_GRPH_Y_START_L, 291 value); 292 293 value = 0; 294 set_reg_field_value(value, 0, 295 UNP_GRPH_Y_START_C, GRPH_Y_START_C); 296 dm_write_reg( 297 mem_input110->base.ctx, 298 mmUNP_GRPH_Y_START_C, 299 value); 300 301 value = 0; 302 set_reg_field_value(value, local_size.video.luma_size.x + 303 local_size.video.luma_size.width, 304 UNP_GRPH_X_END_L, GRPH_X_END_L); 305 dm_write_reg( 306 mem_input110->base.ctx, 307 mmUNP_GRPH_X_END_L, 308 value); 309 310 value = 0; 311 set_reg_field_value(value, local_size.video.chroma_size.x + 312 local_size.video.chroma_size.width, 313 UNP_GRPH_X_END_C, GRPH_X_END_C); 314 dm_write_reg( 315 mem_input110->base.ctx, 316 mmUNP_GRPH_X_END_C, 317 value); 318 319 value = 0; 320 set_reg_field_value(value, local_size.video.luma_size.y + 321 local_size.video.luma_size.height, 322 UNP_GRPH_Y_END_L, GRPH_Y_END_L); 323 dm_write_reg( 324 mem_input110->base.ctx, 325 mmUNP_GRPH_Y_END_L, 326 value); 327 328 value = 0; 329 set_reg_field_value(value, local_size.video.chroma_size.y + 330 local_size.video.chroma_size.height, 331 UNP_GRPH_Y_END_C, GRPH_Y_END_C); 332 dm_write_reg( 333 mem_input110->base.ctx, 334 mmUNP_GRPH_Y_END_C, 335 value); 336 337 value = 0; 338 switch (rotation) { 339 case ROTATION_ANGLE_90: 340 set_reg_field_value(value, 3, 341 UNP_HW_ROTATION, ROTATION_ANGLE); 342 break; 343 case ROTATION_ANGLE_180: 344 set_reg_field_value(value, 2, 345 UNP_HW_ROTATION, ROTATION_ANGLE); 346 break; 347 case ROTATION_ANGLE_270: 348 set_reg_field_value(value, 1, 349 UNP_HW_ROTATION, ROTATION_ANGLE); 350 break; 351 default: 352 set_reg_field_value(value, 0, 353 UNP_HW_ROTATION, ROTATION_ANGLE); 354 break; 355 } 356 357 dm_write_reg( 358 mem_input110->base.ctx, 359 mmUNP_HW_ROTATION, 360 value); 361 } 362 363 static void program_pixel_format( 364 struct dce_mem_input *mem_input110, 365 enum surface_pixel_format format) 366 { 367 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { 368 uint32_t value; 369 uint8_t grph_depth; 370 uint8_t grph_format; 371 372 value = dm_read_reg( 373 mem_input110->base.ctx, 374 mmUNP_GRPH_CONTROL); 375 376 switch (format) { 377 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: 378 grph_depth = 0; 379 grph_format = 0; 380 break; 381 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 382 grph_depth = 1; 383 grph_format = 1; 384 break; 385 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 386 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 387 grph_depth = 2; 388 grph_format = 0; 389 break; 390 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 391 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 392 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: 393 grph_depth = 2; 394 grph_format = 1; 395 break; 396 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 397 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 398 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 399 grph_depth = 3; 400 grph_format = 0; 401 break; 402 default: 403 grph_depth = 2; 404 grph_format = 0; 405 break; 406 } 407 408 set_reg_field_value( 409 value, 410 grph_depth, 411 UNP_GRPH_CONTROL, 412 GRPH_DEPTH); 413 set_reg_field_value( 414 value, 415 grph_format, 416 UNP_GRPH_CONTROL, 417 GRPH_FORMAT); 418 419 dm_write_reg( 420 mem_input110->base.ctx, 421 mmUNP_GRPH_CONTROL, 422 value); 423 424 value = dm_read_reg( 425 mem_input110->base.ctx, 426 mmUNP_GRPH_CONTROL_EXP); 427 428 /* VIDEO FORMAT 0 */ 429 set_reg_field_value( 430 value, 431 0, 432 UNP_GRPH_CONTROL_EXP, 433 VIDEO_FORMAT); 434 dm_write_reg( 435 mem_input110->base.ctx, 436 mmUNP_GRPH_CONTROL_EXP, 437 value); 438 439 } else { 440 /* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */ 441 uint32_t value; 442 uint8_t video_format; 443 444 value = dm_read_reg( 445 mem_input110->base.ctx, 446 mmUNP_GRPH_CONTROL_EXP); 447 448 switch (format) { 449 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 450 video_format = 2; 451 break; 452 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 453 video_format = 3; 454 break; 455 default: 456 video_format = 0; 457 break; 458 } 459 460 set_reg_field_value( 461 value, 462 video_format, 463 UNP_GRPH_CONTROL_EXP, 464 VIDEO_FORMAT); 465 466 dm_write_reg( 467 mem_input110->base.ctx, 468 mmUNP_GRPH_CONTROL_EXP, 469 value); 470 } 471 } 472 473 static 474 bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input) 475 { 476 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 477 uint32_t value; 478 479 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE); 480 481 if (get_reg_field_value(value, UNP_GRPH_UPDATE, 482 GRPH_SURFACE_UPDATE_PENDING)) 483 return true; 484 485 mem_input->current_address = mem_input->request_address; 486 return false; 487 } 488 489 static 490 bool dce_mem_input_v_program_surface_flip_and_addr( 491 struct mem_input *mem_input, 492 const struct dc_plane_address *address, 493 bool flip_immediate) 494 { 495 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 496 497 set_flip_control(mem_input110, flip_immediate); 498 program_addr(mem_input110, 499 address); 500 501 mem_input->request_address = *address; 502 503 return true; 504 } 505 506 /* Scatter Gather param tables */ 507 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = { 508 { 8, 64, 64, 8, 8, 1, 4, 0, 0}, 509 { 16, 64, 32, 8, 16, 1, 8, 0, 0}, 510 { 32, 32, 32, 16, 16, 1, 8, 0, 0}, 511 { 64, 8, 32, 16, 16, 1, 8, 0, 0}, /* fake */ 512 }; 513 514 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = { 515 { 8, 512, 8, 1, 0, 1, 0, 0, 0}, /* 0 for invalid */ 516 { 16, 256, 8, 2, 0, 1, 0, 0, 0}, 517 { 32, 128, 8, 4, 0, 1, 0, 0, 0}, 518 { 64, 64, 8, 4, 0, 1, 0, 0, 0}, /* fake */ 519 }; 520 521 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = { 522 { 8, 4096, 1, 8, 0, 1, 0, 0, 0}, 523 { 16, 2048, 1, 8, 0, 1, 0, 0, 0}, 524 { 32, 1024, 1, 8, 0, 1, 0, 0, 0}, 525 { 64, 512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */ 526 }; 527 528 /* Helper to get table entry from surface info */ 529 static const unsigned int *get_dvmm_hw_setting( 530 union dc_tiling_info *tiling_info, 531 enum surface_pixel_format format, 532 bool chroma) 533 { 534 enum bits_per_pixel { 535 bpp_8 = 0, 536 bpp_16, 537 bpp_32, 538 bpp_64 539 } bpp; 540 541 if (format >= SURFACE_PIXEL_FORMAT_INVALID) 542 bpp = bpp_32; 543 else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 544 bpp = chroma ? bpp_16 : bpp_8; 545 else 546 bpp = bpp_8; 547 548 switch (tiling_info->gfx8.array_mode) { 549 case DC_ARRAY_1D_TILED_THIN1: 550 case DC_ARRAY_1D_TILED_THICK: 551 case DC_ARRAY_PRT_TILED_THIN1: 552 return dvmm_Hw_Setting_1DTiling[bpp]; 553 case DC_ARRAY_2D_TILED_THIN1: 554 case DC_ARRAY_2D_TILED_THICK: 555 case DC_ARRAY_2D_TILED_X_THICK: 556 case DC_ARRAY_PRT_2D_TILED_THIN1: 557 case DC_ARRAY_PRT_2D_TILED_THICK: 558 return dvmm_Hw_Setting_2DTiling[bpp]; 559 case DC_ARRAY_LINEAR_GENERAL: 560 case DC_ARRAY_LINEAR_ALLIGNED: 561 return dvmm_Hw_Setting_Linear[bpp]; 562 default: 563 return dvmm_Hw_Setting_2DTiling[bpp]; 564 } 565 } 566 567 static 568 void dce_mem_input_v_program_pte_vm( 569 struct mem_input *mem_input, 570 enum surface_pixel_format format, 571 union dc_tiling_info *tiling_info, 572 enum dc_rotation_angle rotation) 573 { 574 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 575 const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false); 576 const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true); 577 578 unsigned int page_width = 0; 579 unsigned int page_height = 0; 580 unsigned int page_width_chroma = 0; 581 unsigned int page_height_chroma = 0; 582 unsigned int temp_page_width = pte[1]; 583 unsigned int temp_page_height = pte[2]; 584 unsigned int min_pte_before_flip = 0; 585 unsigned int min_pte_before_flip_chroma = 0; 586 uint32_t value = 0; 587 588 while ((temp_page_width >>= 1) != 0) 589 page_width++; 590 while ((temp_page_height >>= 1) != 0) 591 page_height++; 592 593 temp_page_width = pte_chroma[1]; 594 temp_page_height = pte_chroma[2]; 595 while ((temp_page_width >>= 1) != 0) 596 page_width_chroma++; 597 while ((temp_page_height >>= 1) != 0) 598 page_height_chroma++; 599 600 switch (rotation) { 601 case ROTATION_ANGLE_90: 602 case ROTATION_ANGLE_270: 603 min_pte_before_flip = pte[4]; 604 min_pte_before_flip_chroma = pte_chroma[4]; 605 break; 606 default: 607 min_pte_before_flip = pte[3]; 608 min_pte_before_flip_chroma = pte_chroma[3]; 609 break; 610 } 611 612 value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT); 613 /* TODO: un-hardcode requestlimit */ 614 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L); 615 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C); 616 dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value); 617 618 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL); 619 set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH); 620 set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT); 621 set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP); 622 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value); 623 624 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL); 625 set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK); 626 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING); 627 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value); 628 629 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C); 630 set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C); 631 set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C); 632 set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C); 633 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value); 634 635 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C); 636 set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C); 637 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C); 638 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value); 639 } 640 641 static 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 union 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 static 929 void dce_mem_input_v_program_display_marks( 930 struct mem_input *mem_input, 931 struct dce_watermarks nbp, 932 struct dce_watermarks stutter, 933 struct dce_watermarks stutter_enter, 934 struct dce_watermarks urgent, 935 uint32_t total_dest_line_time_ns) 936 { 937 program_urgency_watermark_l( 938 mem_input->ctx, 939 urgent, 940 total_dest_line_time_ns); 941 942 program_nbp_watermark_l( 943 mem_input->ctx, 944 nbp); 945 946 program_stutter_watermark_l( 947 mem_input->ctx, 948 stutter); 949 950 } 951 952 static 953 void dce_mem_input_program_chroma_display_marks( 954 struct mem_input *mem_input, 955 struct dce_watermarks nbp, 956 struct dce_watermarks stutter, 957 struct dce_watermarks urgent, 958 uint32_t total_dest_line_time_ns) 959 { 960 program_urgency_watermark_c( 961 mem_input->ctx, 962 urgent, 963 total_dest_line_time_ns); 964 965 program_nbp_watermark_c( 966 mem_input->ctx, 967 nbp); 968 969 program_stutter_watermark_c( 970 mem_input->ctx, 971 stutter); 972 } 973 974 static 975 void dce110_allocate_mem_input_v( 976 struct mem_input *mi, 977 uint32_t h_total,/* for current stream */ 978 uint32_t v_total,/* for current stream */ 979 uint32_t pix_clk_khz,/* for current stream */ 980 uint32_t total_stream_num) 981 { 982 uint32_t addr; 983 uint32_t value; 984 uint32_t pix_dur; 985 if (pix_clk_khz != 0) { 986 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1; 987 value = dm_read_reg(mi->ctx, addr); 988 pix_dur = 1000000000ULL / pix_clk_khz; 989 set_reg_field_value( 990 value, 991 pix_dur, 992 DPGV0_PIPE_ARBITRATION_CONTROL1, 993 PIXEL_DURATION); 994 dm_write_reg(mi->ctx, addr, value); 995 996 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1; 997 value = dm_read_reg(mi->ctx, addr); 998 pix_dur = 1000000000ULL / pix_clk_khz; 999 set_reg_field_value( 1000 value, 1001 pix_dur, 1002 DPGV1_PIPE_ARBITRATION_CONTROL1, 1003 PIXEL_DURATION); 1004 dm_write_reg(mi->ctx, addr, value); 1005 1006 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2; 1007 value = 0x4000800; 1008 dm_write_reg(mi->ctx, addr, value); 1009 1010 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2; 1011 value = 0x4000800; 1012 dm_write_reg(mi->ctx, addr, value); 1013 } 1014 1015 } 1016 1017 static 1018 void dce110_free_mem_input_v( 1019 struct mem_input *mi, 1020 uint32_t total_stream_num) 1021 { 1022 } 1023 1024 static const struct mem_input_funcs dce110_mem_input_v_funcs = { 1025 .mem_input_program_display_marks = 1026 dce_mem_input_v_program_display_marks, 1027 .mem_input_program_chroma_display_marks = 1028 dce_mem_input_program_chroma_display_marks, 1029 .allocate_mem_input = dce110_allocate_mem_input_v, 1030 .free_mem_input = dce110_free_mem_input_v, 1031 .mem_input_program_surface_flip_and_addr = 1032 dce_mem_input_v_program_surface_flip_and_addr, 1033 .mem_input_program_pte_vm = 1034 dce_mem_input_v_program_pte_vm, 1035 .mem_input_program_surface_config = 1036 dce_mem_input_v_program_surface_config, 1037 .mem_input_is_flip_pending = 1038 dce_mem_input_v_is_surface_pending 1039 }; 1040 /*****************************************/ 1041 /* Constructor, Destructor */ 1042 /*****************************************/ 1043 1044 void dce110_mem_input_v_construct( 1045 struct dce_mem_input *dce_mi, 1046 struct dc_context *ctx) 1047 { 1048 dce_mi->base.funcs = &dce110_mem_input_v_funcs; 1049 dce_mi->base.ctx = ctx; 1050 } 1051 1052