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 static void set_flip_control( 39 struct dce_mem_input *mem_input110, 40 bool immediate) 41 { 42 uint32_t value = 0; 43 44 value = dm_read_reg( 45 mem_input110->base.ctx, 46 mmUNP_FLIP_CONTROL); 47 48 set_reg_field_value(value, 1, 49 UNP_FLIP_CONTROL, 50 GRPH_SURFACE_UPDATE_PENDING_MODE); 51 52 dm_write_reg( 53 mem_input110->base.ctx, 54 mmUNP_FLIP_CONTROL, 55 value); 56 } 57 58 /* chroma part */ 59 static void program_pri_addr_c( 60 struct dce_mem_input *mem_input110, 61 PHYSICAL_ADDRESS_LOC address) 62 { 63 uint32_t value = 0; 64 uint32_t temp = 0; 65 /*high register MUST be programmed first*/ 66 temp = address.high_part & 67 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK; 68 69 set_reg_field_value(value, temp, 70 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 71 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C); 72 73 dm_write_reg( 74 mem_input110->base.ctx, 75 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 76 value); 77 78 temp = 0; 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 */ 94 static 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 & 103 UNP_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 temp = 0; 115 value = 0; 116 temp = address.low_part >> 117 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT; 118 119 set_reg_field_value(value, temp, 120 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, 121 GRPH_PRIMARY_SURFACE_ADDRESS_L); 122 123 dm_write_reg( 124 mem_input110->base.ctx, 125 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, 126 value); 127 } 128 129 static void program_addr( 130 struct dce_mem_input *mem_input110, 131 const struct dc_plane_address *addr) 132 { 133 switch (addr->type) { 134 case PLN_ADDR_TYPE_GRAPHICS: 135 program_pri_addr_l( 136 mem_input110, 137 addr->grph.addr); 138 break; 139 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: 140 program_pri_addr_c( 141 mem_input110, 142 addr->video_progressive.chroma_addr); 143 program_pri_addr_l( 144 mem_input110, 145 addr->video_progressive.luma_addr); 146 break; 147 default: 148 /* not supported */ 149 BREAK_TO_DEBUGGER(); 150 } 151 } 152 153 static void enable(struct dce_mem_input *mem_input110) 154 { 155 uint32_t value = 0; 156 157 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE); 158 set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE); 159 dm_write_reg(mem_input110->base.ctx, 160 mmUNP_GRPH_ENABLE, 161 value); 162 } 163 164 static void program_tiling( 165 struct dce_mem_input *mem_input110, 166 const union dc_tiling_info *info, 167 const enum surface_pixel_format pixel_format) 168 { 169 uint32_t value = 0; 170 171 set_reg_field_value(value, info->gfx8.num_banks, 172 UNP_GRPH_CONTROL, GRPH_NUM_BANKS); 173 174 set_reg_field_value(value, info->gfx8.bank_width, 175 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L); 176 177 set_reg_field_value(value, info->gfx8.bank_height, 178 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L); 179 180 set_reg_field_value(value, info->gfx8.tile_aspect, 181 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L); 182 183 set_reg_field_value(value, info->gfx8.tile_split, 184 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L); 185 186 set_reg_field_value(value, info->gfx8.tile_mode, 187 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L); 188 189 set_reg_field_value(value, info->gfx8.pipe_config, 190 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG); 191 192 set_reg_field_value(value, info->gfx8.array_mode, 193 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE); 194 195 set_reg_field_value(value, 1, 196 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE); 197 198 set_reg_field_value(value, 0, 199 UNP_GRPH_CONTROL, GRPH_Z); 200 201 dm_write_reg( 202 mem_input110->base.ctx, 203 mmUNP_GRPH_CONTROL, 204 value); 205 206 value = 0; 207 208 set_reg_field_value(value, info->gfx8.bank_width_c, 209 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C); 210 211 set_reg_field_value(value, info->gfx8.bank_height_c, 212 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C); 213 214 set_reg_field_value(value, info->gfx8.tile_aspect_c, 215 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C); 216 217 set_reg_field_value(value, info->gfx8.tile_split_c, 218 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C); 219 220 set_reg_field_value(value, info->gfx8.tile_mode_c, 221 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C); 222 223 dm_write_reg( 224 mem_input110->base.ctx, 225 mmUNP_GRPH_CONTROL_C, 226 value); 227 } 228 229 static void program_size_and_rotation( 230 struct dce_mem_input *mem_input110, 231 enum dc_rotation_angle rotation, 232 const union plane_size *plane_size) 233 { 234 uint32_t value = 0; 235 union plane_size local_size = *plane_size; 236 237 if (rotation == ROTATION_ANGLE_90 || 238 rotation == ROTATION_ANGLE_270) { 239 240 swap(local_size.video.luma_size.x, 241 local_size.video.luma_size.y); 242 swap(local_size.video.luma_size.width, 243 local_size.video.luma_size.height); 244 swap(local_size.video.chroma_size.x, 245 local_size.video.chroma_size.y); 246 swap(local_size.video.chroma_size.width, 247 local_size.video.chroma_size.height); 248 } 249 250 value = 0; 251 set_reg_field_value(value, local_size.video.luma_pitch, 252 UNP_GRPH_PITCH_L, GRPH_PITCH_L); 253 254 dm_write_reg( 255 mem_input110->base.ctx, 256 mmUNP_GRPH_PITCH_L, 257 value); 258 259 value = 0; 260 set_reg_field_value(value, local_size.video.chroma_pitch, 261 UNP_GRPH_PITCH_C, GRPH_PITCH_C); 262 dm_write_reg( 263 mem_input110->base.ctx, 264 mmUNP_GRPH_PITCH_C, 265 value); 266 267 value = 0; 268 set_reg_field_value(value, 0, 269 UNP_GRPH_X_START_L, GRPH_X_START_L); 270 dm_write_reg( 271 mem_input110->base.ctx, 272 mmUNP_GRPH_X_START_L, 273 value); 274 275 value = 0; 276 set_reg_field_value(value, 0, 277 UNP_GRPH_X_START_C, GRPH_X_START_C); 278 dm_write_reg( 279 mem_input110->base.ctx, 280 mmUNP_GRPH_X_START_C, 281 value); 282 283 value = 0; 284 set_reg_field_value(value, 0, 285 UNP_GRPH_Y_START_L, GRPH_Y_START_L); 286 dm_write_reg( 287 mem_input110->base.ctx, 288 mmUNP_GRPH_Y_START_L, 289 value); 290 291 value = 0; 292 set_reg_field_value(value, 0, 293 UNP_GRPH_Y_START_C, GRPH_Y_START_C); 294 dm_write_reg( 295 mem_input110->base.ctx, 296 mmUNP_GRPH_Y_START_C, 297 value); 298 299 value = 0; 300 set_reg_field_value(value, local_size.video.luma_size.x + 301 local_size.video.luma_size.width, 302 UNP_GRPH_X_END_L, GRPH_X_END_L); 303 dm_write_reg( 304 mem_input110->base.ctx, 305 mmUNP_GRPH_X_END_L, 306 value); 307 308 value = 0; 309 set_reg_field_value(value, local_size.video.chroma_size.x + 310 local_size.video.chroma_size.width, 311 UNP_GRPH_X_END_C, GRPH_X_END_C); 312 dm_write_reg( 313 mem_input110->base.ctx, 314 mmUNP_GRPH_X_END_C, 315 value); 316 317 value = 0; 318 set_reg_field_value(value, local_size.video.luma_size.y + 319 local_size.video.luma_size.height, 320 UNP_GRPH_Y_END_L, GRPH_Y_END_L); 321 dm_write_reg( 322 mem_input110->base.ctx, 323 mmUNP_GRPH_Y_END_L, 324 value); 325 326 value = 0; 327 set_reg_field_value(value, local_size.video.chroma_size.y + 328 local_size.video.chroma_size.height, 329 UNP_GRPH_Y_END_C, GRPH_Y_END_C); 330 dm_write_reg( 331 mem_input110->base.ctx, 332 mmUNP_GRPH_Y_END_C, 333 value); 334 335 value = 0; 336 switch (rotation) { 337 case ROTATION_ANGLE_90: 338 set_reg_field_value(value, 3, 339 UNP_HW_ROTATION, ROTATION_ANGLE); 340 break; 341 case ROTATION_ANGLE_180: 342 set_reg_field_value(value, 2, 343 UNP_HW_ROTATION, ROTATION_ANGLE); 344 break; 345 case ROTATION_ANGLE_270: 346 set_reg_field_value(value, 1, 347 UNP_HW_ROTATION, ROTATION_ANGLE); 348 break; 349 default: 350 set_reg_field_value(value, 0, 351 UNP_HW_ROTATION, ROTATION_ANGLE); 352 break; 353 } 354 355 dm_write_reg( 356 mem_input110->base.ctx, 357 mmUNP_HW_ROTATION, 358 value); 359 } 360 361 static void program_pixel_format( 362 struct dce_mem_input *mem_input110, 363 enum surface_pixel_format format) 364 { 365 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { 366 uint32_t value; 367 uint8_t grph_depth; 368 uint8_t grph_format; 369 370 value = dm_read_reg( 371 mem_input110->base.ctx, 372 mmUNP_GRPH_CONTROL); 373 374 switch (format) { 375 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: 376 grph_depth = 0; 377 grph_format = 0; 378 break; 379 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 380 grph_depth = 1; 381 grph_format = 1; 382 break; 383 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 384 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 385 grph_depth = 2; 386 grph_format = 0; 387 break; 388 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 389 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 390 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: 391 grph_depth = 2; 392 grph_format = 1; 393 break; 394 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 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 471 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 486 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 */ 503 static 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 510 static 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 517 static 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 */ 525 static const unsigned int *get_dvmm_hw_setting( 526 union 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 563 void dce_mem_input_v_program_pte_vm( 564 struct mem_input *mem_input, 565 enum surface_pixel_format format, 566 union 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 636 void dce_mem_input_v_program_surface_config( 637 struct mem_input *mem_input, 638 enum surface_pixel_format format, 639 union dc_tiling_info *tiling_info, 640 union 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 653 static 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 710 static 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 723 static 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 736 static 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 798 static 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 808 static 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 818 static 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 902 static 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 912 static 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 922 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 945 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 966 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 1008 void dce110_free_mem_input_v( 1009 struct mem_input *mi, 1010 uint32_t total_stream_num) 1011 { 1012 } 1013 1014 static 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 1034 void 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 1042