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