root/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dce110_timing_generator_v_enable_crtc
  2. dce110_timing_generator_v_disable_crtc
  3. dce110_timing_generator_v_blank_crtc
  4. dce110_timing_generator_v_unblank_crtc
  5. dce110_timing_generator_v_is_in_vertical_blank
  6. dce110_timing_generator_v_is_counter_moving
  7. dce110_timing_generator_v_wait_for_vblank
  8. dce110_timing_generator_v_wait_for_vactive
  9. dce110_timing_generator_v_wait_for_state
  10. dce110_timing_generator_v_program_blanking
  11. dce110_timing_generator_v_enable_advanced_request
  12. dce110_timing_generator_v_set_blank
  13. dce110_timing_generator_v_program_timing
  14. dce110_timing_generator_v_program_blank_color
  15. dce110_timing_generator_v_set_overscan_color_black
  16. dce110_tg_v_program_blank_color
  17. dce110_timing_generator_v_set_overscan_color
  18. dce110_timing_generator_v_set_colors
  19. dce110_timing_generator_v_set_early_control
  20. dce110_timing_generator_v_get_vblank_counter
  21. dce110_timing_generator_v_did_triggered_reset_occur
  22. dce110_timing_generator_v_setup_global_swap_lock
  23. dce110_timing_generator_v_enable_reset_trigger
  24. dce110_timing_generator_v_disable_reset_trigger
  25. dce110_timing_generator_v_tear_down_global_swap_lock
  26. dce110_timing_generator_v_disable_vga
  27. dce110_timing_generator_v_construct

   1 /*
   2  * Copyright 2017 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  */
  23 
  24 #include "dm_services.h"
  25 
  26 /* include DCE11 register header files */
  27 #include "dce/dce_11_0_d.h"
  28 #include "dce/dce_11_0_sh_mask.h"
  29 
  30 #include "dc_types.h"
  31 #include "dc_bios_types.h"
  32 #include "dc.h"
  33 
  34 #include "include/grph_object_id.h"
  35 #include "include/logger_interface.h"
  36 #include "dce110_timing_generator.h"
  37 #include "dce110_timing_generator_v.h"
  38 
  39 #include "timing_generator.h"
  40 
  41 #define DC_LOGGER \
  42         tg->ctx->logger
  43 /** ********************************************************************************
  44  *
  45  * DCE11 Timing Generator Implementation
  46  *
  47  **********************************************************************************/
  48 
  49 /**
  50 * Enable CRTCV
  51 */
  52 
  53 static bool dce110_timing_generator_v_enable_crtc(struct timing_generator *tg)
  54 {
  55 /*
  56 * Set MASTER_UPDATE_MODE to 0
  57 * This is needed for DRR, and also suggested to be default value by Syed.
  58 */
  59 
  60         uint32_t value;
  61 
  62         value = 0;
  63         set_reg_field_value(value, 0,
  64                         CRTCV_MASTER_UPDATE_MODE, MASTER_UPDATE_MODE);
  65         dm_write_reg(tg->ctx,
  66                         mmCRTCV_MASTER_UPDATE_MODE, value);
  67 
  68         /* TODO: may want this on for looking for underflow */
  69         value = 0;
  70         dm_write_reg(tg->ctx, mmCRTCV_MASTER_UPDATE_MODE, value);
  71 
  72         value = 0;
  73         set_reg_field_value(value, 1,
  74                         CRTCV_MASTER_EN, CRTC_MASTER_EN);
  75         dm_write_reg(tg->ctx,
  76                         mmCRTCV_MASTER_EN, value);
  77 
  78         return true;
  79 }
  80 
  81 static bool dce110_timing_generator_v_disable_crtc(struct timing_generator *tg)
  82 {
  83         uint32_t value;
  84 
  85         value = dm_read_reg(tg->ctx,
  86                         mmCRTCV_CONTROL);
  87         set_reg_field_value(value, 0,
  88                         CRTCV_CONTROL, CRTC_DISABLE_POINT_CNTL);
  89         set_reg_field_value(value, 0,
  90                                 CRTCV_CONTROL, CRTC_MASTER_EN);
  91         dm_write_reg(tg->ctx,
  92                         mmCRTCV_CONTROL, value);
  93         /*
  94          * TODO: call this when adding stereo support
  95          * tg->funcs->disable_stereo(tg);
  96          */
  97         return true;
  98 }
  99 
 100 static void dce110_timing_generator_v_blank_crtc(struct timing_generator *tg)
 101 {
 102         uint32_t addr = mmCRTCV_BLANK_CONTROL;
 103         uint32_t value = dm_read_reg(tg->ctx, addr);
 104 
 105         set_reg_field_value(
 106                 value,
 107                 1,
 108                 CRTCV_BLANK_CONTROL,
 109                 CRTC_BLANK_DATA_EN);
 110 
 111         set_reg_field_value(
 112                 value,
 113                 0,
 114                 CRTCV_BLANK_CONTROL,
 115                 CRTC_BLANK_DE_MODE);
 116 
 117         dm_write_reg(tg->ctx, addr, value);
 118 }
 119 
 120 static void dce110_timing_generator_v_unblank_crtc(struct timing_generator *tg)
 121 {
 122         uint32_t addr = mmCRTCV_BLANK_CONTROL;
 123         uint32_t value = dm_read_reg(tg->ctx, addr);
 124 
 125         set_reg_field_value(
 126                 value,
 127                 0,
 128                 CRTCV_BLANK_CONTROL,
 129                 CRTC_BLANK_DATA_EN);
 130 
 131         set_reg_field_value(
 132                 value,
 133                 0,
 134                 CRTCV_BLANK_CONTROL,
 135                 CRTC_BLANK_DE_MODE);
 136 
 137         dm_write_reg(tg->ctx, addr, value);
 138 }
 139 
 140 static bool dce110_timing_generator_v_is_in_vertical_blank(
 141                 struct timing_generator *tg)
 142 {
 143         uint32_t addr = 0;
 144         uint32_t value = 0;
 145         uint32_t field = 0;
 146 
 147         addr = mmCRTCV_STATUS;
 148         value = dm_read_reg(tg->ctx, addr);
 149         field = get_reg_field_value(value, CRTCV_STATUS, CRTC_V_BLANK);
 150         return field == 1;
 151 }
 152 
 153 static bool dce110_timing_generator_v_is_counter_moving(struct timing_generator *tg)
 154 {
 155         uint32_t value;
 156         uint32_t h1 = 0;
 157         uint32_t h2 = 0;
 158         uint32_t v1 = 0;
 159         uint32_t v2 = 0;
 160 
 161         value = dm_read_reg(tg->ctx, mmCRTCV_STATUS_POSITION);
 162 
 163         h1 = get_reg_field_value(
 164                         value,
 165                         CRTCV_STATUS_POSITION,
 166                         CRTC_HORZ_COUNT);
 167 
 168         v1 = get_reg_field_value(
 169                         value,
 170                         CRTCV_STATUS_POSITION,
 171                         CRTC_VERT_COUNT);
 172 
 173         value = dm_read_reg(tg->ctx, mmCRTCV_STATUS_POSITION);
 174 
 175         h2 = get_reg_field_value(
 176                         value,
 177                         CRTCV_STATUS_POSITION,
 178                         CRTC_HORZ_COUNT);
 179 
 180         v2 = get_reg_field_value(
 181                         value,
 182                         CRTCV_STATUS_POSITION,
 183                         CRTC_VERT_COUNT);
 184 
 185         if (h1 == h2 && v1 == v2)
 186                 return false;
 187         else
 188                 return true;
 189 }
 190 
 191 static void dce110_timing_generator_v_wait_for_vblank(struct timing_generator *tg)
 192 {
 193         /* We want to catch beginning of VBlank here, so if the first try are
 194          * in VBlank, we might be very close to Active, in this case wait for
 195          * another frame
 196          */
 197         while (dce110_timing_generator_v_is_in_vertical_blank(tg)) {
 198                 if (!dce110_timing_generator_v_is_counter_moving(tg)) {
 199                         /* error - no point to wait if counter is not moving */
 200                         break;
 201                 }
 202         }
 203 
 204         while (!dce110_timing_generator_v_is_in_vertical_blank(tg)) {
 205                 if (!dce110_timing_generator_v_is_counter_moving(tg)) {
 206                         /* error - no point to wait if counter is not moving */
 207                         break;
 208                 }
 209         }
 210 }
 211 
 212 /**
 213 * Wait till we are in VActive (anywhere in VActive)
 214 */
 215 static void dce110_timing_generator_v_wait_for_vactive(struct timing_generator *tg)
 216 {
 217         while (dce110_timing_generator_v_is_in_vertical_blank(tg)) {
 218                 if (!dce110_timing_generator_v_is_counter_moving(tg)) {
 219                         /* error - no point to wait if counter is not moving */
 220                         break;
 221                 }
 222         }
 223 }
 224 
 225 static void dce110_timing_generator_v_wait_for_state(struct timing_generator *tg,
 226         enum crtc_state state)
 227 {
 228         switch (state) {
 229         case CRTC_STATE_VBLANK:
 230                 dce110_timing_generator_v_wait_for_vblank(tg);
 231                 break;
 232 
 233         case CRTC_STATE_VACTIVE:
 234                 dce110_timing_generator_v_wait_for_vactive(tg);
 235                 break;
 236 
 237         default:
 238                 break;
 239         }
 240 }
 241 
 242 static void dce110_timing_generator_v_program_blanking(
 243         struct timing_generator *tg,
 244         const struct dc_crtc_timing *timing)
 245 {
 246         uint32_t vsync_offset = timing->v_border_bottom +
 247                         timing->v_front_porch;
 248         uint32_t v_sync_start = timing->v_addressable + vsync_offset;
 249 
 250         uint32_t hsync_offset = timing->h_border_right +
 251                         timing->h_front_porch;
 252         uint32_t h_sync_start = timing->h_addressable + hsync_offset;
 253 
 254         struct dc_context *ctx = tg->ctx;
 255         uint32_t value = 0;
 256         uint32_t addr = 0;
 257         uint32_t tmp = 0;
 258 
 259         addr = mmCRTCV_H_TOTAL;
 260         value = dm_read_reg(ctx, addr);
 261         set_reg_field_value(
 262                 value,
 263                 timing->h_total - 1,
 264                 CRTCV_H_TOTAL,
 265                 CRTC_H_TOTAL);
 266         dm_write_reg(ctx, addr, value);
 267 
 268         addr = mmCRTCV_V_TOTAL;
 269         value = dm_read_reg(ctx, addr);
 270         set_reg_field_value(
 271                 value,
 272                 timing->v_total - 1,
 273                 CRTCV_V_TOTAL,
 274                 CRTC_V_TOTAL);
 275         dm_write_reg(ctx, addr, value);
 276 
 277         addr = mmCRTCV_H_BLANK_START_END;
 278         value = dm_read_reg(ctx, addr);
 279 
 280         tmp = timing->h_total -
 281                 (h_sync_start + timing->h_border_left);
 282 
 283         set_reg_field_value(
 284                 value,
 285                 tmp,
 286                 CRTCV_H_BLANK_START_END,
 287                 CRTC_H_BLANK_END);
 288 
 289         tmp = tmp + timing->h_addressable +
 290                 timing->h_border_left + timing->h_border_right;
 291 
 292         set_reg_field_value(
 293                 value,
 294                 tmp,
 295                 CRTCV_H_BLANK_START_END,
 296                 CRTC_H_BLANK_START);
 297 
 298         dm_write_reg(ctx, addr, value);
 299 
 300         addr = mmCRTCV_V_BLANK_START_END;
 301         value = dm_read_reg(ctx, addr);
 302 
 303         tmp = timing->v_total - (v_sync_start + timing->v_border_top);
 304 
 305         set_reg_field_value(
 306                 value,
 307                 tmp,
 308                 CRTCV_V_BLANK_START_END,
 309                 CRTC_V_BLANK_END);
 310 
 311         tmp = tmp + timing->v_addressable + timing->v_border_top +
 312                 timing->v_border_bottom;
 313 
 314         set_reg_field_value(
 315                 value,
 316                 tmp,
 317                 CRTCV_V_BLANK_START_END,
 318                 CRTC_V_BLANK_START);
 319 
 320         dm_write_reg(ctx, addr, value);
 321 
 322         addr = mmCRTCV_H_SYNC_A;
 323         value = 0;
 324         set_reg_field_value(
 325                 value,
 326                 timing->h_sync_width,
 327                 CRTCV_H_SYNC_A,
 328                 CRTC_H_SYNC_A_END);
 329         dm_write_reg(ctx, addr, value);
 330 
 331         addr = mmCRTCV_H_SYNC_A_CNTL;
 332         value = dm_read_reg(ctx, addr);
 333         if (timing->flags.HSYNC_POSITIVE_POLARITY) {
 334                 set_reg_field_value(
 335                         value,
 336                         0,
 337                         CRTCV_H_SYNC_A_CNTL,
 338                         CRTC_H_SYNC_A_POL);
 339         } else {
 340                 set_reg_field_value(
 341                         value,
 342                         1,
 343                         CRTCV_H_SYNC_A_CNTL,
 344                         CRTC_H_SYNC_A_POL);
 345         }
 346         dm_write_reg(ctx, addr, value);
 347 
 348         addr = mmCRTCV_V_SYNC_A;
 349         value = 0;
 350         set_reg_field_value(
 351                 value,
 352                 timing->v_sync_width,
 353                 CRTCV_V_SYNC_A,
 354                 CRTC_V_SYNC_A_END);
 355         dm_write_reg(ctx, addr, value);
 356 
 357         addr = mmCRTCV_V_SYNC_A_CNTL;
 358         value = dm_read_reg(ctx, addr);
 359         if (timing->flags.VSYNC_POSITIVE_POLARITY) {
 360                 set_reg_field_value(
 361                         value,
 362                         0,
 363                         CRTCV_V_SYNC_A_CNTL,
 364                         CRTC_V_SYNC_A_POL);
 365         } else {
 366                 set_reg_field_value(
 367                         value,
 368                         1,
 369                         CRTCV_V_SYNC_A_CNTL,
 370                         CRTC_V_SYNC_A_POL);
 371         }
 372         dm_write_reg(ctx, addr, value);
 373 
 374         addr = mmCRTCV_INTERLACE_CONTROL;
 375         value = dm_read_reg(ctx, addr);
 376         set_reg_field_value(
 377                 value,
 378                 timing->flags.INTERLACE,
 379                 CRTCV_INTERLACE_CONTROL,
 380                 CRTC_INTERLACE_ENABLE);
 381         dm_write_reg(ctx, addr, value);
 382 }
 383 
 384 static void dce110_timing_generator_v_enable_advanced_request(
 385         struct timing_generator *tg,
 386         bool enable,
 387         const struct dc_crtc_timing *timing)
 388 {
 389         uint32_t addr = mmCRTCV_START_LINE_CONTROL;
 390         uint32_t value = dm_read_reg(tg->ctx, addr);
 391 
 392         if (enable) {
 393                 if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
 394                         set_reg_field_value(
 395                                 value,
 396                                 3,
 397                                 CRTCV_START_LINE_CONTROL,
 398                                 CRTC_ADVANCED_START_LINE_POSITION);
 399                 } else {
 400                         set_reg_field_value(
 401                                 value,
 402                                 4,
 403                                 CRTCV_START_LINE_CONTROL,
 404                                 CRTC_ADVANCED_START_LINE_POSITION);
 405                 }
 406                 set_reg_field_value(
 407                         value,
 408                         0,
 409                         CRTCV_START_LINE_CONTROL,
 410                         CRTC_LEGACY_REQUESTOR_EN);
 411         } else {
 412                 set_reg_field_value(
 413                         value,
 414                         2,
 415                         CRTCV_START_LINE_CONTROL,
 416                         CRTC_ADVANCED_START_LINE_POSITION);
 417                 set_reg_field_value(
 418                         value,
 419                         1,
 420                         CRTCV_START_LINE_CONTROL,
 421                         CRTC_LEGACY_REQUESTOR_EN);
 422         }
 423 
 424         dm_write_reg(tg->ctx, addr, value);
 425 }
 426 
 427 static void dce110_timing_generator_v_set_blank(struct timing_generator *tg,
 428                 bool enable_blanking)
 429 {
 430         if (enable_blanking)
 431                 dce110_timing_generator_v_blank_crtc(tg);
 432         else
 433                 dce110_timing_generator_v_unblank_crtc(tg);
 434 }
 435 
 436 static void dce110_timing_generator_v_program_timing(struct timing_generator *tg,
 437         const struct dc_crtc_timing *timing,
 438         int vready_offset,
 439         int vstartup_start,
 440         int vupdate_offset,
 441         int vupdate_width,
 442         const enum signal_type signal,
 443         bool use_vbios)
 444 {
 445         if (use_vbios)
 446                 dce110_timing_generator_program_timing_generator(tg, timing);
 447         else
 448                 dce110_timing_generator_v_program_blanking(tg, timing);
 449 }
 450 
 451 static void dce110_timing_generator_v_program_blank_color(
 452                 struct timing_generator *tg,
 453                 const struct tg_color *black_color)
 454 {
 455         uint32_t addr = mmCRTCV_BLACK_COLOR;
 456         uint32_t value = dm_read_reg(tg->ctx, addr);
 457 
 458         set_reg_field_value(
 459                 value,
 460                 black_color->color_b_cb,
 461                 CRTCV_BLACK_COLOR,
 462                 CRTC_BLACK_COLOR_B_CB);
 463         set_reg_field_value(
 464                 value,
 465                 black_color->color_g_y,
 466                 CRTCV_BLACK_COLOR,
 467                 CRTC_BLACK_COLOR_G_Y);
 468         set_reg_field_value(
 469                 value,
 470                 black_color->color_r_cr,
 471                 CRTCV_BLACK_COLOR,
 472                 CRTC_BLACK_COLOR_R_CR);
 473 
 474         dm_write_reg(tg->ctx, addr, value);
 475 }
 476 
 477 static void dce110_timing_generator_v_set_overscan_color_black(
 478         struct timing_generator *tg,
 479         const struct tg_color *color)
 480 {
 481         struct dc_context *ctx = tg->ctx;
 482         uint32_t addr;
 483         uint32_t value = 0;
 484 
 485         set_reg_field_value(
 486                         value,
 487                         color->color_b_cb,
 488                         CRTC_OVERSCAN_COLOR,
 489                         CRTC_OVERSCAN_COLOR_BLUE);
 490 
 491         set_reg_field_value(
 492                         value,
 493                         color->color_r_cr,
 494                         CRTC_OVERSCAN_COLOR,
 495                         CRTC_OVERSCAN_COLOR_RED);
 496 
 497         set_reg_field_value(
 498                         value,
 499                         color->color_g_y,
 500                         CRTC_OVERSCAN_COLOR,
 501                         CRTC_OVERSCAN_COLOR_GREEN);
 502 
 503         addr = mmCRTCV_OVERSCAN_COLOR;
 504         dm_write_reg(ctx, addr, value);
 505         addr = mmCRTCV_BLACK_COLOR;
 506         dm_write_reg(ctx, addr, value);
 507         /* This is desirable to have a constant DAC output voltage during the
 508          * blank time that is higher than the 0 volt reference level that the
 509          * DAC outputs when the NBLANK signal
 510          * is asserted low, such as for output to an analog TV. */
 511         addr = mmCRTCV_BLANK_DATA_COLOR;
 512         dm_write_reg(ctx, addr, value);
 513 
 514         /* TO DO we have to program EXT registers and we need to know LB DATA
 515          * format because it is used when more 10 , i.e. 12 bits per color
 516          *
 517          * m_mmDxCRTC_OVERSCAN_COLOR_EXT
 518          * m_mmDxCRTC_BLACK_COLOR_EXT
 519          * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
 520          */
 521 }
 522 
 523 static void dce110_tg_v_program_blank_color(struct timing_generator *tg,
 524                 const struct tg_color *black_color)
 525 {
 526         uint32_t addr = mmCRTCV_BLACK_COLOR;
 527         uint32_t value = dm_read_reg(tg->ctx, addr);
 528 
 529         set_reg_field_value(
 530                 value,
 531                 black_color->color_b_cb,
 532                 CRTCV_BLACK_COLOR,
 533                 CRTC_BLACK_COLOR_B_CB);
 534         set_reg_field_value(
 535                 value,
 536                 black_color->color_g_y,
 537                 CRTCV_BLACK_COLOR,
 538                 CRTC_BLACK_COLOR_G_Y);
 539         set_reg_field_value(
 540                 value,
 541                 black_color->color_r_cr,
 542                 CRTCV_BLACK_COLOR,
 543                 CRTC_BLACK_COLOR_R_CR);
 544 
 545         dm_write_reg(tg->ctx, addr, value);
 546 
 547         addr = mmCRTCV_BLANK_DATA_COLOR;
 548         dm_write_reg(tg->ctx, addr, value);
 549 }
 550 
 551 static void dce110_timing_generator_v_set_overscan_color(struct timing_generator *tg,
 552         const struct tg_color *overscan_color)
 553 {
 554         struct dc_context *ctx = tg->ctx;
 555         uint32_t value = 0;
 556         uint32_t addr;
 557 
 558         set_reg_field_value(
 559                 value,
 560                 overscan_color->color_b_cb,
 561                 CRTCV_OVERSCAN_COLOR,
 562                 CRTC_OVERSCAN_COLOR_BLUE);
 563 
 564         set_reg_field_value(
 565                 value,
 566                 overscan_color->color_g_y,
 567                 CRTCV_OVERSCAN_COLOR,
 568                 CRTC_OVERSCAN_COLOR_GREEN);
 569 
 570         set_reg_field_value(
 571                 value,
 572                 overscan_color->color_r_cr,
 573                 CRTCV_OVERSCAN_COLOR,
 574                 CRTC_OVERSCAN_COLOR_RED);
 575 
 576         addr = mmCRTCV_OVERSCAN_COLOR;
 577         dm_write_reg(ctx, addr, value);
 578 }
 579 
 580 static void dce110_timing_generator_v_set_colors(struct timing_generator *tg,
 581         const struct tg_color *blank_color,
 582         const struct tg_color *overscan_color)
 583 {
 584         if (blank_color != NULL)
 585                 dce110_tg_v_program_blank_color(tg, blank_color);
 586         if (overscan_color != NULL)
 587                 dce110_timing_generator_v_set_overscan_color(tg, overscan_color);
 588 }
 589 
 590 static void dce110_timing_generator_v_set_early_control(
 591                 struct timing_generator *tg,
 592                 uint32_t early_cntl)
 593 {
 594         uint32_t regval;
 595         uint32_t address = mmCRTC_CONTROL;
 596 
 597         regval = dm_read_reg(tg->ctx, address);
 598         set_reg_field_value(regval, early_cntl,
 599                         CRTCV_CONTROL, CRTC_HBLANK_EARLY_CONTROL);
 600         dm_write_reg(tg->ctx, address, regval);
 601 }
 602 
 603 static uint32_t dce110_timing_generator_v_get_vblank_counter(struct timing_generator *tg)
 604 {
 605         uint32_t addr = mmCRTCV_STATUS_FRAME_COUNT;
 606         uint32_t value = dm_read_reg(tg->ctx, addr);
 607         uint32_t field = get_reg_field_value(
 608                         value, CRTCV_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
 609 
 610         return field;
 611 }
 612 
 613 static bool dce110_timing_generator_v_did_triggered_reset_occur(
 614         struct timing_generator *tg)
 615 {
 616         DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n");
 617         return false;
 618 }
 619 
 620 static void dce110_timing_generator_v_setup_global_swap_lock(
 621         struct timing_generator *tg,
 622         const struct dcp_gsl_params *gsl_params)
 623 {
 624         DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n");
 625         return;
 626 }
 627 
 628 static void dce110_timing_generator_v_enable_reset_trigger(
 629         struct timing_generator *tg,
 630         int source_tg_inst)
 631 {
 632         DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n");
 633         return;
 634 }
 635 
 636 static void dce110_timing_generator_v_disable_reset_trigger(
 637         struct timing_generator *tg)
 638 {
 639         DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n");
 640         return;
 641 }
 642 
 643 static void dce110_timing_generator_v_tear_down_global_swap_lock(
 644         struct timing_generator *tg)
 645 {
 646         DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n");
 647         return;
 648 }
 649 
 650 static void dce110_timing_generator_v_disable_vga(
 651         struct timing_generator *tg)
 652 {
 653         return;
 654 }
 655 
 656 /** ********************************************************************************************
 657  *
 658  * DCE11 Timing Generator Constructor / Destructor
 659  *
 660  *********************************************************************************************/
 661 static const struct timing_generator_funcs dce110_tg_v_funcs = {
 662                 .validate_timing = dce110_tg_validate_timing,
 663                 .program_timing = dce110_timing_generator_v_program_timing,
 664                 .enable_crtc = dce110_timing_generator_v_enable_crtc,
 665                 .disable_crtc = dce110_timing_generator_v_disable_crtc,
 666                 .is_counter_moving = dce110_timing_generator_v_is_counter_moving,
 667                 .get_position = NULL, /* Not to be implemented for underlay*/
 668                 .get_frame_count = dce110_timing_generator_v_get_vblank_counter,
 669                 .set_early_control = dce110_timing_generator_v_set_early_control,
 670                 .wait_for_state = dce110_timing_generator_v_wait_for_state,
 671                 .set_blank = dce110_timing_generator_v_set_blank,
 672                 .set_colors = dce110_timing_generator_v_set_colors,
 673                 .set_overscan_blank_color =
 674                                 dce110_timing_generator_v_set_overscan_color_black,
 675                 .set_blank_color = dce110_timing_generator_v_program_blank_color,
 676                 .disable_vga = dce110_timing_generator_v_disable_vga,
 677                 .did_triggered_reset_occur =
 678                                 dce110_timing_generator_v_did_triggered_reset_occur,
 679                 .setup_global_swap_lock =
 680                                 dce110_timing_generator_v_setup_global_swap_lock,
 681                 .enable_reset_trigger = dce110_timing_generator_v_enable_reset_trigger,
 682                 .disable_reset_trigger = dce110_timing_generator_v_disable_reset_trigger,
 683                 .tear_down_global_swap_lock =
 684                                 dce110_timing_generator_v_tear_down_global_swap_lock,
 685                 .enable_advanced_request =
 686                                 dce110_timing_generator_v_enable_advanced_request
 687 };
 688 
 689 void dce110_timing_generator_v_construct(
 690         struct dce110_timing_generator *tg110,
 691         struct dc_context *ctx)
 692 {
 693         tg110->controller_id = CONTROLLER_ID_UNDERLAY0;
 694 
 695         tg110->base.funcs = &dce110_tg_v_funcs;
 696 
 697         tg110->base.ctx = ctx;
 698         tg110->base.bp = ctx->dc_bios;
 699 
 700         tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
 701         tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
 702 
 703         tg110->min_h_blank = 56;
 704         tg110->min_h_front_porch = 4;
 705         tg110->min_h_back_porch = 4;
 706 }

/* [<][>][^][v][top][bottom][index][help] */