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