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 27 #include "reg_helper.h" 28 #include "dcn10_optc.h" 29 #include "dc.h" 30 31 #define REG(reg)\ 32 optc1->tg_regs->reg 33 34 #define CTX \ 35 optc1->base.ctx 36 37 #undef FN 38 #define FN(reg_name, field_name) \ 39 optc1->tg_shift->field_name, optc1->tg_mask->field_name 40 41 #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100 42 43 /** 44 * apply_front_porch_workaround TODO FPGA still need? 45 * 46 * This is a workaround for a bug that has existed since R5xx and has not been 47 * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive. 48 */ 49 static void optc1_apply_front_porch_workaround( 50 struct timing_generator *optc, 51 struct dc_crtc_timing *timing) 52 { 53 if (timing->flags.INTERLACE == 1) { 54 if (timing->v_front_porch < 2) 55 timing->v_front_porch = 2; 56 } else { 57 if (timing->v_front_porch < 1) 58 timing->v_front_porch = 1; 59 } 60 } 61 62 void optc1_program_global_sync( 63 struct timing_generator *optc) 64 { 65 struct optc *optc1 = DCN10TG_FROM_TG(optc); 66 67 if (optc->dlg_otg_param.vstartup_start == 0) { 68 BREAK_TO_DEBUGGER(); 69 return; 70 } 71 72 REG_SET(OTG_VSTARTUP_PARAM, 0, 73 VSTARTUP_START, optc->dlg_otg_param.vstartup_start); 74 75 REG_SET_2(OTG_VUPDATE_PARAM, 0, 76 VUPDATE_OFFSET, optc->dlg_otg_param.vupdate_offset, 77 VUPDATE_WIDTH, optc->dlg_otg_param.vupdate_width); 78 79 REG_SET(OTG_VREADY_PARAM, 0, 80 VREADY_OFFSET, optc->dlg_otg_param.vready_offset); 81 } 82 83 static void optc1_disable_stereo(struct timing_generator *optc) 84 { 85 struct optc *optc1 = DCN10TG_FROM_TG(optc); 86 87 REG_SET(OTG_STEREO_CONTROL, 0, 88 OTG_STEREO_EN, 0); 89 90 REG_SET_2(OTG_3D_STRUCTURE_CONTROL, 0, 91 OTG_3D_STRUCTURE_EN, 0, 92 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); 93 } 94 95 void optc1_program_vline_interrupt( 96 struct timing_generator *optc, 97 enum vline_select vline, 98 struct vline_config vline_config) 99 { 100 struct optc *optc1 = DCN10TG_FROM_TG(optc); 101 102 switch (vline) { 103 case VLINE0: 104 REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0, 105 OTG_VERTICAL_INTERRUPT0_LINE_START, vline_config.start_line, 106 OTG_VERTICAL_INTERRUPT0_LINE_END, vline_config.end_line); 107 break; 108 case VLINE1: 109 REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0, 110 OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config.start_line); 111 break; 112 default: 113 break; 114 } 115 } 116 117 /** 118 * program_timing_generator used by mode timing set 119 * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. 120 * Including SYNC. Call BIOS command table to program Timings. 121 */ 122 void optc1_program_timing( 123 struct timing_generator *optc, 124 const struct dc_crtc_timing *dc_crtc_timing, 125 bool use_vbios) 126 { 127 struct dc_crtc_timing patched_crtc_timing; 128 uint32_t vesa_sync_start; 129 uint32_t asic_blank_end; 130 uint32_t asic_blank_start; 131 uint32_t v_total; 132 uint32_t v_sync_end; 133 uint32_t v_init, v_fp2; 134 uint32_t h_sync_polarity, v_sync_polarity; 135 uint32_t start_point = 0; 136 uint32_t field_num = 0; 137 uint32_t h_div_2; 138 int32_t vertical_line_start; 139 140 struct optc *optc1 = DCN10TG_FROM_TG(optc); 141 142 patched_crtc_timing = *dc_crtc_timing; 143 optc1_apply_front_porch_workaround(optc, &patched_crtc_timing); 144 145 /* Load horizontal timing */ 146 147 /* CRTC_H_TOTAL = vesa.h_total - 1 */ 148 REG_SET(OTG_H_TOTAL, 0, 149 OTG_H_TOTAL, patched_crtc_timing.h_total - 1); 150 151 /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */ 152 REG_UPDATE_2(OTG_H_SYNC_A, 153 OTG_H_SYNC_A_START, 0, 154 OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width); 155 156 /* asic_h_blank_end = HsyncWidth + HbackPorch = 157 * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart - 158 * vesa.h_left_border 159 */ 160 vesa_sync_start = patched_crtc_timing.h_addressable + 161 patched_crtc_timing.h_border_right + 162 patched_crtc_timing.h_front_porch; 163 164 asic_blank_end = patched_crtc_timing.h_total - 165 vesa_sync_start - 166 patched_crtc_timing.h_border_left; 167 168 /* h_blank_start = v_blank_end + v_active */ 169 asic_blank_start = asic_blank_end + 170 patched_crtc_timing.h_border_left + 171 patched_crtc_timing.h_addressable + 172 patched_crtc_timing.h_border_right; 173 174 REG_UPDATE_2(OTG_H_BLANK_START_END, 175 OTG_H_BLANK_START, asic_blank_start, 176 OTG_H_BLANK_END, asic_blank_end); 177 178 /* h_sync polarity */ 179 h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ? 180 0 : 1; 181 182 REG_UPDATE(OTG_H_SYNC_A_CNTL, 183 OTG_H_SYNC_A_POL, h_sync_polarity); 184 185 v_total = patched_crtc_timing.v_total - 1; 186 187 REG_SET(OTG_V_TOTAL, 0, 188 OTG_V_TOTAL, v_total); 189 190 /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and 191 * OTG_V_TOTAL_MIN are equal to V_TOTAL. 192 */ 193 REG_SET(OTG_V_TOTAL_MAX, 0, 194 OTG_V_TOTAL_MAX, v_total); 195 REG_SET(OTG_V_TOTAL_MIN, 0, 196 OTG_V_TOTAL_MIN, v_total); 197 198 /* v_sync_start = 0, v_sync_end = v_sync_width */ 199 v_sync_end = patched_crtc_timing.v_sync_width; 200 201 REG_UPDATE_2(OTG_V_SYNC_A, 202 OTG_V_SYNC_A_START, 0, 203 OTG_V_SYNC_A_END, v_sync_end); 204 205 vesa_sync_start = patched_crtc_timing.v_addressable + 206 patched_crtc_timing.v_border_bottom + 207 patched_crtc_timing.v_front_porch; 208 209 asic_blank_end = (patched_crtc_timing.v_total - 210 vesa_sync_start - 211 patched_crtc_timing.v_border_top); 212 213 /* v_blank_start = v_blank_end + v_active */ 214 asic_blank_start = asic_blank_end + 215 (patched_crtc_timing.v_border_top + 216 patched_crtc_timing.v_addressable + 217 patched_crtc_timing.v_border_bottom); 218 219 REG_UPDATE_2(OTG_V_BLANK_START_END, 220 OTG_V_BLANK_START, asic_blank_start, 221 OTG_V_BLANK_END, asic_blank_end); 222 223 /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt, 224 * program the reg for interrupt postition. 225 */ 226 vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; 227 v_fp2 = 0; 228 if (vertical_line_start < 0) 229 v_fp2 = -vertical_line_start; 230 if (vertical_line_start < 0) 231 vertical_line_start = 0; 232 233 REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0, 234 OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start); 235 236 /* v_sync polarity */ 237 v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ? 238 0 : 1; 239 240 REG_UPDATE(OTG_V_SYNC_A_CNTL, 241 OTG_V_SYNC_A_POL, v_sync_polarity); 242 243 v_init = asic_blank_start; 244 if (optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT || 245 optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST || 246 optc->dlg_otg_param.signal == SIGNAL_TYPE_EDP) { 247 start_point = 1; 248 if (patched_crtc_timing.flags.INTERLACE == 1) 249 field_num = 1; 250 } 251 252 /* Interlace */ 253 if (REG(OTG_INTERLACE_CONTROL)) { 254 if (patched_crtc_timing.flags.INTERLACE == 1) { 255 REG_UPDATE(OTG_INTERLACE_CONTROL, 256 OTG_INTERLACE_ENABLE, 1); 257 v_init = v_init / 2; 258 if ((optc->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end) 259 v_fp2 = v_fp2 / 2; 260 } else 261 REG_UPDATE(OTG_INTERLACE_CONTROL, 262 OTG_INTERLACE_ENABLE, 0); 263 } 264 265 /* VTG enable set to 0 first VInit */ 266 REG_UPDATE(CONTROL, 267 VTG0_ENABLE, 0); 268 269 REG_UPDATE_2(CONTROL, 270 VTG0_FP2, v_fp2, 271 VTG0_VCOUNT_INIT, v_init); 272 273 /* original code is using VTG offset to address OTG reg, seems wrong */ 274 REG_UPDATE_2(OTG_CONTROL, 275 OTG_START_POINT_CNTL, start_point, 276 OTG_FIELD_NUMBER_CNTL, field_num); 277 278 optc1_program_global_sync(optc); 279 280 /* TODO 281 * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1 282 * program_horz_count_by_2 283 * for DVI 30bpp mode, 0 otherwise 284 * program_horz_count_by_2(optc, &patched_crtc_timing); 285 */ 286 287 /* Enable stereo - only when we need to pack 3D frame. Other types 288 * of stereo handled in explicit call 289 */ 290 291 h_div_2 = optc1_is_two_pixels_per_containter(&patched_crtc_timing); 292 REG_UPDATE(OTG_H_TIMING_CNTL, 293 OTG_H_TIMING_DIV_BY2, h_div_2); 294 295 } 296 297 void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable) 298 { 299 struct optc *optc1 = DCN10TG_FROM_TG(optc); 300 301 uint32_t blank_data_double_buffer_enable = enable ? 1 : 0; 302 303 REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL, 304 OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable); 305 } 306 307 /** 308 * unblank_crtc 309 * Call ASIC Control Object to UnBlank CRTC. 310 */ 311 static void optc1_unblank_crtc(struct timing_generator *optc) 312 { 313 struct optc *optc1 = DCN10TG_FROM_TG(optc); 314 315 REG_UPDATE_2(OTG_BLANK_CONTROL, 316 OTG_BLANK_DATA_EN, 0, 317 OTG_BLANK_DE_MODE, 0); 318 319 /* W/A for automated testing 320 * Automated testing will fail underflow test as there 321 * sporadic underflows which occur during the optc blank 322 * sequence. As a w/a, clear underflow on unblank. 323 * This prevents the failure, but will not mask actual 324 * underflow that affect real use cases. 325 */ 326 optc1_clear_optc_underflow(optc); 327 } 328 329 /** 330 * blank_crtc 331 * Call ASIC Control Object to Blank CRTC. 332 */ 333 334 static void optc1_blank_crtc(struct timing_generator *optc) 335 { 336 struct optc *optc1 = DCN10TG_FROM_TG(optc); 337 338 REG_UPDATE_2(OTG_BLANK_CONTROL, 339 OTG_BLANK_DATA_EN, 1, 340 OTG_BLANK_DE_MODE, 0); 341 342 optc1_set_blank_data_double_buffer(optc, false); 343 } 344 345 void optc1_set_blank(struct timing_generator *optc, 346 bool enable_blanking) 347 { 348 if (enable_blanking) 349 optc1_blank_crtc(optc); 350 else 351 optc1_unblank_crtc(optc); 352 } 353 354 bool optc1_is_blanked(struct timing_generator *optc) 355 { 356 struct optc *optc1 = DCN10TG_FROM_TG(optc); 357 uint32_t blank_en; 358 uint32_t blank_state; 359 360 REG_GET_2(OTG_BLANK_CONTROL, 361 OTG_BLANK_DATA_EN, &blank_en, 362 OTG_CURRENT_BLANK_STATE, &blank_state); 363 364 return blank_en && blank_state; 365 } 366 367 void optc1_enable_optc_clock(struct timing_generator *optc, bool enable) 368 { 369 struct optc *optc1 = DCN10TG_FROM_TG(optc); 370 371 if (enable) { 372 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL, 373 OPTC_INPUT_CLK_EN, 1, 374 OPTC_INPUT_CLK_GATE_DIS, 1); 375 376 REG_WAIT(OPTC_INPUT_CLOCK_CONTROL, 377 OPTC_INPUT_CLK_ON, 1, 378 1, 1000); 379 380 /* Enable clock */ 381 REG_UPDATE_2(OTG_CLOCK_CONTROL, 382 OTG_CLOCK_EN, 1, 383 OTG_CLOCK_GATE_DIS, 1); 384 REG_WAIT(OTG_CLOCK_CONTROL, 385 OTG_CLOCK_ON, 1, 386 1, 1000); 387 } else { 388 REG_UPDATE_2(OTG_CLOCK_CONTROL, 389 OTG_CLOCK_GATE_DIS, 0, 390 OTG_CLOCK_EN, 0); 391 392 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL, 393 OPTC_INPUT_CLK_GATE_DIS, 0, 394 OPTC_INPUT_CLK_EN, 0); 395 } 396 } 397 398 /** 399 * Enable CRTC 400 * Enable CRTC - call ASIC Control Object to enable Timing generator. 401 */ 402 static bool optc1_enable_crtc(struct timing_generator *optc) 403 { 404 /* TODO FPGA wait for answer 405 * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE 406 * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK 407 */ 408 struct optc *optc1 = DCN10TG_FROM_TG(optc); 409 410 /* opp instance for OTG. For DCN1.0, ODM is remoed. 411 * OPP and OPTC should 1:1 mapping 412 */ 413 REG_UPDATE(OPTC_DATA_SOURCE_SELECT, 414 OPTC_SRC_SEL, optc->inst); 415 416 /* VTG enable first is for HW workaround */ 417 REG_UPDATE(CONTROL, 418 VTG0_ENABLE, 1); 419 420 /* Enable CRTC */ 421 REG_UPDATE_2(OTG_CONTROL, 422 OTG_DISABLE_POINT_CNTL, 3, 423 OTG_MASTER_EN, 1); 424 425 return true; 426 } 427 428 /* disable_crtc - call ASIC Control Object to disable Timing generator. */ 429 bool optc1_disable_crtc(struct timing_generator *optc) 430 { 431 struct optc *optc1 = DCN10TG_FROM_TG(optc); 432 433 /* disable otg request until end of the first line 434 * in the vertical blank region 435 */ 436 REG_UPDATE_2(OTG_CONTROL, 437 OTG_DISABLE_POINT_CNTL, 3, 438 OTG_MASTER_EN, 0); 439 440 REG_UPDATE(CONTROL, 441 VTG0_ENABLE, 0); 442 443 /* CRTC disabled, so disable clock. */ 444 REG_WAIT(OTG_CLOCK_CONTROL, 445 OTG_BUSY, 0, 446 1, 100000); 447 448 return true; 449 } 450 451 452 void optc1_program_blank_color( 453 struct timing_generator *optc, 454 const struct tg_color *black_color) 455 { 456 struct optc *optc1 = DCN10TG_FROM_TG(optc); 457 458 REG_SET_3(OTG_BLACK_COLOR, 0, 459 OTG_BLACK_COLOR_B_CB, black_color->color_b_cb, 460 OTG_BLACK_COLOR_G_Y, black_color->color_g_y, 461 OTG_BLACK_COLOR_R_CR, black_color->color_r_cr); 462 } 463 464 bool optc1_validate_timing( 465 struct timing_generator *optc, 466 const struct dc_crtc_timing *timing) 467 { 468 uint32_t v_blank; 469 uint32_t h_blank; 470 uint32_t min_v_blank; 471 struct optc *optc1 = DCN10TG_FROM_TG(optc); 472 473 ASSERT(timing != NULL); 474 475 v_blank = (timing->v_total - timing->v_addressable - 476 timing->v_border_top - timing->v_border_bottom); 477 478 h_blank = (timing->h_total - timing->h_addressable - 479 timing->h_border_right - 480 timing->h_border_left); 481 482 if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE && 483 timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING && 484 timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM && 485 timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE && 486 timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE && 487 timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA) 488 return false; 489 490 /* Temporarily blocking interlacing mode until it's supported */ 491 if (timing->flags.INTERLACE == 1) 492 return false; 493 494 /* Check maximum number of pixels supported by Timing Generator 495 * (Currently will never fail, in order to fail needs display which 496 * needs more than 8192 horizontal and 497 * more than 8192 vertical total pixels) 498 */ 499 if (timing->h_total > optc1->max_h_total || 500 timing->v_total > optc1->max_v_total) 501 return false; 502 503 504 if (h_blank < optc1->min_h_blank) 505 return false; 506 507 if (timing->h_sync_width < optc1->min_h_sync_width || 508 timing->v_sync_width < optc1->min_v_sync_width) 509 return false; 510 511 min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank; 512 513 if (v_blank < min_v_blank) 514 return false; 515 516 return true; 517 518 } 519 520 /* 521 * get_vblank_counter 522 * 523 * @brief 524 * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which 525 * holds the counter of frames. 526 * 527 * @param 528 * struct timing_generator *optc - [in] timing generator which controls the 529 * desired CRTC 530 * 531 * @return 532 * Counter of frames, which should equal to number of vblanks. 533 */ 534 uint32_t optc1_get_vblank_counter(struct timing_generator *optc) 535 { 536 struct optc *optc1 = DCN10TG_FROM_TG(optc); 537 uint32_t frame_count; 538 539 REG_GET(OTG_STATUS_FRAME_COUNT, 540 OTG_FRAME_COUNT, &frame_count); 541 542 return frame_count; 543 } 544 545 void optc1_lock(struct timing_generator *optc) 546 { 547 struct optc *optc1 = DCN10TG_FROM_TG(optc); 548 549 REG_SET(OTG_GLOBAL_CONTROL0, 0, 550 OTG_MASTER_UPDATE_LOCK_SEL, optc->inst); 551 REG_SET(OTG_MASTER_UPDATE_LOCK, 0, 552 OTG_MASTER_UPDATE_LOCK, 1); 553 554 /* Should be fast, status does not update on maximus */ 555 if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS) 556 REG_WAIT(OTG_MASTER_UPDATE_LOCK, 557 UPDATE_LOCK_STATUS, 1, 558 1, 10); 559 } 560 561 void optc1_unlock(struct timing_generator *optc) 562 { 563 struct optc *optc1 = DCN10TG_FROM_TG(optc); 564 565 REG_SET(OTG_MASTER_UPDATE_LOCK, 0, 566 OTG_MASTER_UPDATE_LOCK, 0); 567 } 568 569 void optc1_get_position(struct timing_generator *optc, 570 struct crtc_position *position) 571 { 572 struct optc *optc1 = DCN10TG_FROM_TG(optc); 573 574 REG_GET_2(OTG_STATUS_POSITION, 575 OTG_HORZ_COUNT, &position->horizontal_count, 576 OTG_VERT_COUNT, &position->vertical_count); 577 578 REG_GET(OTG_NOM_VERT_POSITION, 579 OTG_VERT_COUNT_NOM, &position->nominal_vcount); 580 } 581 582 bool optc1_is_counter_moving(struct timing_generator *optc) 583 { 584 struct crtc_position position1, position2; 585 586 optc->funcs->get_position(optc, &position1); 587 optc->funcs->get_position(optc, &position2); 588 589 if (position1.horizontal_count == position2.horizontal_count && 590 position1.vertical_count == position2.vertical_count) 591 return false; 592 else 593 return true; 594 } 595 596 bool optc1_did_triggered_reset_occur( 597 struct timing_generator *optc) 598 { 599 struct optc *optc1 = DCN10TG_FROM_TG(optc); 600 uint32_t occurred_force, occurred_vsync; 601 602 REG_GET(OTG_FORCE_COUNT_NOW_CNTL, 603 OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force); 604 605 REG_GET(OTG_VERT_SYNC_CONTROL, 606 OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync); 607 608 return occurred_vsync != 0 || occurred_force != 0; 609 } 610 611 void optc1_disable_reset_trigger(struct timing_generator *optc) 612 { 613 struct optc *optc1 = DCN10TG_FROM_TG(optc); 614 615 REG_WRITE(OTG_TRIGA_CNTL, 0); 616 617 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0, 618 OTG_FORCE_COUNT_NOW_CLEAR, 1); 619 620 REG_SET(OTG_VERT_SYNC_CONTROL, 0, 621 OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1); 622 } 623 624 void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst) 625 { 626 struct optc *optc1 = DCN10TG_FROM_TG(optc); 627 uint32_t falling_edge; 628 629 REG_GET(OTG_V_SYNC_A_CNTL, 630 OTG_V_SYNC_A_POL, &falling_edge); 631 632 if (falling_edge) 633 REG_SET_3(OTG_TRIGA_CNTL, 0, 634 /* vsync signal from selected OTG pipe based 635 * on OTG_TRIG_SOURCE_PIPE_SELECT setting 636 */ 637 OTG_TRIGA_SOURCE_SELECT, 20, 638 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst, 639 /* always detect falling edge */ 640 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1); 641 else 642 REG_SET_3(OTG_TRIGA_CNTL, 0, 643 /* vsync signal from selected OTG pipe based 644 * on OTG_TRIG_SOURCE_PIPE_SELECT setting 645 */ 646 OTG_TRIGA_SOURCE_SELECT, 20, 647 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst, 648 /* always detect rising edge */ 649 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1); 650 651 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0, 652 /* force H count to H_TOTAL and V count to V_TOTAL in 653 * progressive mode and V_TOTAL-1 in interlaced mode 654 */ 655 OTG_FORCE_COUNT_NOW_MODE, 2); 656 } 657 658 void optc1_enable_crtc_reset( 659 struct timing_generator *optc, 660 int source_tg_inst, 661 struct crtc_trigger_info *crtc_tp) 662 { 663 struct optc *optc1 = DCN10TG_FROM_TG(optc); 664 uint32_t falling_edge = 0; 665 uint32_t rising_edge = 0; 666 667 switch (crtc_tp->event) { 668 669 case CRTC_EVENT_VSYNC_RISING: 670 rising_edge = 1; 671 break; 672 673 case CRTC_EVENT_VSYNC_FALLING: 674 falling_edge = 1; 675 break; 676 } 677 678 REG_SET_4(OTG_TRIGA_CNTL, 0, 679 /* vsync signal from selected OTG pipe based 680 * on OTG_TRIG_SOURCE_PIPE_SELECT setting 681 */ 682 OTG_TRIGA_SOURCE_SELECT, 20, 683 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst, 684 /* always detect falling edge */ 685 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, rising_edge, 686 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, falling_edge); 687 688 switch (crtc_tp->delay) { 689 case TRIGGER_DELAY_NEXT_LINE: 690 REG_SET(OTG_VERT_SYNC_CONTROL, 0, 691 OTG_AUTO_FORCE_VSYNC_MODE, 1); 692 break; 693 case TRIGGER_DELAY_NEXT_PIXEL: 694 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0, 695 /* force H count to H_TOTAL and V count to V_TOTAL in 696 * progressive mode and V_TOTAL-1 in interlaced mode 697 */ 698 OTG_FORCE_COUNT_NOW_MODE, 2); 699 break; 700 } 701 } 702 703 void optc1_wait_for_state(struct timing_generator *optc, 704 enum crtc_state state) 705 { 706 struct optc *optc1 = DCN10TG_FROM_TG(optc); 707 708 switch (state) { 709 case CRTC_STATE_VBLANK: 710 REG_WAIT(OTG_STATUS, 711 OTG_V_BLANK, 1, 712 1, 100000); /* 1 vupdate at 10hz */ 713 break; 714 715 case CRTC_STATE_VACTIVE: 716 REG_WAIT(OTG_STATUS, 717 OTG_V_ACTIVE_DISP, 1, 718 1, 100000); /* 1 vupdate at 10hz */ 719 break; 720 721 default: 722 break; 723 } 724 } 725 726 void optc1_set_early_control( 727 struct timing_generator *optc, 728 uint32_t early_cntl) 729 { 730 /* asic design change, do not need this control 731 * empty for share caller logic 732 */ 733 } 734 735 736 void optc1_set_static_screen_control( 737 struct timing_generator *optc, 738 uint32_t value) 739 { 740 struct optc *optc1 = DCN10TG_FROM_TG(optc); 741 742 /* Bit 8 is no longer applicable in RV for PSR case, 743 * set bit 8 to 0 if given 744 */ 745 if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN) 746 != 0) 747 value = value & 748 ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN; 749 750 REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0, 751 OTG_STATIC_SCREEN_EVENT_MASK, value, 752 OTG_STATIC_SCREEN_FRAME_COUNT, 2); 753 } 754 755 756 /** 757 ***************************************************************************** 758 * Function: set_drr 759 * 760 * @brief 761 * Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*. 762 * 763 ***************************************************************************** 764 */ 765 void optc1_set_drr( 766 struct timing_generator *optc, 767 const struct drr_params *params) 768 { 769 struct optc *optc1 = DCN10TG_FROM_TG(optc); 770 771 if (params != NULL && 772 params->vertical_total_max > 0 && 773 params->vertical_total_min > 0) { 774 775 REG_SET(OTG_V_TOTAL_MAX, 0, 776 OTG_V_TOTAL_MAX, params->vertical_total_max - 1); 777 778 REG_SET(OTG_V_TOTAL_MIN, 0, 779 OTG_V_TOTAL_MIN, params->vertical_total_min - 1); 780 781 REG_UPDATE_5(OTG_V_TOTAL_CONTROL, 782 OTG_V_TOTAL_MIN_SEL, 1, 783 OTG_V_TOTAL_MAX_SEL, 1, 784 OTG_FORCE_LOCK_ON_EVENT, 0, 785 OTG_SET_V_TOTAL_MIN_MASK_EN, 0, 786 OTG_SET_V_TOTAL_MIN_MASK, 0); 787 } else { 788 REG_UPDATE_4(OTG_V_TOTAL_CONTROL, 789 OTG_SET_V_TOTAL_MIN_MASK, 0, 790 OTG_V_TOTAL_MIN_SEL, 0, 791 OTG_V_TOTAL_MAX_SEL, 0, 792 OTG_FORCE_LOCK_ON_EVENT, 0); 793 794 REG_SET(OTG_V_TOTAL_MIN, 0, 795 OTG_V_TOTAL_MIN, 0); 796 797 REG_SET(OTG_V_TOTAL_MAX, 0, 798 OTG_V_TOTAL_MAX, 0); 799 } 800 } 801 802 static void optc1_set_test_pattern( 803 struct timing_generator *optc, 804 /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' 805 * because this is not DP-specific (which is probably somewhere in DP 806 * encoder) */ 807 enum controller_dp_test_pattern test_pattern, 808 enum dc_color_depth color_depth) 809 { 810 struct optc *optc1 = DCN10TG_FROM_TG(optc); 811 enum test_pattern_color_format bit_depth; 812 enum test_pattern_dyn_range dyn_range; 813 enum test_pattern_mode mode; 814 uint32_t pattern_mask; 815 uint32_t pattern_data; 816 /* color ramp generator mixes 16-bits color */ 817 uint32_t src_bpc = 16; 818 /* requested bpc */ 819 uint32_t dst_bpc; 820 uint32_t index; 821 /* RGB values of the color bars. 822 * Produce two RGB colors: RGB0 - white (all Fs) 823 * and RGB1 - black (all 0s) 824 * (three RGB components for two colors) 825 */ 826 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 827 0x0000, 0x0000}; 828 /* dest color (converted to the specified color format) */ 829 uint16_t dst_color[6]; 830 uint32_t inc_base; 831 832 /* translate to bit depth */ 833 switch (color_depth) { 834 case COLOR_DEPTH_666: 835 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; 836 break; 837 case COLOR_DEPTH_888: 838 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 839 break; 840 case COLOR_DEPTH_101010: 841 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; 842 break; 843 case COLOR_DEPTH_121212: 844 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; 845 break; 846 default: 847 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 848 break; 849 } 850 851 switch (test_pattern) { 852 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: 853 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: 854 { 855 dyn_range = (test_pattern == 856 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? 857 TEST_PATTERN_DYN_RANGE_CEA : 858 TEST_PATTERN_DYN_RANGE_VESA); 859 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; 860 861 REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS, 862 OTG_TEST_PATTERN_VRES, 6, 863 OTG_TEST_PATTERN_HRES, 6); 864 865 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL, 866 OTG_TEST_PATTERN_EN, 1, 867 OTG_TEST_PATTERN_MODE, mode, 868 OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range, 869 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth); 870 } 871 break; 872 873 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: 874 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: 875 { 876 mode = (test_pattern == 877 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? 878 TEST_PATTERN_MODE_VERTICALBARS : 879 TEST_PATTERN_MODE_HORIZONTALBARS); 880 881 switch (bit_depth) { 882 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 883 dst_bpc = 6; 884 break; 885 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 886 dst_bpc = 8; 887 break; 888 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 889 dst_bpc = 10; 890 break; 891 default: 892 dst_bpc = 8; 893 break; 894 } 895 896 /* adjust color to the required colorFormat */ 897 for (index = 0; index < 6; index++) { 898 /* dst = 2^dstBpc * src / 2^srcBpc = src >> 899 * (srcBpc - dstBpc); 900 */ 901 dst_color[index] = 902 src_color[index] >> (src_bpc - dst_bpc); 903 /* CRTC_TEST_PATTERN_DATA has 16 bits, 904 * lowest 6 are hardwired to ZERO 905 * color bits should be left aligned aligned to MSB 906 * XXXXXXXXXX000000 for 10 bit, 907 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6 908 */ 909 dst_color[index] <<= (16 - dst_bpc); 910 } 911 912 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0); 913 914 /* We have to write the mask before data, similar to pipeline. 915 * For example, for 8 bpc, if we want RGB0 to be magenta, 916 * and RGB1 to be cyan, 917 * we need to make 7 writes: 918 * MASK DATA 919 * 000001 00000000 00000000 set mask to R0 920 * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0 921 * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0 922 * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1 923 * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1 924 * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1 925 * 100000 11111111 00000000 B1 255, 0xFF00 926 * 927 * we will make a loop of 6 in which we prepare the mask, 928 * then write, then prepare the color for next write. 929 * first iteration will write mask only, 930 * but each next iteration color prepared in 931 * previous iteration will be written within new mask, 932 * the last component will written separately, 933 * mask is not changing between 6th and 7th write 934 * and color will be prepared by last iteration 935 */ 936 937 /* write color, color values mask in CRTC_TEST_PATTERN_MASK 938 * is B1, G1, R1, B0, G0, R0 939 */ 940 pattern_data = 0; 941 for (index = 0; index < 6; index++) { 942 /* prepare color mask, first write PATTERN_DATA 943 * will have all zeros 944 */ 945 pattern_mask = (1 << index); 946 947 /* write color component */ 948 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0, 949 OTG_TEST_PATTERN_MASK, pattern_mask, 950 OTG_TEST_PATTERN_DATA, pattern_data); 951 952 /* prepare next color component, 953 * will be written in the next iteration 954 */ 955 pattern_data = dst_color[index]; 956 } 957 /* write last color component, 958 * it's been already prepared in the loop 959 */ 960 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0, 961 OTG_TEST_PATTERN_MASK, pattern_mask, 962 OTG_TEST_PATTERN_DATA, pattern_data); 963 964 /* enable test pattern */ 965 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL, 966 OTG_TEST_PATTERN_EN, 1, 967 OTG_TEST_PATTERN_MODE, mode, 968 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0, 969 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth); 970 } 971 break; 972 973 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: 974 { 975 mode = (bit_depth == 976 TEST_PATTERN_COLOR_FORMAT_BPC_10 ? 977 TEST_PATTERN_MODE_DUALRAMP_RGB : 978 TEST_PATTERN_MODE_SINGLERAMP_RGB); 979 980 switch (bit_depth) { 981 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 982 dst_bpc = 6; 983 break; 984 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 985 dst_bpc = 8; 986 break; 987 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 988 dst_bpc = 10; 989 break; 990 default: 991 dst_bpc = 8; 992 break; 993 } 994 995 /* increment for the first ramp for one color gradation 996 * 1 gradation for 6-bit color is 2^10 997 * gradations in 16-bit color 998 */ 999 inc_base = (src_bpc - dst_bpc); 1000 1001 switch (bit_depth) { 1002 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1003 { 1004 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS, 1005 OTG_TEST_PATTERN_INC0, inc_base, 1006 OTG_TEST_PATTERN_INC1, 0, 1007 OTG_TEST_PATTERN_HRES, 6, 1008 OTG_TEST_PATTERN_VRES, 6, 1009 OTG_TEST_PATTERN_RAMP0_OFFSET, 0); 1010 } 1011 break; 1012 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1013 { 1014 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS, 1015 OTG_TEST_PATTERN_INC0, inc_base, 1016 OTG_TEST_PATTERN_INC1, 0, 1017 OTG_TEST_PATTERN_HRES, 8, 1018 OTG_TEST_PATTERN_VRES, 6, 1019 OTG_TEST_PATTERN_RAMP0_OFFSET, 0); 1020 } 1021 break; 1022 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1023 { 1024 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS, 1025 OTG_TEST_PATTERN_INC0, inc_base, 1026 OTG_TEST_PATTERN_INC1, inc_base + 2, 1027 OTG_TEST_PATTERN_HRES, 8, 1028 OTG_TEST_PATTERN_VRES, 5, 1029 OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6); 1030 } 1031 break; 1032 default: 1033 break; 1034 } 1035 1036 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0); 1037 1038 /* enable test pattern */ 1039 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0); 1040 1041 REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0, 1042 OTG_TEST_PATTERN_EN, 1, 1043 OTG_TEST_PATTERN_MODE, mode, 1044 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0, 1045 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth); 1046 } 1047 break; 1048 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: 1049 { 1050 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0); 1051 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0); 1052 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0); 1053 } 1054 break; 1055 default: 1056 break; 1057 1058 } 1059 } 1060 1061 void optc1_get_crtc_scanoutpos( 1062 struct timing_generator *optc, 1063 uint32_t *v_blank_start, 1064 uint32_t *v_blank_end, 1065 uint32_t *h_position, 1066 uint32_t *v_position) 1067 { 1068 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1069 struct crtc_position position; 1070 1071 REG_GET_2(OTG_V_BLANK_START_END, 1072 OTG_V_BLANK_START, v_blank_start, 1073 OTG_V_BLANK_END, v_blank_end); 1074 1075 optc1_get_position(optc, &position); 1076 1077 *h_position = position.horizontal_count; 1078 *v_position = position.vertical_count; 1079 } 1080 1081 static void optc1_enable_stereo(struct timing_generator *optc, 1082 const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags) 1083 { 1084 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1085 1086 if (flags) { 1087 uint32_t stereo_en; 1088 stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0; 1089 1090 if (flags->PROGRAM_STEREO) 1091 REG_UPDATE_3(OTG_STEREO_CONTROL, 1092 OTG_STEREO_EN, stereo_en, 1093 OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0, 1094 OTG_STEREO_SYNC_OUTPUT_POLARITY, 0); 1095 1096 if (flags->PROGRAM_POLARITY) 1097 REG_UPDATE(OTG_STEREO_CONTROL, 1098 OTG_STEREO_EYE_FLAG_POLARITY, 1099 flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1); 1100 1101 if (flags->DISABLE_STEREO_DP_SYNC) 1102 REG_UPDATE(OTG_STEREO_CONTROL, 1103 OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1); 1104 1105 if (flags->PROGRAM_STEREO) 1106 REG_UPDATE_2(OTG_3D_STRUCTURE_CONTROL, 1107 OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED, 1108 OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED); 1109 1110 } 1111 } 1112 1113 void optc1_program_stereo(struct timing_generator *optc, 1114 const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags) 1115 { 1116 if (flags->PROGRAM_STEREO) 1117 optc1_enable_stereo(optc, timing, flags); 1118 else 1119 optc1_disable_stereo(optc); 1120 } 1121 1122 1123 bool optc1_is_stereo_left_eye(struct timing_generator *optc) 1124 { 1125 bool ret = false; 1126 uint32_t left_eye = 0; 1127 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1128 1129 REG_GET(OTG_STEREO_STATUS, 1130 OTG_STEREO_CURRENT_EYE, &left_eye); 1131 if (left_eye == 1) 1132 ret = true; 1133 else 1134 ret = false; 1135 1136 return ret; 1137 } 1138 1139 void optc1_read_otg_state(struct optc *optc1, 1140 struct dcn_otg_state *s) 1141 { 1142 REG_GET(OTG_CONTROL, 1143 OTG_MASTER_EN, &s->otg_enabled); 1144 1145 REG_GET_2(OTG_V_BLANK_START_END, 1146 OTG_V_BLANK_START, &s->v_blank_start, 1147 OTG_V_BLANK_END, &s->v_blank_end); 1148 1149 REG_GET(OTG_V_SYNC_A_CNTL, 1150 OTG_V_SYNC_A_POL, &s->v_sync_a_pol); 1151 1152 REG_GET(OTG_V_TOTAL, 1153 OTG_V_TOTAL, &s->v_total); 1154 1155 REG_GET(OTG_V_TOTAL_MAX, 1156 OTG_V_TOTAL_MAX, &s->v_total_max); 1157 1158 REG_GET(OTG_V_TOTAL_MIN, 1159 OTG_V_TOTAL_MIN, &s->v_total_min); 1160 1161 REG_GET(OTG_V_TOTAL_CONTROL, 1162 OTG_V_TOTAL_MAX_SEL, &s->v_total_max_sel); 1163 1164 REG_GET(OTG_V_TOTAL_CONTROL, 1165 OTG_V_TOTAL_MIN_SEL, &s->v_total_min_sel); 1166 1167 REG_GET_2(OTG_V_SYNC_A, 1168 OTG_V_SYNC_A_START, &s->v_sync_a_start, 1169 OTG_V_SYNC_A_END, &s->v_sync_a_end); 1170 1171 REG_GET_2(OTG_H_BLANK_START_END, 1172 OTG_H_BLANK_START, &s->h_blank_start, 1173 OTG_H_BLANK_END, &s->h_blank_end); 1174 1175 REG_GET_2(OTG_H_SYNC_A, 1176 OTG_H_SYNC_A_START, &s->h_sync_a_start, 1177 OTG_H_SYNC_A_END, &s->h_sync_a_end); 1178 1179 REG_GET(OTG_H_SYNC_A_CNTL, 1180 OTG_H_SYNC_A_POL, &s->h_sync_a_pol); 1181 1182 REG_GET(OTG_H_TOTAL, 1183 OTG_H_TOTAL, &s->h_total); 1184 1185 REG_GET(OPTC_INPUT_GLOBAL_CONTROL, 1186 OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status); 1187 } 1188 1189 bool optc1_get_otg_active_size(struct timing_generator *optc, 1190 uint32_t *otg_active_width, 1191 uint32_t *otg_active_height) 1192 { 1193 uint32_t otg_enabled; 1194 uint32_t v_blank_start; 1195 uint32_t v_blank_end; 1196 uint32_t h_blank_start; 1197 uint32_t h_blank_end; 1198 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1199 1200 1201 REG_GET(OTG_CONTROL, 1202 OTG_MASTER_EN, &otg_enabled); 1203 1204 if (otg_enabled == 0) 1205 return false; 1206 1207 REG_GET_2(OTG_V_BLANK_START_END, 1208 OTG_V_BLANK_START, &v_blank_start, 1209 OTG_V_BLANK_END, &v_blank_end); 1210 1211 REG_GET_2(OTG_H_BLANK_START_END, 1212 OTG_H_BLANK_START, &h_blank_start, 1213 OTG_H_BLANK_END, &h_blank_end); 1214 1215 *otg_active_width = v_blank_start - v_blank_end; 1216 *otg_active_height = h_blank_start - h_blank_end; 1217 return true; 1218 } 1219 1220 void optc1_clear_optc_underflow(struct timing_generator *optc) 1221 { 1222 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1223 1224 REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1); 1225 } 1226 1227 void optc1_tg_init(struct timing_generator *optc) 1228 { 1229 optc1_set_blank_data_double_buffer(optc, true); 1230 optc1_clear_optc_underflow(optc); 1231 } 1232 1233 bool optc1_is_tg_enabled(struct timing_generator *optc) 1234 { 1235 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1236 uint32_t otg_enabled = 0; 1237 1238 REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled); 1239 1240 return (otg_enabled != 0); 1241 1242 } 1243 1244 bool optc1_is_optc_underflow_occurred(struct timing_generator *optc) 1245 { 1246 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1247 uint32_t underflow_occurred = 0; 1248 1249 REG_GET(OPTC_INPUT_GLOBAL_CONTROL, 1250 OPTC_UNDERFLOW_OCCURRED_STATUS, 1251 &underflow_occurred); 1252 1253 return (underflow_occurred == 1); 1254 } 1255 1256 bool optc1_configure_crc(struct timing_generator *optc, 1257 const struct crc_params *params) 1258 { 1259 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1260 1261 /* Cannot configure crc on a CRTC that is disabled */ 1262 if (!optc1_is_tg_enabled(optc)) 1263 return false; 1264 1265 REG_WRITE(OTG_CRC_CNTL, 0); 1266 1267 if (!params->enable) 1268 return true; 1269 1270 /* Program frame boundaries */ 1271 /* Window A x axis start and end. */ 1272 REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL, 1273 OTG_CRC0_WINDOWA_X_START, params->windowa_x_start, 1274 OTG_CRC0_WINDOWA_X_END, params->windowa_x_end); 1275 1276 /* Window A y axis start and end. */ 1277 REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL, 1278 OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start, 1279 OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end); 1280 1281 /* Window B x axis start and end. */ 1282 REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL, 1283 OTG_CRC0_WINDOWB_X_START, params->windowb_x_start, 1284 OTG_CRC0_WINDOWB_X_END, params->windowb_x_end); 1285 1286 /* Window B y axis start and end. */ 1287 REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL, 1288 OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start, 1289 OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end); 1290 1291 /* Set crc mode and selection, and enable. Only using CRC0*/ 1292 REG_UPDATE_3(OTG_CRC_CNTL, 1293 OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 1294 OTG_CRC0_SELECT, params->selection, 1295 OTG_CRC_EN, 1); 1296 1297 return true; 1298 } 1299 1300 bool optc1_get_crc(struct timing_generator *optc, 1301 uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) 1302 { 1303 uint32_t field = 0; 1304 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1305 1306 REG_GET(OTG_CRC_CNTL, OTG_CRC_EN, &field); 1307 1308 /* Early return if CRC is not enabled for this CRTC */ 1309 if (!field) 1310 return false; 1311 1312 REG_GET_2(OTG_CRC0_DATA_RG, 1313 CRC0_R_CR, r_cr, 1314 CRC0_G_Y, g_y); 1315 1316 REG_GET(OTG_CRC0_DATA_B, 1317 CRC0_B_CB, b_cb); 1318 1319 return true; 1320 } 1321 1322 static const struct timing_generator_funcs dcn10_tg_funcs = { 1323 .validate_timing = optc1_validate_timing, 1324 .program_timing = optc1_program_timing, 1325 .program_vline_interrupt = optc1_program_vline_interrupt, 1326 .program_global_sync = optc1_program_global_sync, 1327 .enable_crtc = optc1_enable_crtc, 1328 .disable_crtc = optc1_disable_crtc, 1329 /* used by enable_timing_synchronization. Not need for FPGA */ 1330 .is_counter_moving = optc1_is_counter_moving, 1331 .get_position = optc1_get_position, 1332 .get_frame_count = optc1_get_vblank_counter, 1333 .get_scanoutpos = optc1_get_crtc_scanoutpos, 1334 .get_otg_active_size = optc1_get_otg_active_size, 1335 .set_early_control = optc1_set_early_control, 1336 /* used by enable_timing_synchronization. Not need for FPGA */ 1337 .wait_for_state = optc1_wait_for_state, 1338 .set_blank = optc1_set_blank, 1339 .is_blanked = optc1_is_blanked, 1340 .set_blank_color = optc1_program_blank_color, 1341 .did_triggered_reset_occur = optc1_did_triggered_reset_occur, 1342 .enable_reset_trigger = optc1_enable_reset_trigger, 1343 .enable_crtc_reset = optc1_enable_crtc_reset, 1344 .disable_reset_trigger = optc1_disable_reset_trigger, 1345 .lock = optc1_lock, 1346 .unlock = optc1_unlock, 1347 .enable_optc_clock = optc1_enable_optc_clock, 1348 .set_drr = optc1_set_drr, 1349 .set_static_screen_control = optc1_set_static_screen_control, 1350 .set_test_pattern = optc1_set_test_pattern, 1351 .program_stereo = optc1_program_stereo, 1352 .is_stereo_left_eye = optc1_is_stereo_left_eye, 1353 .set_blank_data_double_buffer = optc1_set_blank_data_double_buffer, 1354 .tg_init = optc1_tg_init, 1355 .is_tg_enabled = optc1_is_tg_enabled, 1356 .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, 1357 .clear_optc_underflow = optc1_clear_optc_underflow, 1358 .get_crc = optc1_get_crc, 1359 .configure_crc = optc1_configure_crc, 1360 }; 1361 1362 void dcn10_timing_generator_init(struct optc *optc1) 1363 { 1364 optc1->base.funcs = &dcn10_tg_funcs; 1365 1366 optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1; 1367 optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1; 1368 1369 optc1->min_h_blank = 32; 1370 optc1->min_v_blank = 3; 1371 optc1->min_v_blank_interlace = 5; 1372 optc1->min_h_sync_width = 8; 1373 optc1->min_v_sync_width = 1; 1374 } 1375 1376 bool optc1_is_two_pixels_per_containter(const struct dc_crtc_timing *timing) 1377 { 1378 return timing->pixel_encoding == PIXEL_ENCODING_YCBCR420; 1379 } 1380 1381