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