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