dce110_mem_input_v.c (27050B)
1/* 2 * Copyright 2012-16 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25#include "dm_services.h" 26 27#include "dce/dce_11_0_d.h" 28#include "dce/dce_11_0_sh_mask.h" 29/* TODO: this needs to be looked at, used by Stella's workaround*/ 30#include "gmc/gmc_8_2_d.h" 31#include "gmc/gmc_8_2_sh_mask.h" 32 33#include "include/logger_interface.h" 34#include "inc/dce_calcs.h" 35 36#include "dce/dce_mem_input.h" 37#include "dce110_mem_input_v.h" 38 39static void set_flip_control( 40 struct dce_mem_input *mem_input110, 41 bool immediate) 42{ 43 uint32_t value = 0; 44 45 value = dm_read_reg( 46 mem_input110->base.ctx, 47 mmUNP_FLIP_CONTROL); 48 49 set_reg_field_value(value, 1, 50 UNP_FLIP_CONTROL, 51 GRPH_SURFACE_UPDATE_PENDING_MODE); 52 53 dm_write_reg( 54 mem_input110->base.ctx, 55 mmUNP_FLIP_CONTROL, 56 value); 57} 58 59/* chroma part */ 60static void program_pri_addr_c( 61 struct dce_mem_input *mem_input110, 62 PHYSICAL_ADDRESS_LOC address) 63{ 64 uint32_t value = 0; 65 uint32_t temp = 0; 66 /*high register MUST be programmed first*/ 67 temp = address.high_part & 68UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK; 69 70 set_reg_field_value(value, temp, 71 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 72 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C); 73 74 dm_write_reg( 75 mem_input110->base.ctx, 76 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C, 77 value); 78 79 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 */ 95static 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 & 104UNP_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 130static 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 154static 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 165static 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 230static 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 362static 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_ABGR16161616: 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 473static bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input) 474{ 475 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 476 uint32_t value; 477 478 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE); 479 480 if (get_reg_field_value(value, UNP_GRPH_UPDATE, 481 GRPH_SURFACE_UPDATE_PENDING)) 482 return true; 483 484 mem_input->current_address = mem_input->request_address; 485 return false; 486} 487 488static bool dce_mem_input_v_program_surface_flip_and_addr( 489 struct mem_input *mem_input, 490 const struct dc_plane_address *address, 491 bool flip_immediate) 492{ 493 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 494 495 set_flip_control(mem_input110, flip_immediate); 496 program_addr(mem_input110, 497 address); 498 499 mem_input->request_address = *address; 500 501 return true; 502} 503 504/* Scatter Gather param tables */ 505static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = { 506 { 8, 64, 64, 8, 8, 1, 4, 0, 0}, 507 { 16, 64, 32, 8, 16, 1, 8, 0, 0}, 508 { 32, 32, 32, 16, 16, 1, 8, 0, 0}, 509 { 64, 8, 32, 16, 16, 1, 8, 0, 0}, /* fake */ 510}; 511 512static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = { 513 { 8, 512, 8, 1, 0, 1, 0, 0, 0}, /* 0 for invalid */ 514 { 16, 256, 8, 2, 0, 1, 0, 0, 0}, 515 { 32, 128, 8, 4, 0, 1, 0, 0, 0}, 516 { 64, 64, 8, 4, 0, 1, 0, 0, 0}, /* fake */ 517}; 518 519static const unsigned int dvmm_Hw_Setting_Linear[4][9] = { 520 { 8, 4096, 1, 8, 0, 1, 0, 0, 0}, 521 { 16, 2048, 1, 8, 0, 1, 0, 0, 0}, 522 { 32, 1024, 1, 8, 0, 1, 0, 0, 0}, 523 { 64, 512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */ 524}; 525 526/* Helper to get table entry from surface info */ 527static const unsigned int *get_dvmm_hw_setting( 528 union dc_tiling_info *tiling_info, 529 enum surface_pixel_format format, 530 bool chroma) 531{ 532 enum bits_per_pixel { 533 bpp_8 = 0, 534 bpp_16, 535 bpp_32, 536 bpp_64 537 } bpp; 538 539 if (format >= SURFACE_PIXEL_FORMAT_INVALID) 540 bpp = bpp_32; 541 else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 542 bpp = chroma ? bpp_16 : bpp_8; 543 else 544 bpp = bpp_8; 545 546 switch (tiling_info->gfx8.array_mode) { 547 case DC_ARRAY_1D_TILED_THIN1: 548 case DC_ARRAY_1D_TILED_THICK: 549 case DC_ARRAY_PRT_TILED_THIN1: 550 return dvmm_Hw_Setting_1DTiling[bpp]; 551 case DC_ARRAY_2D_TILED_THIN1: 552 case DC_ARRAY_2D_TILED_THICK: 553 case DC_ARRAY_2D_TILED_X_THICK: 554 case DC_ARRAY_PRT_2D_TILED_THIN1: 555 case DC_ARRAY_PRT_2D_TILED_THICK: 556 return dvmm_Hw_Setting_2DTiling[bpp]; 557 case DC_ARRAY_LINEAR_GENERAL: 558 case DC_ARRAY_LINEAR_ALLIGNED: 559 return dvmm_Hw_Setting_Linear[bpp]; 560 default: 561 return dvmm_Hw_Setting_2DTiling[bpp]; 562 } 563} 564 565static void dce_mem_input_v_program_pte_vm( 566 struct mem_input *mem_input, 567 enum surface_pixel_format format, 568 union dc_tiling_info *tiling_info, 569 enum dc_rotation_angle rotation) 570{ 571 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 572 const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false); 573 const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true); 574 575 unsigned int page_width = 0; 576 unsigned int page_height = 0; 577 unsigned int page_width_chroma = 0; 578 unsigned int page_height_chroma = 0; 579 unsigned int temp_page_width = pte[1]; 580 unsigned int temp_page_height = pte[2]; 581 unsigned int min_pte_before_flip = 0; 582 unsigned int min_pte_before_flip_chroma = 0; 583 uint32_t value = 0; 584 585 while ((temp_page_width >>= 1) != 0) 586 page_width++; 587 while ((temp_page_height >>= 1) != 0) 588 page_height++; 589 590 temp_page_width = pte_chroma[1]; 591 temp_page_height = pte_chroma[2]; 592 while ((temp_page_width >>= 1) != 0) 593 page_width_chroma++; 594 while ((temp_page_height >>= 1) != 0) 595 page_height_chroma++; 596 597 switch (rotation) { 598 case ROTATION_ANGLE_90: 599 case ROTATION_ANGLE_270: 600 min_pte_before_flip = pte[4]; 601 min_pte_before_flip_chroma = pte_chroma[4]; 602 break; 603 default: 604 min_pte_before_flip = pte[3]; 605 min_pte_before_flip_chroma = pte_chroma[3]; 606 break; 607 } 608 609 value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT); 610 /* TODO: un-hardcode requestlimit */ 611 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L); 612 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C); 613 dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value); 614 615 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL); 616 set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH); 617 set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT); 618 set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP); 619 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value); 620 621 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL); 622 set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK); 623 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING); 624 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value); 625 626 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C); 627 set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C); 628 set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C); 629 set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C); 630 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value); 631 632 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C); 633 set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C); 634 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C); 635 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value); 636} 637 638static void dce_mem_input_v_program_surface_config( 639 struct mem_input *mem_input, 640 enum surface_pixel_format format, 641 union dc_tiling_info *tiling_info, 642 struct plane_size *plane_size, 643 enum dc_rotation_angle rotation, 644 struct dc_plane_dcc_param *dcc, 645 bool horizotal_mirror) 646{ 647 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); 648 649 enable(mem_input110); 650 program_tiling(mem_input110, tiling_info, format); 651 program_size_and_rotation(mem_input110, rotation, plane_size); 652 program_pixel_format(mem_input110, format); 653} 654 655static void program_urgency_watermark( 656 const struct dc_context *ctx, 657 const uint32_t urgency_addr, 658 const uint32_t wm_addr, 659 struct dce_watermarks marks_low, 660 uint32_t total_dest_line_time_ns) 661{ 662 /* register value */ 663 uint32_t urgency_cntl = 0; 664 uint32_t wm_mask_cntl = 0; 665 666 /*Write mask to enable reading/writing of watermark set A*/ 667 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 668 set_reg_field_value(wm_mask_cntl, 669 1, 670 DPGV0_WATERMARK_MASK_CONTROL, 671 URGENCY_WATERMARK_MASK); 672 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 673 674 urgency_cntl = dm_read_reg(ctx, urgency_addr); 675 676 set_reg_field_value( 677 urgency_cntl, 678 marks_low.a_mark, 679 DPGV0_PIPE_URGENCY_CONTROL, 680 URGENCY_LOW_WATERMARK); 681 682 set_reg_field_value( 683 urgency_cntl, 684 total_dest_line_time_ns, 685 DPGV0_PIPE_URGENCY_CONTROL, 686 URGENCY_HIGH_WATERMARK); 687 dm_write_reg(ctx, urgency_addr, urgency_cntl); 688 689 /*Write mask to enable reading/writing of watermark set B*/ 690 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 691 set_reg_field_value(wm_mask_cntl, 692 2, 693 DPGV0_WATERMARK_MASK_CONTROL, 694 URGENCY_WATERMARK_MASK); 695 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 696 697 urgency_cntl = dm_read_reg(ctx, urgency_addr); 698 699 set_reg_field_value(urgency_cntl, 700 marks_low.b_mark, 701 DPGV0_PIPE_URGENCY_CONTROL, 702 URGENCY_LOW_WATERMARK); 703 704 set_reg_field_value(urgency_cntl, 705 total_dest_line_time_ns, 706 DPGV0_PIPE_URGENCY_CONTROL, 707 URGENCY_HIGH_WATERMARK); 708 709 dm_write_reg(ctx, urgency_addr, urgency_cntl); 710} 711 712static void program_urgency_watermark_l( 713 const struct dc_context *ctx, 714 struct dce_watermarks marks_low, 715 uint32_t total_dest_line_time_ns) 716{ 717 program_urgency_watermark( 718 ctx, 719 mmDPGV0_PIPE_URGENCY_CONTROL, 720 mmDPGV0_WATERMARK_MASK_CONTROL, 721 marks_low, 722 total_dest_line_time_ns); 723} 724 725static void program_urgency_watermark_c( 726 const struct dc_context *ctx, 727 struct dce_watermarks marks_low, 728 uint32_t total_dest_line_time_ns) 729{ 730 program_urgency_watermark( 731 ctx, 732 mmDPGV1_PIPE_URGENCY_CONTROL, 733 mmDPGV1_WATERMARK_MASK_CONTROL, 734 marks_low, 735 total_dest_line_time_ns); 736} 737 738static void program_stutter_watermark( 739 const struct dc_context *ctx, 740 const uint32_t stutter_addr, 741 const uint32_t wm_addr, 742 struct dce_watermarks marks) 743{ 744 /* register value */ 745 uint32_t stutter_cntl = 0; 746 uint32_t wm_mask_cntl = 0; 747 748 /*Write mask to enable reading/writing of watermark set A*/ 749 750 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 751 set_reg_field_value(wm_mask_cntl, 752 1, 753 DPGV0_WATERMARK_MASK_CONTROL, 754 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK); 755 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 756 757 stutter_cntl = dm_read_reg(ctx, stutter_addr); 758 759 if (ctx->dc->debug.disable_stutter) { 760 set_reg_field_value(stutter_cntl, 761 0, 762 DPGV0_PIPE_STUTTER_CONTROL, 763 STUTTER_ENABLE); 764 } else { 765 set_reg_field_value(stutter_cntl, 766 1, 767 DPGV0_PIPE_STUTTER_CONTROL, 768 STUTTER_ENABLE); 769 } 770 771 set_reg_field_value(stutter_cntl, 772 1, 773 DPGV0_PIPE_STUTTER_CONTROL, 774 STUTTER_IGNORE_FBC); 775 776 /*Write watermark set A*/ 777 set_reg_field_value(stutter_cntl, 778 marks.a_mark, 779 DPGV0_PIPE_STUTTER_CONTROL, 780 STUTTER_EXIT_SELF_REFRESH_WATERMARK); 781 dm_write_reg(ctx, stutter_addr, stutter_cntl); 782 783 /*Write mask to enable reading/writing of watermark set B*/ 784 wm_mask_cntl = dm_read_reg(ctx, wm_addr); 785 set_reg_field_value(wm_mask_cntl, 786 2, 787 DPGV0_WATERMARK_MASK_CONTROL, 788 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK); 789 dm_write_reg(ctx, wm_addr, wm_mask_cntl); 790 791 stutter_cntl = dm_read_reg(ctx, stutter_addr); 792 /*Write watermark set B*/ 793 set_reg_field_value(stutter_cntl, 794 marks.b_mark, 795 DPGV0_PIPE_STUTTER_CONTROL, 796 STUTTER_EXIT_SELF_REFRESH_WATERMARK); 797 dm_write_reg(ctx, stutter_addr, stutter_cntl); 798} 799 800static void program_stutter_watermark_l( 801 const struct dc_context *ctx, 802 struct dce_watermarks marks) 803{ 804 program_stutter_watermark(ctx, 805 mmDPGV0_PIPE_STUTTER_CONTROL, 806 mmDPGV0_WATERMARK_MASK_CONTROL, 807 marks); 808} 809 810static void program_stutter_watermark_c( 811 const struct dc_context *ctx, 812 struct dce_watermarks marks) 813{ 814 program_stutter_watermark(ctx, 815 mmDPGV1_PIPE_STUTTER_CONTROL, 816 mmDPGV1_WATERMARK_MASK_CONTROL, 817 marks); 818} 819 820static void program_nbp_watermark( 821 const struct dc_context *ctx, 822 const uint32_t wm_mask_ctrl_addr, 823 const uint32_t nbp_pstate_ctrl_addr, 824 struct dce_watermarks marks) 825{ 826 uint32_t value; 827 828 /* Write mask to enable reading/writing of watermark set A */ 829 830 value = dm_read_reg(ctx, wm_mask_ctrl_addr); 831 832 set_reg_field_value( 833 value, 834 1, 835 DPGV0_WATERMARK_MASK_CONTROL, 836 NB_PSTATE_CHANGE_WATERMARK_MASK); 837 dm_write_reg(ctx, wm_mask_ctrl_addr, value); 838 839 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 840 841 set_reg_field_value( 842 value, 843 1, 844 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 845 NB_PSTATE_CHANGE_ENABLE); 846 set_reg_field_value( 847 value, 848 1, 849 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 850 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST); 851 set_reg_field_value( 852 value, 853 1, 854 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 855 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST); 856 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 857 858 /* Write watermark set A */ 859 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 860 set_reg_field_value( 861 value, 862 marks.a_mark, 863 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 864 NB_PSTATE_CHANGE_WATERMARK); 865 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 866 867 /* Write mask to enable reading/writing of watermark set B */ 868 value = dm_read_reg(ctx, wm_mask_ctrl_addr); 869 set_reg_field_value( 870 value, 871 2, 872 DPGV0_WATERMARK_MASK_CONTROL, 873 NB_PSTATE_CHANGE_WATERMARK_MASK); 874 dm_write_reg(ctx, wm_mask_ctrl_addr, value); 875 876 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 877 set_reg_field_value( 878 value, 879 1, 880 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 881 NB_PSTATE_CHANGE_ENABLE); 882 set_reg_field_value( 883 value, 884 1, 885 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 886 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST); 887 set_reg_field_value( 888 value, 889 1, 890 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 891 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST); 892 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 893 894 /* Write watermark set B */ 895 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr); 896 set_reg_field_value( 897 value, 898 marks.b_mark, 899 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 900 NB_PSTATE_CHANGE_WATERMARK); 901 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value); 902} 903 904static void program_nbp_watermark_l( 905 const struct dc_context *ctx, 906 struct dce_watermarks marks) 907{ 908 program_nbp_watermark(ctx, 909 mmDPGV0_WATERMARK_MASK_CONTROL, 910 mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL, 911 marks); 912} 913 914static void program_nbp_watermark_c( 915 const struct dc_context *ctx, 916 struct dce_watermarks marks) 917{ 918 program_nbp_watermark(ctx, 919 mmDPGV1_WATERMARK_MASK_CONTROL, 920 mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL, 921 marks); 922} 923 924static void dce_mem_input_v_program_display_marks( 925 struct mem_input *mem_input, 926 struct dce_watermarks nbp, 927 struct dce_watermarks stutter, 928 struct dce_watermarks stutter_enter, 929 struct dce_watermarks urgent, 930 uint32_t total_dest_line_time_ns) 931{ 932 program_urgency_watermark_l( 933 mem_input->ctx, 934 urgent, 935 total_dest_line_time_ns); 936 937 program_nbp_watermark_l( 938 mem_input->ctx, 939 nbp); 940 941 program_stutter_watermark_l( 942 mem_input->ctx, 943 stutter); 944 945} 946 947static void dce_mem_input_program_chroma_display_marks( 948 struct mem_input *mem_input, 949 struct dce_watermarks nbp, 950 struct dce_watermarks stutter, 951 struct dce_watermarks urgent, 952 uint32_t total_dest_line_time_ns) 953{ 954 program_urgency_watermark_c( 955 mem_input->ctx, 956 urgent, 957 total_dest_line_time_ns); 958 959 program_nbp_watermark_c( 960 mem_input->ctx, 961 nbp); 962 963 program_stutter_watermark_c( 964 mem_input->ctx, 965 stutter); 966} 967 968static void dce110_allocate_mem_input_v( 969 struct mem_input *mi, 970 uint32_t h_total,/* for current stream */ 971 uint32_t v_total,/* for current stream */ 972 uint32_t pix_clk_khz,/* for current stream */ 973 uint32_t total_stream_num) 974{ 975 uint32_t addr; 976 uint32_t value; 977 uint32_t pix_dur; 978 if (pix_clk_khz != 0) { 979 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1; 980 value = dm_read_reg(mi->ctx, addr); 981 pix_dur = 1000000000ULL / pix_clk_khz; 982 set_reg_field_value( 983 value, 984 pix_dur, 985 DPGV0_PIPE_ARBITRATION_CONTROL1, 986 PIXEL_DURATION); 987 dm_write_reg(mi->ctx, addr, value); 988 989 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1; 990 value = dm_read_reg(mi->ctx, addr); 991 pix_dur = 1000000000ULL / pix_clk_khz; 992 set_reg_field_value( 993 value, 994 pix_dur, 995 DPGV1_PIPE_ARBITRATION_CONTROL1, 996 PIXEL_DURATION); 997 dm_write_reg(mi->ctx, addr, value); 998 999 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2; 1000 value = 0x4000800; 1001 dm_write_reg(mi->ctx, addr, value); 1002 1003 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2; 1004 value = 0x4000800; 1005 dm_write_reg(mi->ctx, addr, value); 1006 } 1007 1008} 1009 1010static void dce110_free_mem_input_v( 1011 struct mem_input *mi, 1012 uint32_t total_stream_num) 1013{ 1014} 1015 1016static const struct mem_input_funcs dce110_mem_input_v_funcs = { 1017 .mem_input_program_display_marks = 1018 dce_mem_input_v_program_display_marks, 1019 .mem_input_program_chroma_display_marks = 1020 dce_mem_input_program_chroma_display_marks, 1021 .allocate_mem_input = dce110_allocate_mem_input_v, 1022 .free_mem_input = dce110_free_mem_input_v, 1023 .mem_input_program_surface_flip_and_addr = 1024 dce_mem_input_v_program_surface_flip_and_addr, 1025 .mem_input_program_pte_vm = 1026 dce_mem_input_v_program_pte_vm, 1027 .mem_input_program_surface_config = 1028 dce_mem_input_v_program_surface_config, 1029 .mem_input_is_flip_pending = 1030 dce_mem_input_v_is_surface_pending 1031}; 1032/*****************************************/ 1033/* Constructor, Destructor */ 1034/*****************************************/ 1035 1036void dce110_mem_input_v_construct( 1037 struct dce_mem_input *dce_mi, 1038 struct dc_context *ctx) 1039{ 1040 dce_mi->base.funcs = &dce110_mem_input_v_funcs; 1041 dce_mi->base.ctx = ctx; 1042} 1043