1 /* 2 * Copyright 2012-15 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 26 #include "dm_services.h" 27 28 /* include DCE11 register header files */ 29 #include "dce/dce_11_0_d.h" 30 #include "dce/dce_11_0_sh_mask.h" 31 32 #include "dc_types.h" 33 #include "dc_bios_types.h" 34 #include "dc.h" 35 36 #include "include/grph_object_id.h" 37 #include "include/logger_interface.h" 38 #include "dce110_timing_generator.h" 39 40 #include "timing_generator.h" 41 42 43 #define NUMBER_OF_FRAME_TO_WAIT_ON_TRIGGERED_RESET 10 44 45 #define MAX_H_TOTAL (CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1) 46 #define MAX_V_TOTAL (CRTC_V_TOTAL__CRTC_V_TOTAL_MASKhw + 1) 47 48 #define CRTC_REG(reg) (reg + tg110->offsets.crtc) 49 #define DCP_REG(reg) (reg + tg110->offsets.dcp) 50 51 /* Flowing register offsets are same in files of 52 * dce/dce_11_0_d.h 53 * dce/vi_polaris10_p/vi_polaris10_d.h 54 * 55 * So we can create dce110 timing generator to use it. 56 */ 57 58 59 /* 60 * apply_front_porch_workaround 61 * 62 * This is a workaround for a bug that has existed since R5xx and has not been 63 * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive. 64 */ 65 static void dce110_timing_generator_apply_front_porch_workaround( 66 struct timing_generator *tg, 67 struct dc_crtc_timing *timing) 68 { 69 if (timing->flags.INTERLACE == 1) { 70 if (timing->v_front_porch < 2) 71 timing->v_front_porch = 2; 72 } else { 73 if (timing->v_front_porch < 1) 74 timing->v_front_porch = 1; 75 } 76 } 77 78 /** 79 ***************************************************************************** 80 * Function: is_in_vertical_blank 81 * 82 * @brief 83 * check the current status of CRTC to check if we are in Vertical Blank 84 * regioneased" state 85 * 86 * @return 87 * true if currently in blank region, false otherwise 88 * 89 ***************************************************************************** 90 */ 91 static bool dce110_timing_generator_is_in_vertical_blank( 92 struct timing_generator *tg) 93 { 94 uint32_t addr = 0; 95 uint32_t value = 0; 96 uint32_t field = 0; 97 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 98 99 addr = CRTC_REG(mmCRTC_STATUS); 100 value = dm_read_reg(tg->ctx, addr); 101 field = get_reg_field_value(value, CRTC_STATUS, CRTC_V_BLANK); 102 return field == 1; 103 } 104 105 void dce110_timing_generator_set_early_control( 106 struct timing_generator *tg, 107 uint32_t early_cntl) 108 { 109 uint32_t regval; 110 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 111 uint32_t address = CRTC_REG(mmCRTC_CONTROL); 112 113 regval = dm_read_reg(tg->ctx, address); 114 set_reg_field_value(regval, early_cntl, 115 CRTC_CONTROL, CRTC_HBLANK_EARLY_CONTROL); 116 dm_write_reg(tg->ctx, address, regval); 117 } 118 119 /** 120 * Enable CRTC 121 * Enable CRTC - call ASIC Control Object to enable Timing generator. 122 */ 123 bool dce110_timing_generator_enable_crtc(struct timing_generator *tg) 124 { 125 enum bp_result result; 126 127 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 128 uint32_t value = 0; 129 130 /* 131 * 3 is used to make sure V_UPDATE occurs at the beginning of the first 132 * line of vertical front porch 133 */ 134 set_reg_field_value( 135 value, 136 0, 137 CRTC_MASTER_UPDATE_MODE, 138 MASTER_UPDATE_MODE); 139 140 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value); 141 142 /* TODO: may want this on to catch underflow */ 143 value = 0; 144 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK), value); 145 146 result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true); 147 148 return result == BP_RESULT_OK; 149 } 150 151 void dce110_timing_generator_program_blank_color( 152 struct timing_generator *tg, 153 const struct tg_color *black_color) 154 { 155 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 156 uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR); 157 uint32_t value = dm_read_reg(tg->ctx, addr); 158 159 set_reg_field_value( 160 value, 161 black_color->color_b_cb, 162 CRTC_BLACK_COLOR, 163 CRTC_BLACK_COLOR_B_CB); 164 set_reg_field_value( 165 value, 166 black_color->color_g_y, 167 CRTC_BLACK_COLOR, 168 CRTC_BLACK_COLOR_G_Y); 169 set_reg_field_value( 170 value, 171 black_color->color_r_cr, 172 CRTC_BLACK_COLOR, 173 CRTC_BLACK_COLOR_R_CR); 174 175 dm_write_reg(tg->ctx, addr, value); 176 } 177 178 /** 179 ***************************************************************************** 180 * Function: disable_stereo 181 * 182 * @brief 183 * Disables active stereo on controller 184 * Frame Packing need to be disabled in vBlank or when CRTC not running 185 ***************************************************************************** 186 */ 187 #if 0 188 @TODOSTEREO 189 static void disable_stereo(struct timing_generator *tg) 190 { 191 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 192 uint32_t addr = CRTC_REG(mmCRTC_3D_STRUCTURE_CONTROL); 193 uint32_t value = 0; 194 uint32_t test = 0; 195 uint32_t field = 0; 196 uint32_t struc_en = 0; 197 uint32_t struc_stereo_sel_ovr = 0; 198 199 value = dm_read_reg(tg->ctx, addr); 200 struc_en = get_reg_field_value( 201 value, 202 CRTC_3D_STRUCTURE_CONTROL, 203 CRTC_3D_STRUCTURE_EN); 204 205 struc_stereo_sel_ovr = get_reg_field_value( 206 value, 207 CRTC_3D_STRUCTURE_CONTROL, 208 CRTC_3D_STRUCTURE_STEREO_SEL_OVR); 209 210 /* 211 * When disabling Frame Packing in 2 step mode, we need to program both 212 * registers at the same frame 213 * Programming it in the beginning of VActive makes sure we are ok 214 */ 215 216 if (struc_en != 0 && struc_stereo_sel_ovr == 0) { 217 tg->funcs->wait_for_vblank(tg); 218 tg->funcs->wait_for_vactive(tg); 219 } 220 221 value = 0; 222 dm_write_reg(tg->ctx, addr, value); 223 224 addr = tg->regs[IDX_CRTC_STEREO_CONTROL]; 225 dm_write_reg(tg->ctx, addr, value); 226 } 227 #endif 228 229 /** 230 * disable_crtc - call ASIC Control Object to disable Timing generator. 231 */ 232 bool dce110_timing_generator_disable_crtc(struct timing_generator *tg) 233 { 234 enum bp_result result; 235 236 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 237 238 result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, false); 239 240 /* Need to make sure stereo is disabled according to the DCE5.0 spec */ 241 242 /* 243 * @TODOSTEREO call this when adding stereo support 244 * tg->funcs->disable_stereo(tg); 245 */ 246 247 return result == BP_RESULT_OK; 248 } 249 250 /** 251 * program_horz_count_by_2 252 * Programs DxCRTC_HORZ_COUNT_BY2_EN - 1 for DVI 30bpp mode, 0 otherwise 253 * 254 */ 255 static void program_horz_count_by_2( 256 struct timing_generator *tg, 257 const struct dc_crtc_timing *timing) 258 { 259 uint32_t regval; 260 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 261 262 regval = dm_read_reg(tg->ctx, 263 CRTC_REG(mmCRTC_COUNT_CONTROL)); 264 265 set_reg_field_value(regval, 0, CRTC_COUNT_CONTROL, 266 CRTC_HORZ_COUNT_BY2_EN); 267 268 if (timing->flags.HORZ_COUNT_BY_TWO) 269 set_reg_field_value(regval, 1, CRTC_COUNT_CONTROL, 270 CRTC_HORZ_COUNT_BY2_EN); 271 272 dm_write_reg(tg->ctx, 273 CRTC_REG(mmCRTC_COUNT_CONTROL), regval); 274 } 275 276 /** 277 * program_timing_generator 278 * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition. 279 * Call ASIC Control Object to program Timings. 280 */ 281 bool dce110_timing_generator_program_timing_generator( 282 struct timing_generator *tg, 283 const struct dc_crtc_timing *dc_crtc_timing) 284 { 285 enum bp_result result; 286 struct bp_hw_crtc_timing_parameters bp_params; 287 struct dc_crtc_timing patched_crtc_timing; 288 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 289 290 uint32_t vsync_offset = dc_crtc_timing->v_border_bottom + 291 dc_crtc_timing->v_front_porch; 292 uint32_t v_sync_start =dc_crtc_timing->v_addressable + vsync_offset; 293 294 uint32_t hsync_offset = dc_crtc_timing->h_border_right + 295 dc_crtc_timing->h_front_porch; 296 uint32_t h_sync_start = dc_crtc_timing->h_addressable + hsync_offset; 297 298 memset(&bp_params, 0, sizeof(struct bp_hw_crtc_timing_parameters)); 299 300 /* Due to an asic bug we need to apply the Front Porch workaround prior 301 * to programming the timing. 302 */ 303 304 patched_crtc_timing = *dc_crtc_timing; 305 306 dce110_timing_generator_apply_front_porch_workaround(tg, &patched_crtc_timing); 307 308 bp_params.controller_id = tg110->controller_id; 309 310 bp_params.h_total = patched_crtc_timing.h_total; 311 bp_params.h_addressable = 312 patched_crtc_timing.h_addressable; 313 bp_params.v_total = patched_crtc_timing.v_total; 314 bp_params.v_addressable = patched_crtc_timing.v_addressable; 315 316 bp_params.h_sync_start = h_sync_start; 317 bp_params.h_sync_width = patched_crtc_timing.h_sync_width; 318 bp_params.v_sync_start = v_sync_start; 319 bp_params.v_sync_width = patched_crtc_timing.v_sync_width; 320 321 /* Set overscan */ 322 bp_params.h_overscan_left = 323 patched_crtc_timing.h_border_left; 324 bp_params.h_overscan_right = 325 patched_crtc_timing.h_border_right; 326 bp_params.v_overscan_top = patched_crtc_timing.v_border_top; 327 bp_params.v_overscan_bottom = 328 patched_crtc_timing.v_border_bottom; 329 330 /* Set flags */ 331 if (patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY == 1) 332 bp_params.flags.HSYNC_POSITIVE_POLARITY = 1; 333 334 if (patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY == 1) 335 bp_params.flags.VSYNC_POSITIVE_POLARITY = 1; 336 337 if (patched_crtc_timing.flags.INTERLACE == 1) 338 bp_params.flags.INTERLACE = 1; 339 340 if (patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1) 341 bp_params.flags.HORZ_COUNT_BY_TWO = 1; 342 343 result = tg->bp->funcs->program_crtc_timing(tg->bp, &bp_params); 344 345 program_horz_count_by_2(tg, &patched_crtc_timing); 346 347 tg110->base.funcs->enable_advanced_request(tg, true, &patched_crtc_timing); 348 349 /* Enable stereo - only when we need to pack 3D frame. Other types 350 * of stereo handled in explicit call */ 351 352 return result == BP_RESULT_OK; 353 } 354 355 /** 356 ***************************************************************************** 357 * Function: set_drr 358 * 359 * @brief 360 * Program dynamic refresh rate registers m_DxCRTC_V_TOTAL_*. 361 * 362 * @param [in] pHwCrtcTiming: point to H 363 * wCrtcTiming struct 364 ***************************************************************************** 365 */ 366 void dce110_timing_generator_set_drr( 367 struct timing_generator *tg, 368 const struct drr_params *params) 369 { 370 /* register values */ 371 uint32_t v_total_min = 0; 372 uint32_t v_total_max = 0; 373 uint32_t v_total_cntl = 0; 374 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 375 376 uint32_t addr = 0; 377 378 addr = CRTC_REG(mmCRTC_V_TOTAL_MIN); 379 v_total_min = dm_read_reg(tg->ctx, addr); 380 381 addr = CRTC_REG(mmCRTC_V_TOTAL_MAX); 382 v_total_max = dm_read_reg(tg->ctx, addr); 383 384 addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL); 385 v_total_cntl = dm_read_reg(tg->ctx, addr); 386 387 if (params != NULL && 388 params->vertical_total_max > 0 && 389 params->vertical_total_min > 0) { 390 391 set_reg_field_value(v_total_max, 392 params->vertical_total_max - 1, 393 CRTC_V_TOTAL_MAX, 394 CRTC_V_TOTAL_MAX); 395 396 set_reg_field_value(v_total_min, 397 params->vertical_total_min - 1, 398 CRTC_V_TOTAL_MIN, 399 CRTC_V_TOTAL_MIN); 400 401 set_reg_field_value(v_total_cntl, 402 1, 403 CRTC_V_TOTAL_CONTROL, 404 CRTC_V_TOTAL_MIN_SEL); 405 406 set_reg_field_value(v_total_cntl, 407 1, 408 CRTC_V_TOTAL_CONTROL, 409 CRTC_V_TOTAL_MAX_SEL); 410 411 set_reg_field_value(v_total_cntl, 412 0, 413 CRTC_V_TOTAL_CONTROL, 414 CRTC_FORCE_LOCK_ON_EVENT); 415 set_reg_field_value(v_total_cntl, 416 0, 417 CRTC_V_TOTAL_CONTROL, 418 CRTC_FORCE_LOCK_TO_MASTER_VSYNC); 419 420 set_reg_field_value(v_total_cntl, 421 0, 422 CRTC_V_TOTAL_CONTROL, 423 CRTC_SET_V_TOTAL_MIN_MASK_EN); 424 425 set_reg_field_value(v_total_cntl, 426 0, 427 CRTC_V_TOTAL_CONTROL, 428 CRTC_SET_V_TOTAL_MIN_MASK); 429 } else { 430 set_reg_field_value(v_total_cntl, 431 0, 432 CRTC_V_TOTAL_CONTROL, 433 CRTC_SET_V_TOTAL_MIN_MASK); 434 set_reg_field_value(v_total_cntl, 435 0, 436 CRTC_V_TOTAL_CONTROL, 437 CRTC_V_TOTAL_MIN_SEL); 438 set_reg_field_value(v_total_cntl, 439 0, 440 CRTC_V_TOTAL_CONTROL, 441 CRTC_V_TOTAL_MAX_SEL); 442 set_reg_field_value(v_total_min, 443 0, 444 CRTC_V_TOTAL_MIN, 445 CRTC_V_TOTAL_MIN); 446 set_reg_field_value(v_total_max, 447 0, 448 CRTC_V_TOTAL_MAX, 449 CRTC_V_TOTAL_MAX); 450 set_reg_field_value(v_total_cntl, 451 0, 452 CRTC_V_TOTAL_CONTROL, 453 CRTC_FORCE_LOCK_ON_EVENT); 454 set_reg_field_value(v_total_cntl, 455 0, 456 CRTC_V_TOTAL_CONTROL, 457 CRTC_FORCE_LOCK_TO_MASTER_VSYNC); 458 } 459 460 addr = CRTC_REG(mmCRTC_V_TOTAL_MIN); 461 dm_write_reg(tg->ctx, addr, v_total_min); 462 463 addr = CRTC_REG(mmCRTC_V_TOTAL_MAX); 464 dm_write_reg(tg->ctx, addr, v_total_max); 465 466 addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL); 467 dm_write_reg(tg->ctx, addr, v_total_cntl); 468 } 469 470 void dce110_timing_generator_set_static_screen_control( 471 struct timing_generator *tg, 472 uint32_t value) 473 { 474 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 475 uint32_t static_screen_cntl = 0; 476 uint32_t addr = 0; 477 478 addr = CRTC_REG(mmCRTC_STATIC_SCREEN_CONTROL); 479 static_screen_cntl = dm_read_reg(tg->ctx, addr); 480 481 set_reg_field_value(static_screen_cntl, 482 value, 483 CRTC_STATIC_SCREEN_CONTROL, 484 CRTC_STATIC_SCREEN_EVENT_MASK); 485 486 set_reg_field_value(static_screen_cntl, 487 2, 488 CRTC_STATIC_SCREEN_CONTROL, 489 CRTC_STATIC_SCREEN_FRAME_COUNT); 490 491 dm_write_reg(tg->ctx, addr, static_screen_cntl); 492 } 493 494 /* 495 * get_vblank_counter 496 * 497 * @brief 498 * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which 499 * holds the counter of frames. 500 * 501 * @param 502 * struct timing_generator *tg - [in] timing generator which controls the 503 * desired CRTC 504 * 505 * @return 506 * Counter of frames, which should equal to number of vblanks. 507 */ 508 uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg) 509 { 510 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 511 uint32_t addr = CRTC_REG(mmCRTC_STATUS_FRAME_COUNT); 512 uint32_t value = dm_read_reg(tg->ctx, addr); 513 uint32_t field = get_reg_field_value( 514 value, CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT); 515 516 return field; 517 } 518 519 /** 520 ***************************************************************************** 521 * Function: dce110_timing_generator_get_position 522 * 523 * @brief 524 * Returns CRTC vertical/horizontal counters 525 * 526 * @param [out] position 527 ***************************************************************************** 528 */ 529 void dce110_timing_generator_get_position(struct timing_generator *tg, 530 struct crtc_position *position) 531 { 532 uint32_t value; 533 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 534 535 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_STATUS_POSITION)); 536 537 position->horizontal_count = get_reg_field_value( 538 value, 539 CRTC_STATUS_POSITION, 540 CRTC_HORZ_COUNT); 541 542 position->vertical_count = get_reg_field_value( 543 value, 544 CRTC_STATUS_POSITION, 545 CRTC_VERT_COUNT); 546 547 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_NOM_VERT_POSITION)); 548 549 position->nominal_vcount = get_reg_field_value( 550 value, 551 CRTC_NOM_VERT_POSITION, 552 CRTC_VERT_COUNT_NOM); 553 } 554 555 /** 556 ***************************************************************************** 557 * Function: get_crtc_scanoutpos 558 * 559 * @brief 560 * Returns CRTC vertical/horizontal counters 561 * 562 * @param [out] vpos, hpos 563 ***************************************************************************** 564 */ 565 void dce110_timing_generator_get_crtc_scanoutpos( 566 struct timing_generator *tg, 567 uint32_t *v_blank_start, 568 uint32_t *v_blank_end, 569 uint32_t *h_position, 570 uint32_t *v_position) 571 { 572 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 573 struct crtc_position position; 574 575 uint32_t value = dm_read_reg(tg->ctx, 576 CRTC_REG(mmCRTC_V_BLANK_START_END)); 577 578 *v_blank_start = get_reg_field_value(value, 579 CRTC_V_BLANK_START_END, 580 CRTC_V_BLANK_START); 581 *v_blank_end = get_reg_field_value(value, 582 CRTC_V_BLANK_START_END, 583 CRTC_V_BLANK_END); 584 585 dce110_timing_generator_get_position( 586 tg, &position); 587 588 *h_position = position.horizontal_count; 589 *v_position = position.vertical_count; 590 } 591 592 /* TODO: is it safe to assume that mask/shift of Primary and Underlay 593 * are the same? 594 * For example: today CRTC_H_TOTAL == CRTCV_H_TOTAL but is it always 595 * guaranteed? */ 596 void dce110_timing_generator_program_blanking( 597 struct timing_generator *tg, 598 const struct dc_crtc_timing *timing) 599 { 600 uint32_t vsync_offset = timing->v_border_bottom + 601 timing->v_front_porch; 602 uint32_t v_sync_start =timing->v_addressable + vsync_offset; 603 604 uint32_t hsync_offset = timing->h_border_right + 605 timing->h_front_porch; 606 uint32_t h_sync_start = timing->h_addressable + hsync_offset; 607 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 608 609 struct dc_context *ctx = tg->ctx; 610 uint32_t value = 0; 611 uint32_t addr = 0; 612 uint32_t tmp = 0; 613 614 addr = CRTC_REG(mmCRTC_H_TOTAL); 615 value = dm_read_reg(ctx, addr); 616 set_reg_field_value( 617 value, 618 timing->h_total - 1, 619 CRTC_H_TOTAL, 620 CRTC_H_TOTAL); 621 dm_write_reg(ctx, addr, value); 622 623 addr = CRTC_REG(mmCRTC_V_TOTAL); 624 value = dm_read_reg(ctx, addr); 625 set_reg_field_value( 626 value, 627 timing->v_total - 1, 628 CRTC_V_TOTAL, 629 CRTC_V_TOTAL); 630 dm_write_reg(ctx, addr, value); 631 632 /* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and 633 * V_TOTAL_MIN are equal to V_TOTAL. 634 */ 635 addr = CRTC_REG(mmCRTC_V_TOTAL_MAX); 636 value = dm_read_reg(ctx, addr); 637 set_reg_field_value( 638 value, 639 timing->v_total - 1, 640 CRTC_V_TOTAL_MAX, 641 CRTC_V_TOTAL_MAX); 642 dm_write_reg(ctx, addr, value); 643 644 addr = CRTC_REG(mmCRTC_V_TOTAL_MIN); 645 value = dm_read_reg(ctx, addr); 646 set_reg_field_value( 647 value, 648 timing->v_total - 1, 649 CRTC_V_TOTAL_MIN, 650 CRTC_V_TOTAL_MIN); 651 dm_write_reg(ctx, addr, value); 652 653 addr = CRTC_REG(mmCRTC_H_BLANK_START_END); 654 value = dm_read_reg(ctx, addr); 655 656 tmp = timing->h_total - 657 (h_sync_start + timing->h_border_left); 658 659 set_reg_field_value( 660 value, 661 tmp, 662 CRTC_H_BLANK_START_END, 663 CRTC_H_BLANK_END); 664 665 tmp = tmp + timing->h_addressable + 666 timing->h_border_left + timing->h_border_right; 667 668 set_reg_field_value( 669 value, 670 tmp, 671 CRTC_H_BLANK_START_END, 672 CRTC_H_BLANK_START); 673 674 dm_write_reg(ctx, addr, value); 675 676 addr = CRTC_REG(mmCRTC_V_BLANK_START_END); 677 value = dm_read_reg(ctx, addr); 678 679 tmp = timing->v_total - (v_sync_start + timing->v_border_top); 680 681 set_reg_field_value( 682 value, 683 tmp, 684 CRTC_V_BLANK_START_END, 685 CRTC_V_BLANK_END); 686 687 tmp = tmp + timing->v_addressable + timing->v_border_top + 688 timing->v_border_bottom; 689 690 set_reg_field_value( 691 value, 692 tmp, 693 CRTC_V_BLANK_START_END, 694 CRTC_V_BLANK_START); 695 696 dm_write_reg(ctx, addr, value); 697 } 698 699 void dce110_timing_generator_set_test_pattern( 700 struct timing_generator *tg, 701 /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' 702 * because this is not DP-specific (which is probably somewhere in DP 703 * encoder) */ 704 enum controller_dp_test_pattern test_pattern, 705 enum dc_color_depth color_depth) 706 { 707 struct dc_context *ctx = tg->ctx; 708 uint32_t value; 709 uint32_t addr; 710 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 711 enum test_pattern_color_format bit_depth; 712 enum test_pattern_dyn_range dyn_range; 713 enum test_pattern_mode mode; 714 /* color ramp generator mixes 16-bits color */ 715 uint32_t src_bpc = 16; 716 /* requested bpc */ 717 uint32_t dst_bpc; 718 uint32_t index; 719 /* RGB values of the color bars. 720 * Produce two RGB colors: RGB0 - white (all Fs) 721 * and RGB1 - black (all 0s) 722 * (three RGB components for two colors) 723 */ 724 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 725 0x0000, 0x0000}; 726 /* dest color (converted to the specified color format) */ 727 uint16_t dst_color[6]; 728 uint32_t inc_base; 729 730 /* translate to bit depth */ 731 switch (color_depth) { 732 case COLOR_DEPTH_666: 733 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; 734 break; 735 case COLOR_DEPTH_888: 736 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 737 break; 738 case COLOR_DEPTH_101010: 739 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; 740 break; 741 case COLOR_DEPTH_121212: 742 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; 743 break; 744 default: 745 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 746 break; 747 } 748 749 switch (test_pattern) { 750 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: 751 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: 752 { 753 dyn_range = (test_pattern == 754 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? 755 TEST_PATTERN_DYN_RANGE_CEA : 756 TEST_PATTERN_DYN_RANGE_VESA); 757 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; 758 value = 0; 759 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS); 760 761 set_reg_field_value( 762 value, 763 6, 764 CRTC_TEST_PATTERN_PARAMETERS, 765 CRTC_TEST_PATTERN_VRES); 766 set_reg_field_value( 767 value, 768 6, 769 CRTC_TEST_PATTERN_PARAMETERS, 770 CRTC_TEST_PATTERN_HRES); 771 772 dm_write_reg(ctx, addr, value); 773 774 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL); 775 value = 0; 776 777 set_reg_field_value( 778 value, 779 1, 780 CRTC_TEST_PATTERN_CONTROL, 781 CRTC_TEST_PATTERN_EN); 782 783 set_reg_field_value( 784 value, 785 mode, 786 CRTC_TEST_PATTERN_CONTROL, 787 CRTC_TEST_PATTERN_MODE); 788 789 set_reg_field_value( 790 value, 791 dyn_range, 792 CRTC_TEST_PATTERN_CONTROL, 793 CRTC_TEST_PATTERN_DYNAMIC_RANGE); 794 set_reg_field_value( 795 value, 796 bit_depth, 797 CRTC_TEST_PATTERN_CONTROL, 798 CRTC_TEST_PATTERN_COLOR_FORMAT); 799 dm_write_reg(ctx, addr, value); 800 } 801 break; 802 803 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: 804 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: 805 { 806 mode = (test_pattern == 807 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? 808 TEST_PATTERN_MODE_VERTICALBARS : 809 TEST_PATTERN_MODE_HORIZONTALBARS); 810 811 switch (bit_depth) { 812 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 813 dst_bpc = 6; 814 break; 815 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 816 dst_bpc = 8; 817 break; 818 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 819 dst_bpc = 10; 820 break; 821 default: 822 dst_bpc = 8; 823 break; 824 } 825 826 /* adjust color to the required colorFormat */ 827 for (index = 0; index < 6; index++) { 828 /* dst = 2^dstBpc * src / 2^srcBpc = src >> 829 * (srcBpc - dstBpc); 830 */ 831 dst_color[index] = 832 src_color[index] >> (src_bpc - dst_bpc); 833 /* CRTC_TEST_PATTERN_DATA has 16 bits, 834 * lowest 6 are hardwired to ZERO 835 * color bits should be left aligned aligned to MSB 836 * XXXXXXXXXX000000 for 10 bit, 837 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6 838 */ 839 dst_color[index] <<= (16 - dst_bpc); 840 } 841 842 value = 0; 843 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS); 844 dm_write_reg(ctx, addr, value); 845 846 /* We have to write the mask before data, similar to pipeline. 847 * For example, for 8 bpc, if we want RGB0 to be magenta, 848 * and RGB1 to be cyan, 849 * we need to make 7 writes: 850 * MASK DATA 851 * 000001 00000000 00000000 set mask to R0 852 * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0 853 * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0 854 * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1 855 * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1 856 * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1 857 * 100000 11111111 00000000 B1 255, 0xFF00 858 * 859 * we will make a loop of 6 in which we prepare the mask, 860 * then write, then prepare the color for next write. 861 * first iteration will write mask only, 862 * but each next iteration color prepared in 863 * previous iteration will be written within new mask, 864 * the last component will written separately, 865 * mask is not changing between 6th and 7th write 866 * and color will be prepared by last iteration 867 */ 868 869 /* write color, color values mask in CRTC_TEST_PATTERN_MASK 870 * is B1, G1, R1, B0, G0, R0 871 */ 872 value = 0; 873 addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR); 874 for (index = 0; index < 6; index++) { 875 /* prepare color mask, first write PATTERN_DATA 876 * will have all zeros 877 */ 878 set_reg_field_value( 879 value, 880 (1 << index), 881 CRTC_TEST_PATTERN_COLOR, 882 CRTC_TEST_PATTERN_MASK); 883 /* write color component */ 884 dm_write_reg(ctx, addr, value); 885 /* prepare next color component, 886 * will be written in the next iteration 887 */ 888 set_reg_field_value( 889 value, 890 dst_color[index], 891 CRTC_TEST_PATTERN_COLOR, 892 CRTC_TEST_PATTERN_DATA); 893 } 894 /* write last color component, 895 * it's been already prepared in the loop 896 */ 897 dm_write_reg(ctx, addr, value); 898 899 /* enable test pattern */ 900 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL); 901 value = 0; 902 903 set_reg_field_value( 904 value, 905 1, 906 CRTC_TEST_PATTERN_CONTROL, 907 CRTC_TEST_PATTERN_EN); 908 909 set_reg_field_value( 910 value, 911 mode, 912 CRTC_TEST_PATTERN_CONTROL, 913 CRTC_TEST_PATTERN_MODE); 914 915 set_reg_field_value( 916 value, 917 0, 918 CRTC_TEST_PATTERN_CONTROL, 919 CRTC_TEST_PATTERN_DYNAMIC_RANGE); 920 921 set_reg_field_value( 922 value, 923 bit_depth, 924 CRTC_TEST_PATTERN_CONTROL, 925 CRTC_TEST_PATTERN_COLOR_FORMAT); 926 927 dm_write_reg(ctx, addr, value); 928 } 929 break; 930 931 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: 932 { 933 mode = (bit_depth == 934 TEST_PATTERN_COLOR_FORMAT_BPC_10 ? 935 TEST_PATTERN_MODE_DUALRAMP_RGB : 936 TEST_PATTERN_MODE_SINGLERAMP_RGB); 937 938 switch (bit_depth) { 939 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 940 dst_bpc = 6; 941 break; 942 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 943 dst_bpc = 8; 944 break; 945 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 946 dst_bpc = 10; 947 break; 948 default: 949 dst_bpc = 8; 950 break; 951 } 952 953 /* increment for the first ramp for one color gradation 954 * 1 gradation for 6-bit color is 2^10 955 * gradations in 16-bit color 956 */ 957 inc_base = (src_bpc - dst_bpc); 958 959 value = 0; 960 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS); 961 962 switch (bit_depth) { 963 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 964 { 965 set_reg_field_value( 966 value, 967 inc_base, 968 CRTC_TEST_PATTERN_PARAMETERS, 969 CRTC_TEST_PATTERN_INC0); 970 set_reg_field_value( 971 value, 972 0, 973 CRTC_TEST_PATTERN_PARAMETERS, 974 CRTC_TEST_PATTERN_INC1); 975 set_reg_field_value( 976 value, 977 6, 978 CRTC_TEST_PATTERN_PARAMETERS, 979 CRTC_TEST_PATTERN_HRES); 980 set_reg_field_value( 981 value, 982 6, 983 CRTC_TEST_PATTERN_PARAMETERS, 984 CRTC_TEST_PATTERN_VRES); 985 set_reg_field_value( 986 value, 987 0, 988 CRTC_TEST_PATTERN_PARAMETERS, 989 CRTC_TEST_PATTERN_RAMP0_OFFSET); 990 } 991 break; 992 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 993 { 994 set_reg_field_value( 995 value, 996 inc_base, 997 CRTC_TEST_PATTERN_PARAMETERS, 998 CRTC_TEST_PATTERN_INC0); 999 set_reg_field_value( 1000 value, 1001 0, 1002 CRTC_TEST_PATTERN_PARAMETERS, 1003 CRTC_TEST_PATTERN_INC1); 1004 set_reg_field_value( 1005 value, 1006 8, 1007 CRTC_TEST_PATTERN_PARAMETERS, 1008 CRTC_TEST_PATTERN_HRES); 1009 set_reg_field_value( 1010 value, 1011 6, 1012 CRTC_TEST_PATTERN_PARAMETERS, 1013 CRTC_TEST_PATTERN_VRES); 1014 set_reg_field_value( 1015 value, 1016 0, 1017 CRTC_TEST_PATTERN_PARAMETERS, 1018 CRTC_TEST_PATTERN_RAMP0_OFFSET); 1019 } 1020 break; 1021 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1022 { 1023 set_reg_field_value( 1024 value, 1025 inc_base, 1026 CRTC_TEST_PATTERN_PARAMETERS, 1027 CRTC_TEST_PATTERN_INC0); 1028 set_reg_field_value( 1029 value, 1030 inc_base + 2, 1031 CRTC_TEST_PATTERN_PARAMETERS, 1032 CRTC_TEST_PATTERN_INC1); 1033 set_reg_field_value( 1034 value, 1035 8, 1036 CRTC_TEST_PATTERN_PARAMETERS, 1037 CRTC_TEST_PATTERN_HRES); 1038 set_reg_field_value( 1039 value, 1040 5, 1041 CRTC_TEST_PATTERN_PARAMETERS, 1042 CRTC_TEST_PATTERN_VRES); 1043 set_reg_field_value( 1044 value, 1045 384 << 6, 1046 CRTC_TEST_PATTERN_PARAMETERS, 1047 CRTC_TEST_PATTERN_RAMP0_OFFSET); 1048 } 1049 break; 1050 default: 1051 break; 1052 } 1053 dm_write_reg(ctx, addr, value); 1054 1055 value = 0; 1056 addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR); 1057 dm_write_reg(ctx, addr, value); 1058 1059 /* enable test pattern */ 1060 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL); 1061 value = 0; 1062 1063 set_reg_field_value( 1064 value, 1065 1, 1066 CRTC_TEST_PATTERN_CONTROL, 1067 CRTC_TEST_PATTERN_EN); 1068 1069 set_reg_field_value( 1070 value, 1071 mode, 1072 CRTC_TEST_PATTERN_CONTROL, 1073 CRTC_TEST_PATTERN_MODE); 1074 1075 set_reg_field_value( 1076 value, 1077 0, 1078 CRTC_TEST_PATTERN_CONTROL, 1079 CRTC_TEST_PATTERN_DYNAMIC_RANGE); 1080 /* add color depth translation here */ 1081 set_reg_field_value( 1082 value, 1083 bit_depth, 1084 CRTC_TEST_PATTERN_CONTROL, 1085 CRTC_TEST_PATTERN_COLOR_FORMAT); 1086 1087 dm_write_reg(ctx, addr, value); 1088 } 1089 break; 1090 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: 1091 { 1092 value = 0; 1093 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL), value); 1094 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_COLOR), value); 1095 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS), 1096 value); 1097 } 1098 break; 1099 default: 1100 break; 1101 } 1102 } 1103 1104 /** 1105 * dce110_timing_generator_validate_timing 1106 * The timing generators support a maximum display size of is 8192 x 8192 pixels, 1107 * including both active display and blanking periods. Check H Total and V Total. 1108 */ 1109 bool dce110_timing_generator_validate_timing( 1110 struct timing_generator *tg, 1111 const struct dc_crtc_timing *timing, 1112 enum signal_type signal) 1113 { 1114 uint32_t h_blank; 1115 uint32_t h_back_porch, hsync_offset, h_sync_start; 1116 1117 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1118 1119 ASSERT(timing != NULL); 1120 1121 if (!timing) 1122 return false; 1123 1124 hsync_offset = timing->h_border_right + timing->h_front_porch; 1125 h_sync_start = timing->h_addressable + hsync_offset; 1126 1127 /* Currently we don't support 3D, so block all 3D timings */ 1128 if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE) 1129 return false; 1130 1131 /* Temporarily blocking interlacing mode until it's supported */ 1132 if (timing->flags.INTERLACE == 1) 1133 return false; 1134 1135 /* Check maximum number of pixels supported by Timing Generator 1136 * (Currently will never fail, in order to fail needs display which 1137 * needs more than 8192 horizontal and 1138 * more than 8192 vertical total pixels) 1139 */ 1140 if (timing->h_total > tg110->max_h_total || 1141 timing->v_total > tg110->max_v_total) 1142 return false; 1143 1144 h_blank = (timing->h_total - timing->h_addressable - 1145 timing->h_border_right - 1146 timing->h_border_left); 1147 1148 if (h_blank < tg110->min_h_blank) 1149 return false; 1150 1151 if (timing->h_front_porch < tg110->min_h_front_porch) 1152 return false; 1153 1154 h_back_porch = h_blank - (h_sync_start - 1155 timing->h_addressable - 1156 timing->h_border_right - 1157 timing->h_sync_width); 1158 1159 if (h_back_porch < tg110->min_h_back_porch) 1160 return false; 1161 1162 return true; 1163 } 1164 1165 /** 1166 * Wait till we are at the beginning of VBlank. 1167 */ 1168 void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg) 1169 { 1170 /* We want to catch beginning of VBlank here, so if the first try are 1171 * in VBlank, we might be very close to Active, in this case wait for 1172 * another frame 1173 */ 1174 while (dce110_timing_generator_is_in_vertical_blank(tg)) { 1175 if (!dce110_timing_generator_is_counter_moving(tg)) { 1176 /* error - no point to wait if counter is not moving */ 1177 break; 1178 } 1179 } 1180 1181 while (!dce110_timing_generator_is_in_vertical_blank(tg)) { 1182 if (!dce110_timing_generator_is_counter_moving(tg)) { 1183 /* error - no point to wait if counter is not moving */ 1184 break; 1185 } 1186 } 1187 } 1188 1189 /** 1190 * Wait till we are in VActive (anywhere in VActive) 1191 */ 1192 void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg) 1193 { 1194 while (dce110_timing_generator_is_in_vertical_blank(tg)) { 1195 if (!dce110_timing_generator_is_counter_moving(tg)) { 1196 /* error - no point to wait if counter is not moving */ 1197 break; 1198 } 1199 } 1200 } 1201 1202 /** 1203 ***************************************************************************** 1204 * Function: dce110_timing_generator_setup_global_swap_lock 1205 * 1206 * @brief 1207 * Setups Global Swap Lock group for current pipe 1208 * Pipe can join or leave GSL group, become a TimingServer or TimingClient 1209 * 1210 * @param [in] gsl_params: setup data 1211 ***************************************************************************** 1212 */ 1213 1214 void dce110_timing_generator_setup_global_swap_lock( 1215 struct timing_generator *tg, 1216 const struct dcp_gsl_params *gsl_params) 1217 { 1218 uint32_t value; 1219 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1220 uint32_t address = DCP_REG(mmDCP_GSL_CONTROL); 1221 uint32_t check_point = FLIP_READY_BACK_LOOKUP; 1222 1223 value = dm_read_reg(tg->ctx, address); 1224 1225 /* This pipe will belong to GSL Group zero. */ 1226 set_reg_field_value(value, 1227 1, 1228 DCP_GSL_CONTROL, 1229 DCP_GSL0_EN); 1230 1231 set_reg_field_value(value, 1232 gsl_params->gsl_master == tg->inst, 1233 DCP_GSL_CONTROL, 1234 DCP_GSL_MASTER_EN); 1235 1236 set_reg_field_value(value, 1237 HFLIP_READY_DELAY, 1238 DCP_GSL_CONTROL, 1239 DCP_GSL_HSYNC_FLIP_FORCE_DELAY); 1240 1241 /* Keep signal low (pending high) during 6 lines. 1242 * Also defines minimum interval before re-checking signal. */ 1243 set_reg_field_value(value, 1244 HFLIP_CHECK_DELAY, 1245 DCP_GSL_CONTROL, 1246 DCP_GSL_HSYNC_FLIP_CHECK_DELAY); 1247 1248 dm_write_reg(tg->ctx, CRTC_REG(mmDCP_GSL_CONTROL), value); 1249 value = 0; 1250 1251 set_reg_field_value(value, 1252 gsl_params->gsl_master, 1253 DCIO_GSL0_CNTL, 1254 DCIO_GSL0_VSYNC_SEL); 1255 1256 set_reg_field_value(value, 1257 0, 1258 DCIO_GSL0_CNTL, 1259 DCIO_GSL0_TIMING_SYNC_SEL); 1260 1261 set_reg_field_value(value, 1262 0, 1263 DCIO_GSL0_CNTL, 1264 DCIO_GSL0_GLOBAL_UNLOCK_SEL); 1265 1266 dm_write_reg(tg->ctx, CRTC_REG(mmDCIO_GSL0_CNTL), value); 1267 1268 1269 { 1270 uint32_t value_crtc_vtotal; 1271 1272 value_crtc_vtotal = dm_read_reg(tg->ctx, 1273 CRTC_REG(mmCRTC_V_TOTAL)); 1274 1275 set_reg_field_value(value, 1276 0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */ 1277 DCP_GSL_CONTROL, 1278 DCP_GSL_SYNC_SOURCE); 1279 1280 /* Checkpoint relative to end of frame */ 1281 check_point = get_reg_field_value(value_crtc_vtotal, 1282 CRTC_V_TOTAL, 1283 CRTC_V_TOTAL); 1284 1285 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0); 1286 } 1287 1288 set_reg_field_value(value, 1289 1, 1290 DCP_GSL_CONTROL, 1291 DCP_GSL_DELAY_SURFACE_UPDATE_PENDING); 1292 1293 dm_write_reg(tg->ctx, address, value); 1294 1295 /********************************************************************/ 1296 address = CRTC_REG(mmCRTC_GSL_CONTROL); 1297 1298 value = dm_read_reg(tg->ctx, address); 1299 set_reg_field_value(value, 1300 check_point - FLIP_READY_BACK_LOOKUP, 1301 CRTC_GSL_CONTROL, 1302 CRTC_GSL_CHECK_LINE_NUM); 1303 1304 set_reg_field_value(value, 1305 VFLIP_READY_DELAY, 1306 CRTC_GSL_CONTROL, 1307 CRTC_GSL_FORCE_DELAY); 1308 1309 dm_write_reg(tg->ctx, address, value); 1310 } 1311 1312 void dce110_timing_generator_tear_down_global_swap_lock( 1313 struct timing_generator *tg) 1314 { 1315 /* Clear all the register writes done by 1316 * dce110_timing_generator_setup_global_swap_lock 1317 */ 1318 1319 uint32_t value; 1320 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1321 uint32_t address = DCP_REG(mmDCP_GSL_CONTROL); 1322 1323 value = 0; 1324 1325 /* This pipe will belong to GSL Group zero. */ 1326 /* Settig HW default values from reg specs */ 1327 set_reg_field_value(value, 1328 0, 1329 DCP_GSL_CONTROL, 1330 DCP_GSL0_EN); 1331 1332 set_reg_field_value(value, 1333 0, 1334 DCP_GSL_CONTROL, 1335 DCP_GSL_MASTER_EN); 1336 1337 set_reg_field_value(value, 1338 0x2, 1339 DCP_GSL_CONTROL, 1340 DCP_GSL_HSYNC_FLIP_FORCE_DELAY); 1341 1342 set_reg_field_value(value, 1343 0x6, 1344 DCP_GSL_CONTROL, 1345 DCP_GSL_HSYNC_FLIP_CHECK_DELAY); 1346 1347 /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */ 1348 { 1349 uint32_t value_crtc_vtotal; 1350 1351 value_crtc_vtotal = dm_read_reg(tg->ctx, 1352 CRTC_REG(mmCRTC_V_TOTAL)); 1353 1354 set_reg_field_value(value, 1355 0, 1356 DCP_GSL_CONTROL, 1357 DCP_GSL_SYNC_SOURCE); 1358 } 1359 1360 set_reg_field_value(value, 1361 0, 1362 DCP_GSL_CONTROL, 1363 DCP_GSL_DELAY_SURFACE_UPDATE_PENDING); 1364 1365 dm_write_reg(tg->ctx, address, value); 1366 1367 /********************************************************************/ 1368 address = CRTC_REG(mmCRTC_GSL_CONTROL); 1369 1370 value = 0; 1371 set_reg_field_value(value, 1372 0, 1373 CRTC_GSL_CONTROL, 1374 CRTC_GSL_CHECK_LINE_NUM); 1375 1376 set_reg_field_value(value, 1377 0x2, 1378 CRTC_GSL_CONTROL, 1379 CRTC_GSL_FORCE_DELAY); 1380 1381 dm_write_reg(tg->ctx, address, value); 1382 } 1383 /** 1384 ***************************************************************************** 1385 * Function: is_counter_moving 1386 * 1387 * @brief 1388 * check if the timing generator is currently going 1389 * 1390 * @return 1391 * true if currently going, false if currently paused or stopped. 1392 * 1393 ***************************************************************************** 1394 */ 1395 bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg) 1396 { 1397 struct crtc_position position1, position2; 1398 1399 tg->funcs->get_position(tg, &position1); 1400 tg->funcs->get_position(tg, &position2); 1401 1402 if (position1.horizontal_count == position2.horizontal_count && 1403 position1.vertical_count == position2.vertical_count) 1404 return false; 1405 else 1406 return true; 1407 } 1408 1409 void dce110_timing_generator_enable_advanced_request( 1410 struct timing_generator *tg, 1411 bool enable, 1412 const struct dc_crtc_timing *timing) 1413 { 1414 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1415 uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL); 1416 uint32_t value = dm_read_reg(tg->ctx, addr); 1417 1418 if (enable) { 1419 set_reg_field_value( 1420 value, 1421 0, 1422 CRTC_START_LINE_CONTROL, 1423 CRTC_LEGACY_REQUESTOR_EN); 1424 } else { 1425 set_reg_field_value( 1426 value, 1427 1, 1428 CRTC_START_LINE_CONTROL, 1429 CRTC_LEGACY_REQUESTOR_EN); 1430 } 1431 1432 if ((timing->v_sync_width + timing->v_front_porch) <= 3) { 1433 set_reg_field_value( 1434 value, 1435 3, 1436 CRTC_START_LINE_CONTROL, 1437 CRTC_ADVANCED_START_LINE_POSITION); 1438 set_reg_field_value( 1439 value, 1440 0, 1441 CRTC_START_LINE_CONTROL, 1442 CRTC_PREFETCH_EN); 1443 } else { 1444 set_reg_field_value( 1445 value, 1446 4, 1447 CRTC_START_LINE_CONTROL, 1448 CRTC_ADVANCED_START_LINE_POSITION); 1449 set_reg_field_value( 1450 value, 1451 1, 1452 CRTC_START_LINE_CONTROL, 1453 CRTC_PREFETCH_EN); 1454 } 1455 1456 set_reg_field_value( 1457 value, 1458 1, 1459 CRTC_START_LINE_CONTROL, 1460 CRTC_PROGRESSIVE_START_LINE_EARLY); 1461 1462 set_reg_field_value( 1463 value, 1464 1, 1465 CRTC_START_LINE_CONTROL, 1466 CRTC_INTERLACE_START_LINE_EARLY); 1467 1468 dm_write_reg(tg->ctx, addr, value); 1469 } 1470 1471 /*TODO: Figure out if we need this function. */ 1472 void dce110_timing_generator_set_lock_master(struct timing_generator *tg, 1473 bool lock) 1474 { 1475 struct dc_context *ctx = tg->ctx; 1476 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1477 uint32_t addr = CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK); 1478 uint32_t value = dm_read_reg(ctx, addr); 1479 1480 set_reg_field_value( 1481 value, 1482 lock ? 1 : 0, 1483 CRTC_MASTER_UPDATE_LOCK, 1484 MASTER_UPDATE_LOCK); 1485 1486 dm_write_reg(ctx, addr, value); 1487 } 1488 1489 void dce110_timing_generator_enable_reset_trigger( 1490 struct timing_generator *tg, 1491 int source_tg_inst) 1492 { 1493 uint32_t value; 1494 uint32_t rising_edge = 0; 1495 uint32_t falling_edge = 0; 1496 enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO; 1497 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1498 1499 /* Setup trigger edge */ 1500 { 1501 uint32_t pol_value = dm_read_reg(tg->ctx, 1502 CRTC_REG(mmCRTC_V_SYNC_A_CNTL)); 1503 1504 /* Register spec has reversed definition: 1505 * 0 for positive, 1 for negative */ 1506 if (get_reg_field_value(pol_value, 1507 CRTC_V_SYNC_A_CNTL, 1508 CRTC_V_SYNC_A_POL) == 0) { 1509 rising_edge = 1; 1510 } else { 1511 falling_edge = 1; 1512 } 1513 } 1514 1515 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL)); 1516 1517 trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0; 1518 1519 set_reg_field_value(value, 1520 trig_src_select, 1521 CRTC_TRIGB_CNTL, 1522 CRTC_TRIGB_SOURCE_SELECT); 1523 1524 set_reg_field_value(value, 1525 TRIGGER_POLARITY_SELECT_LOGIC_ZERO, 1526 CRTC_TRIGB_CNTL, 1527 CRTC_TRIGB_POLARITY_SELECT); 1528 1529 set_reg_field_value(value, 1530 rising_edge, 1531 CRTC_TRIGB_CNTL, 1532 CRTC_TRIGB_RISING_EDGE_DETECT_CNTL); 1533 1534 set_reg_field_value(value, 1535 falling_edge, 1536 CRTC_TRIGB_CNTL, 1537 CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL); 1538 1539 set_reg_field_value(value, 1540 0, /* send every signal */ 1541 CRTC_TRIGB_CNTL, 1542 CRTC_TRIGB_FREQUENCY_SELECT); 1543 1544 set_reg_field_value(value, 1545 0, /* no delay */ 1546 CRTC_TRIGB_CNTL, 1547 CRTC_TRIGB_DELAY); 1548 1549 set_reg_field_value(value, 1550 1, /* clear trigger status */ 1551 CRTC_TRIGB_CNTL, 1552 CRTC_TRIGB_CLEAR); 1553 1554 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value); 1555 1556 /**************************************************************/ 1557 1558 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL)); 1559 1560 set_reg_field_value(value, 1561 2, /* force H count to H_TOTAL and V count to V_TOTAL */ 1562 CRTC_FORCE_COUNT_NOW_CNTL, 1563 CRTC_FORCE_COUNT_NOW_MODE); 1564 1565 set_reg_field_value(value, 1566 1, /* TriggerB - we never use TriggerA */ 1567 CRTC_FORCE_COUNT_NOW_CNTL, 1568 CRTC_FORCE_COUNT_NOW_TRIG_SEL); 1569 1570 set_reg_field_value(value, 1571 1, /* clear trigger status */ 1572 CRTC_FORCE_COUNT_NOW_CNTL, 1573 CRTC_FORCE_COUNT_NOW_CLEAR); 1574 1575 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value); 1576 } 1577 1578 void dce110_timing_generator_enable_crtc_reset( 1579 struct timing_generator *tg, 1580 int source_tg_inst, 1581 struct crtc_trigger_info *crtc_tp) 1582 { 1583 uint32_t value = 0; 1584 uint32_t rising_edge = 0; 1585 uint32_t falling_edge = 0; 1586 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1587 1588 /* Setup trigger edge */ 1589 switch (crtc_tp->event) { 1590 case CRTC_EVENT_VSYNC_RISING: 1591 rising_edge = 1; 1592 break; 1593 1594 case CRTC_EVENT_VSYNC_FALLING: 1595 falling_edge = 1; 1596 break; 1597 } 1598 1599 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL)); 1600 1601 set_reg_field_value(value, 1602 source_tg_inst, 1603 CRTC_TRIGB_CNTL, 1604 CRTC_TRIGB_SOURCE_SELECT); 1605 1606 set_reg_field_value(value, 1607 TRIGGER_POLARITY_SELECT_LOGIC_ZERO, 1608 CRTC_TRIGB_CNTL, 1609 CRTC_TRIGB_POLARITY_SELECT); 1610 1611 set_reg_field_value(value, 1612 rising_edge, 1613 CRTC_TRIGB_CNTL, 1614 CRTC_TRIGB_RISING_EDGE_DETECT_CNTL); 1615 1616 set_reg_field_value(value, 1617 falling_edge, 1618 CRTC_TRIGB_CNTL, 1619 CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL); 1620 1621 set_reg_field_value(value, 1622 1, /* clear trigger status */ 1623 CRTC_TRIGB_CNTL, 1624 CRTC_TRIGB_CLEAR); 1625 1626 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value); 1627 1628 /**************************************************************/ 1629 1630 switch (crtc_tp->delay) { 1631 case TRIGGER_DELAY_NEXT_LINE: 1632 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL)); 1633 1634 set_reg_field_value(value, 1635 0, /* force H count to H_TOTAL and V count to V_TOTAL */ 1636 CRTC_FORCE_COUNT_NOW_CNTL, 1637 CRTC_FORCE_COUNT_NOW_MODE); 1638 1639 set_reg_field_value(value, 1640 0, /* TriggerB - we never use TriggerA */ 1641 CRTC_FORCE_COUNT_NOW_CNTL, 1642 CRTC_FORCE_COUNT_NOW_TRIG_SEL); 1643 1644 set_reg_field_value(value, 1645 1, /* clear trigger status */ 1646 CRTC_FORCE_COUNT_NOW_CNTL, 1647 CRTC_FORCE_COUNT_NOW_CLEAR); 1648 1649 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value); 1650 1651 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL)); 1652 1653 set_reg_field_value(value, 1654 1, 1655 CRTC_VERT_SYNC_CONTROL, 1656 CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR); 1657 1658 set_reg_field_value(value, 1659 2, 1660 CRTC_VERT_SYNC_CONTROL, 1661 CRTC_AUTO_FORCE_VSYNC_MODE); 1662 1663 break; 1664 1665 case TRIGGER_DELAY_NEXT_PIXEL: 1666 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL)); 1667 1668 set_reg_field_value(value, 1669 1, 1670 CRTC_VERT_SYNC_CONTROL, 1671 CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR); 1672 1673 set_reg_field_value(value, 1674 0, 1675 CRTC_VERT_SYNC_CONTROL, 1676 CRTC_AUTO_FORCE_VSYNC_MODE); 1677 1678 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value); 1679 1680 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL)); 1681 1682 set_reg_field_value(value, 1683 2, /* force H count to H_TOTAL and V count to V_TOTAL */ 1684 CRTC_FORCE_COUNT_NOW_CNTL, 1685 CRTC_FORCE_COUNT_NOW_MODE); 1686 1687 set_reg_field_value(value, 1688 1, /* TriggerB - we never use TriggerA */ 1689 CRTC_FORCE_COUNT_NOW_CNTL, 1690 CRTC_FORCE_COUNT_NOW_TRIG_SEL); 1691 1692 set_reg_field_value(value, 1693 1, /* clear trigger status */ 1694 CRTC_FORCE_COUNT_NOW_CNTL, 1695 CRTC_FORCE_COUNT_NOW_CLEAR); 1696 1697 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value); 1698 break; 1699 } 1700 1701 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE)); 1702 1703 set_reg_field_value(value, 1704 2, 1705 CRTC_MASTER_UPDATE_MODE, 1706 MASTER_UPDATE_MODE); 1707 1708 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value); 1709 } 1710 void dce110_timing_generator_disable_reset_trigger( 1711 struct timing_generator *tg) 1712 { 1713 uint32_t value; 1714 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1715 1716 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL)); 1717 1718 set_reg_field_value(value, 1719 0, /* force counter now mode is disabled */ 1720 CRTC_FORCE_COUNT_NOW_CNTL, 1721 CRTC_FORCE_COUNT_NOW_MODE); 1722 1723 set_reg_field_value(value, 1724 1, /* clear trigger status */ 1725 CRTC_FORCE_COUNT_NOW_CNTL, 1726 CRTC_FORCE_COUNT_NOW_CLEAR); 1727 1728 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value); 1729 1730 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL)); 1731 1732 set_reg_field_value(value, 1733 1, 1734 CRTC_VERT_SYNC_CONTROL, 1735 CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR); 1736 1737 set_reg_field_value(value, 1738 0, 1739 CRTC_VERT_SYNC_CONTROL, 1740 CRTC_AUTO_FORCE_VSYNC_MODE); 1741 1742 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value); 1743 1744 /********************************************************************/ 1745 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL)); 1746 1747 set_reg_field_value(value, 1748 TRIGGER_SOURCE_SELECT_LOGIC_ZERO, 1749 CRTC_TRIGB_CNTL, 1750 CRTC_TRIGB_SOURCE_SELECT); 1751 1752 set_reg_field_value(value, 1753 TRIGGER_POLARITY_SELECT_LOGIC_ZERO, 1754 CRTC_TRIGB_CNTL, 1755 CRTC_TRIGB_POLARITY_SELECT); 1756 1757 set_reg_field_value(value, 1758 1, /* clear trigger status */ 1759 CRTC_TRIGB_CNTL, 1760 CRTC_TRIGB_CLEAR); 1761 1762 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value); 1763 } 1764 1765 /** 1766 ***************************************************************************** 1767 * @brief 1768 * Checks whether CRTC triggered reset occurred 1769 * 1770 * @return 1771 * true if triggered reset occurred, false otherwise 1772 ***************************************************************************** 1773 */ 1774 bool dce110_timing_generator_did_triggered_reset_occur( 1775 struct timing_generator *tg) 1776 { 1777 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1778 uint32_t value = dm_read_reg(tg->ctx, 1779 CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL)); 1780 uint32_t value1 = dm_read_reg(tg->ctx, 1781 CRTC_REG(mmCRTC_VERT_SYNC_CONTROL)); 1782 bool force = get_reg_field_value(value, 1783 CRTC_FORCE_COUNT_NOW_CNTL, 1784 CRTC_FORCE_COUNT_NOW_OCCURRED) != 0; 1785 bool vert_sync = get_reg_field_value(value1, 1786 CRTC_VERT_SYNC_CONTROL, 1787 CRTC_FORCE_VSYNC_NEXT_LINE_OCCURRED) != 0; 1788 1789 return (force || vert_sync); 1790 } 1791 1792 /** 1793 * dce110_timing_generator_disable_vga 1794 * Turn OFF VGA Mode and Timing - DxVGA_CONTROL 1795 * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors; 1796 */ 1797 void dce110_timing_generator_disable_vga( 1798 struct timing_generator *tg) 1799 { 1800 uint32_t addr = 0; 1801 uint32_t value = 0; 1802 1803 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1804 1805 switch (tg110->controller_id) { 1806 case CONTROLLER_ID_D0: 1807 addr = mmD1VGA_CONTROL; 1808 break; 1809 case CONTROLLER_ID_D1: 1810 addr = mmD2VGA_CONTROL; 1811 break; 1812 case CONTROLLER_ID_D2: 1813 addr = mmD3VGA_CONTROL; 1814 break; 1815 case CONTROLLER_ID_D3: 1816 addr = mmD4VGA_CONTROL; 1817 break; 1818 case CONTROLLER_ID_D4: 1819 addr = mmD5VGA_CONTROL; 1820 break; 1821 case CONTROLLER_ID_D5: 1822 addr = mmD6VGA_CONTROL; 1823 break; 1824 default: 1825 break; 1826 } 1827 value = dm_read_reg(tg->ctx, addr); 1828 1829 set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE); 1830 set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT); 1831 set_reg_field_value( 1832 value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT); 1833 set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN); 1834 1835 dm_write_reg(tg->ctx, addr, value); 1836 } 1837 1838 /** 1839 * set_overscan_color_black 1840 * 1841 * @param :black_color is one of the color space 1842 * :this routine will set overscan black color according to the color space. 1843 * @return none 1844 */ 1845 1846 void dce110_timing_generator_set_overscan_color_black( 1847 struct timing_generator *tg, 1848 const struct tg_color *color) 1849 { 1850 struct dc_context *ctx = tg->ctx; 1851 uint32_t addr; 1852 uint32_t value = 0; 1853 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1854 1855 set_reg_field_value( 1856 value, 1857 color->color_b_cb, 1858 CRTC_OVERSCAN_COLOR, 1859 CRTC_OVERSCAN_COLOR_BLUE); 1860 1861 set_reg_field_value( 1862 value, 1863 color->color_r_cr, 1864 CRTC_OVERSCAN_COLOR, 1865 CRTC_OVERSCAN_COLOR_RED); 1866 1867 set_reg_field_value( 1868 value, 1869 color->color_g_y, 1870 CRTC_OVERSCAN_COLOR, 1871 CRTC_OVERSCAN_COLOR_GREEN); 1872 1873 addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR); 1874 dm_write_reg(ctx, addr, value); 1875 addr = CRTC_REG(mmCRTC_BLACK_COLOR); 1876 dm_write_reg(ctx, addr, value); 1877 /* This is desirable to have a constant DAC output voltage during the 1878 * blank time that is higher than the 0 volt reference level that the 1879 * DAC outputs when the NBLANK signal 1880 * is asserted low, such as for output to an analog TV. */ 1881 addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR); 1882 dm_write_reg(ctx, addr, value); 1883 1884 /* TO DO we have to program EXT registers and we need to know LB DATA 1885 * format because it is used when more 10 , i.e. 12 bits per color 1886 * 1887 * m_mmDxCRTC_OVERSCAN_COLOR_EXT 1888 * m_mmDxCRTC_BLACK_COLOR_EXT 1889 * m_mmDxCRTC_BLANK_DATA_COLOR_EXT 1890 */ 1891 1892 } 1893 1894 void dce110_tg_program_blank_color(struct timing_generator *tg, 1895 const struct tg_color *black_color) 1896 { 1897 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1898 uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR); 1899 uint32_t value = dm_read_reg(tg->ctx, addr); 1900 1901 set_reg_field_value( 1902 value, 1903 black_color->color_b_cb, 1904 CRTC_BLACK_COLOR, 1905 CRTC_BLACK_COLOR_B_CB); 1906 set_reg_field_value( 1907 value, 1908 black_color->color_g_y, 1909 CRTC_BLACK_COLOR, 1910 CRTC_BLACK_COLOR_G_Y); 1911 set_reg_field_value( 1912 value, 1913 black_color->color_r_cr, 1914 CRTC_BLACK_COLOR, 1915 CRTC_BLACK_COLOR_R_CR); 1916 1917 dm_write_reg(tg->ctx, addr, value); 1918 1919 addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR); 1920 dm_write_reg(tg->ctx, addr, value); 1921 } 1922 1923 void dce110_tg_set_overscan_color(struct timing_generator *tg, 1924 const struct tg_color *overscan_color) 1925 { 1926 struct dc_context *ctx = tg->ctx; 1927 uint32_t value = 0; 1928 uint32_t addr; 1929 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1930 1931 set_reg_field_value( 1932 value, 1933 overscan_color->color_b_cb, 1934 CRTC_OVERSCAN_COLOR, 1935 CRTC_OVERSCAN_COLOR_BLUE); 1936 1937 set_reg_field_value( 1938 value, 1939 overscan_color->color_g_y, 1940 CRTC_OVERSCAN_COLOR, 1941 CRTC_OVERSCAN_COLOR_GREEN); 1942 1943 set_reg_field_value( 1944 value, 1945 overscan_color->color_r_cr, 1946 CRTC_OVERSCAN_COLOR, 1947 CRTC_OVERSCAN_COLOR_RED); 1948 1949 addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR); 1950 dm_write_reg(ctx, addr, value); 1951 } 1952 1953 void dce110_tg_program_timing(struct timing_generator *tg, 1954 const struct dc_crtc_timing *timing, 1955 bool use_vbios) 1956 { 1957 if (use_vbios) 1958 dce110_timing_generator_program_timing_generator(tg, timing); 1959 else 1960 dce110_timing_generator_program_blanking(tg, timing); 1961 } 1962 1963 bool dce110_tg_is_blanked(struct timing_generator *tg) 1964 { 1965 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1966 uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL)); 1967 1968 if (get_reg_field_value( 1969 value, 1970 CRTC_BLANK_CONTROL, 1971 CRTC_BLANK_DATA_EN) == 1 && 1972 get_reg_field_value( 1973 value, 1974 CRTC_BLANK_CONTROL, 1975 CRTC_CURRENT_BLANK_STATE) == 1) 1976 return true; 1977 return false; 1978 } 1979 1980 void dce110_tg_set_blank(struct timing_generator *tg, 1981 bool enable_blanking) 1982 { 1983 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 1984 uint32_t value = 0; 1985 1986 set_reg_field_value( 1987 value, 1988 1, 1989 CRTC_DOUBLE_BUFFER_CONTROL, 1990 CRTC_BLANK_DATA_DOUBLE_BUFFER_EN); 1991 1992 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value); 1993 value = 0; 1994 1995 if (enable_blanking) { 1996 set_reg_field_value( 1997 value, 1998 1, 1999 CRTC_BLANK_CONTROL, 2000 CRTC_BLANK_DATA_EN); 2001 2002 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value); 2003 2004 } else 2005 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0); 2006 } 2007 2008 bool dce110_tg_validate_timing(struct timing_generator *tg, 2009 const struct dc_crtc_timing *timing) 2010 { 2011 return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE); 2012 } 2013 2014 void dce110_tg_wait_for_state(struct timing_generator *tg, 2015 enum crtc_state state) 2016 { 2017 switch (state) { 2018 case CRTC_STATE_VBLANK: 2019 dce110_timing_generator_wait_for_vblank(tg); 2020 break; 2021 2022 case CRTC_STATE_VACTIVE: 2023 dce110_timing_generator_wait_for_vactive(tg); 2024 break; 2025 2026 default: 2027 break; 2028 } 2029 } 2030 2031 void dce110_tg_set_colors(struct timing_generator *tg, 2032 const struct tg_color *blank_color, 2033 const struct tg_color *overscan_color) 2034 { 2035 if (blank_color != NULL) 2036 dce110_tg_program_blank_color(tg, blank_color); 2037 if (overscan_color != NULL) 2038 dce110_tg_set_overscan_color(tg, overscan_color); 2039 } 2040 2041 /* Gets first line of blank region of the display timing for CRTC 2042 * and programms is as a trigger to fire vertical interrupt 2043 */ 2044 bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width) 2045 { 2046 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 2047 uint32_t v_blank_start = 0; 2048 uint32_t v_blank_end = 0; 2049 uint32_t val = 0; 2050 uint32_t h_position, v_position; 2051 2052 tg->funcs->get_scanoutpos( 2053 tg, 2054 &v_blank_start, 2055 &v_blank_end, 2056 &h_position, 2057 &v_position); 2058 2059 if (v_blank_start == 0 || v_blank_end == 0) 2060 return false; 2061 2062 set_reg_field_value( 2063 val, 2064 v_blank_start, 2065 CRTC_VERTICAL_INTERRUPT0_POSITION, 2066 CRTC_VERTICAL_INTERRUPT0_LINE_START); 2067 2068 /* Set interval width for interrupt to fire to 1 scanline */ 2069 set_reg_field_value( 2070 val, 2071 v_blank_start + width, 2072 CRTC_VERTICAL_INTERRUPT0_POSITION, 2073 CRTC_VERTICAL_INTERRUPT0_LINE_END); 2074 2075 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val); 2076 2077 return true; 2078 } 2079 2080 static bool dce110_is_tg_enabled(struct timing_generator *tg) 2081 { 2082 uint32_t addr = 0; 2083 uint32_t value = 0; 2084 uint32_t field = 0; 2085 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 2086 2087 addr = CRTC_REG(mmCRTC_CONTROL); 2088 value = dm_read_reg(tg->ctx, addr); 2089 field = get_reg_field_value(value, CRTC_CONTROL, 2090 CRTC_CURRENT_MASTER_EN_STATE); 2091 return field == 1; 2092 } 2093 2094 bool dce110_configure_crc(struct timing_generator *tg, 2095 const struct crc_params *params) 2096 { 2097 uint32_t cntl_addr = 0; 2098 uint32_t addr = 0; 2099 uint32_t value; 2100 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 2101 2102 /* Cannot configure crc on a CRTC that is disabled */ 2103 if (!dce110_is_tg_enabled(tg)) 2104 return false; 2105 2106 cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL); 2107 2108 /* First, disable CRC before we configure it. */ 2109 dm_write_reg(tg->ctx, cntl_addr, 0); 2110 2111 if (!params->enable) 2112 return true; 2113 2114 /* Program frame boundaries */ 2115 /* Window A x axis start and end. */ 2116 value = 0; 2117 addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL); 2118 set_reg_field_value(value, params->windowa_x_start, 2119 CRTC_CRC0_WINDOWA_X_CONTROL, 2120 CRTC_CRC0_WINDOWA_X_START); 2121 set_reg_field_value(value, params->windowa_x_end, 2122 CRTC_CRC0_WINDOWA_X_CONTROL, 2123 CRTC_CRC0_WINDOWA_X_END); 2124 dm_write_reg(tg->ctx, addr, value); 2125 2126 /* Window A y axis start and end. */ 2127 value = 0; 2128 addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL); 2129 set_reg_field_value(value, params->windowa_y_start, 2130 CRTC_CRC0_WINDOWA_Y_CONTROL, 2131 CRTC_CRC0_WINDOWA_Y_START); 2132 set_reg_field_value(value, params->windowa_y_end, 2133 CRTC_CRC0_WINDOWA_Y_CONTROL, 2134 CRTC_CRC0_WINDOWA_Y_END); 2135 dm_write_reg(tg->ctx, addr, value); 2136 2137 /* Window B x axis start and end. */ 2138 value = 0; 2139 addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL); 2140 set_reg_field_value(value, params->windowb_x_start, 2141 CRTC_CRC0_WINDOWB_X_CONTROL, 2142 CRTC_CRC0_WINDOWB_X_START); 2143 set_reg_field_value(value, params->windowb_x_end, 2144 CRTC_CRC0_WINDOWB_X_CONTROL, 2145 CRTC_CRC0_WINDOWB_X_END); 2146 dm_write_reg(tg->ctx, addr, value); 2147 2148 /* Window B y axis start and end. */ 2149 value = 0; 2150 addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL); 2151 set_reg_field_value(value, params->windowb_y_start, 2152 CRTC_CRC0_WINDOWB_Y_CONTROL, 2153 CRTC_CRC0_WINDOWB_Y_START); 2154 set_reg_field_value(value, params->windowb_y_end, 2155 CRTC_CRC0_WINDOWB_Y_CONTROL, 2156 CRTC_CRC0_WINDOWB_Y_END); 2157 dm_write_reg(tg->ctx, addr, value); 2158 2159 /* Set crc mode and selection, and enable. Only using CRC0*/ 2160 value = 0; 2161 set_reg_field_value(value, params->continuous_mode ? 1 : 0, 2162 CRTC_CRC_CNTL, CRTC_CRC_CONT_EN); 2163 set_reg_field_value(value, params->selection, 2164 CRTC_CRC_CNTL, CRTC_CRC0_SELECT); 2165 set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN); 2166 dm_write_reg(tg->ctx, cntl_addr, value); 2167 2168 return true; 2169 } 2170 2171 bool dce110_get_crc(struct timing_generator *tg, 2172 uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) 2173 { 2174 uint32_t addr = 0; 2175 uint32_t value = 0; 2176 uint32_t field = 0; 2177 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 2178 2179 addr = CRTC_REG(mmCRTC_CRC_CNTL); 2180 value = dm_read_reg(tg->ctx, addr); 2181 field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN); 2182 2183 /* Early return if CRC is not enabled for this CRTC */ 2184 if (!field) 2185 return false; 2186 2187 addr = CRTC_REG(mmCRTC_CRC0_DATA_RG); 2188 value = dm_read_reg(tg->ctx, addr); 2189 *r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR); 2190 *g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y); 2191 2192 addr = CRTC_REG(mmCRTC_CRC0_DATA_B); 2193 value = dm_read_reg(tg->ctx, addr); 2194 *b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB); 2195 2196 return true; 2197 } 2198 2199 static const struct timing_generator_funcs dce110_tg_funcs = { 2200 .validate_timing = dce110_tg_validate_timing, 2201 .program_timing = dce110_tg_program_timing, 2202 .enable_crtc = dce110_timing_generator_enable_crtc, 2203 .disable_crtc = dce110_timing_generator_disable_crtc, 2204 .is_counter_moving = dce110_timing_generator_is_counter_moving, 2205 .get_position = dce110_timing_generator_get_position, 2206 .get_frame_count = dce110_timing_generator_get_vblank_counter, 2207 .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos, 2208 .set_early_control = dce110_timing_generator_set_early_control, 2209 .wait_for_state = dce110_tg_wait_for_state, 2210 .set_blank = dce110_tg_set_blank, 2211 .is_blanked = dce110_tg_is_blanked, 2212 .set_colors = dce110_tg_set_colors, 2213 .set_overscan_blank_color = 2214 dce110_timing_generator_set_overscan_color_black, 2215 .set_blank_color = dce110_timing_generator_program_blank_color, 2216 .disable_vga = dce110_timing_generator_disable_vga, 2217 .did_triggered_reset_occur = 2218 dce110_timing_generator_did_triggered_reset_occur, 2219 .setup_global_swap_lock = 2220 dce110_timing_generator_setup_global_swap_lock, 2221 .enable_reset_trigger = dce110_timing_generator_enable_reset_trigger, 2222 .enable_crtc_reset = dce110_timing_generator_enable_crtc_reset, 2223 .disable_reset_trigger = dce110_timing_generator_disable_reset_trigger, 2224 .tear_down_global_swap_lock = 2225 dce110_timing_generator_tear_down_global_swap_lock, 2226 .enable_advanced_request = 2227 dce110_timing_generator_enable_advanced_request, 2228 .set_drr = 2229 dce110_timing_generator_set_drr, 2230 .set_static_screen_control = 2231 dce110_timing_generator_set_static_screen_control, 2232 .set_test_pattern = dce110_timing_generator_set_test_pattern, 2233 .arm_vert_intr = dce110_arm_vert_intr, 2234 .is_tg_enabled = dce110_is_tg_enabled, 2235 .configure_crc = dce110_configure_crc, 2236 .get_crc = dce110_get_crc, 2237 }; 2238 2239 void dce110_timing_generator_construct( 2240 struct dce110_timing_generator *tg110, 2241 struct dc_context *ctx, 2242 uint32_t instance, 2243 const struct dce110_timing_generator_offsets *offsets) 2244 { 2245 tg110->controller_id = CONTROLLER_ID_D0 + instance; 2246 tg110->base.inst = instance; 2247 2248 tg110->offsets = *offsets; 2249 2250 tg110->base.funcs = &dce110_tg_funcs; 2251 2252 tg110->base.ctx = ctx; 2253 tg110->base.bp = ctx->dc_bios; 2254 2255 tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1; 2256 tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1; 2257 2258 tg110->min_h_blank = 56; 2259 tg110->min_h_front_porch = 4; 2260 tg110->min_h_back_porch = 4; 2261 } 2262