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 */
 254static void program_horz_count_by_2(
 255        struct timing_generator *tg,
 256        const struct dc_crtc_timing *timing)
 257{
 258        uint32_t regval;
 259        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 260
 261        regval = dm_read_reg(tg->ctx,
 262                        CRTC_REG(mmCRTC_COUNT_CONTROL));
 263
 264        set_reg_field_value(regval, 0, CRTC_COUNT_CONTROL,
 265                        CRTC_HORZ_COUNT_BY2_EN);
 266
 267        if (timing->flags.HORZ_COUNT_BY_TWO)
 268                set_reg_field_value(regval, 1, CRTC_COUNT_CONTROL,
 269                                        CRTC_HORZ_COUNT_BY2_EN);
 270
 271        dm_write_reg(tg->ctx,
 272                        CRTC_REG(mmCRTC_COUNT_CONTROL), regval);
 273}
 274
 275/*
 276 * program_timing_generator
 277 * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition.
 278 * Call ASIC Control Object to program Timings.
 279 */
 280bool dce110_timing_generator_program_timing_generator(
 281        struct timing_generator *tg,
 282        const struct dc_crtc_timing *dc_crtc_timing)
 283{
 284        enum bp_result result;
 285        struct bp_hw_crtc_timing_parameters bp_params;
 286        struct dc_crtc_timing patched_crtc_timing;
 287        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 288
 289        uint32_t vsync_offset = dc_crtc_timing->v_border_bottom +
 290                        dc_crtc_timing->v_front_porch;
 291        uint32_t v_sync_start =dc_crtc_timing->v_addressable + vsync_offset;
 292
 293        uint32_t hsync_offset = dc_crtc_timing->h_border_right +
 294                        dc_crtc_timing->h_front_porch;
 295        uint32_t h_sync_start = dc_crtc_timing->h_addressable + hsync_offset;
 296
 297        memset(&bp_params, 0, sizeof(struct bp_hw_crtc_timing_parameters));
 298
 299        /* Due to an asic bug we need to apply the Front Porch workaround prior
 300         * to programming the timing.
 301         */
 302
 303        patched_crtc_timing = *dc_crtc_timing;
 304
 305        dce110_timing_generator_apply_front_porch_workaround(tg, &patched_crtc_timing);
 306
 307        bp_params.controller_id = tg110->controller_id;
 308
 309        bp_params.h_total = patched_crtc_timing.h_total;
 310        bp_params.h_addressable =
 311                patched_crtc_timing.h_addressable;
 312        bp_params.v_total = patched_crtc_timing.v_total;
 313        bp_params.v_addressable = patched_crtc_timing.v_addressable;
 314
 315        bp_params.h_sync_start = h_sync_start;
 316        bp_params.h_sync_width = patched_crtc_timing.h_sync_width;
 317        bp_params.v_sync_start = v_sync_start;
 318        bp_params.v_sync_width = patched_crtc_timing.v_sync_width;
 319
 320        /* Set overscan */
 321        bp_params.h_overscan_left =
 322                patched_crtc_timing.h_border_left;
 323        bp_params.h_overscan_right =
 324                patched_crtc_timing.h_border_right;
 325        bp_params.v_overscan_top = patched_crtc_timing.v_border_top;
 326        bp_params.v_overscan_bottom =
 327                patched_crtc_timing.v_border_bottom;
 328
 329        /* Set flags */
 330        if (patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY == 1)
 331                bp_params.flags.HSYNC_POSITIVE_POLARITY = 1;
 332
 333        if (patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY == 1)
 334                bp_params.flags.VSYNC_POSITIVE_POLARITY = 1;
 335
 336        if (patched_crtc_timing.flags.INTERLACE == 1)
 337                bp_params.flags.INTERLACE = 1;
 338
 339        if (patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1)
 340                bp_params.flags.HORZ_COUNT_BY_TWO = 1;
 341
 342        result = tg->bp->funcs->program_crtc_timing(tg->bp, &bp_params);
 343
 344        program_horz_count_by_2(tg, &patched_crtc_timing);
 345
 346        tg110->base.funcs->enable_advanced_request(tg, true, &patched_crtc_timing);
 347
 348        /* Enable stereo - only when we need to pack 3D frame. Other types
 349         * of stereo handled in explicit call */
 350
 351        return result == BP_RESULT_OK;
 352}
 353
 354/*
 355 *****************************************************************************
 356 *  Function: set_drr
 357 *
 358 *  @brief
 359 *     Program dynamic refresh rate registers m_DxCRTC_V_TOTAL_*.
 360 *
 361 *  @param [in] pHwCrtcTiming: point to H
 362 *  wCrtcTiming struct
 363 *****************************************************************************
 364 */
 365void dce110_timing_generator_set_drr(
 366        struct timing_generator *tg,
 367        const struct drr_params *params)
 368{
 369        /* register values */
 370        uint32_t v_total_min = 0;
 371        uint32_t v_total_max = 0;
 372        uint32_t v_total_cntl = 0;
 373        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 374
 375        uint32_t addr = 0;
 376
 377        addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
 378        v_total_min = dm_read_reg(tg->ctx, addr);
 379
 380        addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
 381        v_total_max = dm_read_reg(tg->ctx, addr);
 382
 383        addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
 384        v_total_cntl = dm_read_reg(tg->ctx, addr);
 385
 386        if (params != NULL &&
 387                params->vertical_total_max > 0 &&
 388                params->vertical_total_min > 0) {
 389
 390                set_reg_field_value(v_total_max,
 391                                params->vertical_total_max - 1,
 392                                CRTC_V_TOTAL_MAX,
 393                                CRTC_V_TOTAL_MAX);
 394
 395                set_reg_field_value(v_total_min,
 396                                params->vertical_total_min - 1,
 397                                CRTC_V_TOTAL_MIN,
 398                                CRTC_V_TOTAL_MIN);
 399
 400                set_reg_field_value(v_total_cntl,
 401                                1,
 402                                CRTC_V_TOTAL_CONTROL,
 403                                CRTC_V_TOTAL_MIN_SEL);
 404
 405                set_reg_field_value(v_total_cntl,
 406                                1,
 407                                CRTC_V_TOTAL_CONTROL,
 408                                CRTC_V_TOTAL_MAX_SEL);
 409
 410                set_reg_field_value(v_total_cntl,
 411                                0,
 412                                CRTC_V_TOTAL_CONTROL,
 413                                CRTC_FORCE_LOCK_ON_EVENT);
 414                set_reg_field_value(v_total_cntl,
 415                                0,
 416                                CRTC_V_TOTAL_CONTROL,
 417                                CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
 418
 419                set_reg_field_value(v_total_cntl,
 420                                0,
 421                                CRTC_V_TOTAL_CONTROL,
 422                                CRTC_SET_V_TOTAL_MIN_MASK_EN);
 423
 424                set_reg_field_value(v_total_cntl,
 425                                0,
 426                                CRTC_V_TOTAL_CONTROL,
 427                                CRTC_SET_V_TOTAL_MIN_MASK);
 428        } else {
 429                set_reg_field_value(v_total_cntl,
 430                        0,
 431                        CRTC_V_TOTAL_CONTROL,
 432                        CRTC_SET_V_TOTAL_MIN_MASK);
 433                set_reg_field_value(v_total_cntl,
 434                                0,
 435                                CRTC_V_TOTAL_CONTROL,
 436                                CRTC_V_TOTAL_MIN_SEL);
 437                set_reg_field_value(v_total_cntl,
 438                                0,
 439                                CRTC_V_TOTAL_CONTROL,
 440                                CRTC_V_TOTAL_MAX_SEL);
 441                set_reg_field_value(v_total_min,
 442                                0,
 443                                CRTC_V_TOTAL_MIN,
 444                                CRTC_V_TOTAL_MIN);
 445                set_reg_field_value(v_total_max,
 446                                0,
 447                                CRTC_V_TOTAL_MAX,
 448                                CRTC_V_TOTAL_MAX);
 449                set_reg_field_value(v_total_cntl,
 450                                0,
 451                                CRTC_V_TOTAL_CONTROL,
 452                                CRTC_FORCE_LOCK_ON_EVENT);
 453                set_reg_field_value(v_total_cntl,
 454                                0,
 455                                CRTC_V_TOTAL_CONTROL,
 456                                CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
 457        }
 458
 459        addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
 460        dm_write_reg(tg->ctx, addr, v_total_min);
 461
 462        addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
 463        dm_write_reg(tg->ctx, addr, v_total_max);
 464
 465        addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
 466        dm_write_reg(tg->ctx, addr, v_total_cntl);
 467}
 468
 469void dce110_timing_generator_set_static_screen_control(
 470        struct timing_generator *tg,
 471        uint32_t event_triggers,
 472        uint32_t num_frames)
 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        // By register spec, it only takes 8 bit value
 479        if (num_frames > 0xFF)
 480                num_frames = 0xFF;
 481
 482        addr = CRTC_REG(mmCRTC_STATIC_SCREEN_CONTROL);
 483        static_screen_cntl = dm_read_reg(tg->ctx, addr);
 484
 485        set_reg_field_value(static_screen_cntl,
 486                                event_triggers,
 487                                CRTC_STATIC_SCREEN_CONTROL,
 488                                CRTC_STATIC_SCREEN_EVENT_MASK);
 489
 490        set_reg_field_value(static_screen_cntl,
 491                                num_frames,
 492                                CRTC_STATIC_SCREEN_CONTROL,
 493                                CRTC_STATIC_SCREEN_FRAME_COUNT);
 494
 495        dm_write_reg(tg->ctx, addr, static_screen_cntl);
 496}
 497
 498/*
 499 * get_vblank_counter
 500 *
 501 * @brief
 502 * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
 503 * holds the counter of frames.
 504 *
 505 * @param
 506 * struct timing_generator *tg - [in] timing generator which controls the
 507 * desired CRTC
 508 *
 509 * @return
 510 * Counter of frames, which should equal to number of vblanks.
 511 */
 512uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg)
 513{
 514        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 515        uint32_t addr = CRTC_REG(mmCRTC_STATUS_FRAME_COUNT);
 516        uint32_t value = dm_read_reg(tg->ctx, addr);
 517        uint32_t field = get_reg_field_value(
 518                        value, CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
 519
 520        return field;
 521}
 522
 523/*
 524 *****************************************************************************
 525 *  Function: dce110_timing_generator_get_position
 526 *
 527 *  @brief
 528 *     Returns CRTC vertical/horizontal counters
 529 *
 530 *  @param [out] position
 531 *****************************************************************************
 532 */
 533void dce110_timing_generator_get_position(struct timing_generator *tg,
 534        struct crtc_position *position)
 535{
 536        uint32_t value;
 537        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 538
 539        value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_STATUS_POSITION));
 540
 541        position->horizontal_count = get_reg_field_value(
 542                        value,
 543                        CRTC_STATUS_POSITION,
 544                        CRTC_HORZ_COUNT);
 545
 546        position->vertical_count = get_reg_field_value(
 547                        value,
 548                        CRTC_STATUS_POSITION,
 549                        CRTC_VERT_COUNT);
 550
 551        value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_NOM_VERT_POSITION));
 552
 553        position->nominal_vcount = get_reg_field_value(
 554                        value,
 555                        CRTC_NOM_VERT_POSITION,
 556                        CRTC_VERT_COUNT_NOM);
 557}
 558
 559/*
 560 *****************************************************************************
 561 *  Function: get_crtc_scanoutpos
 562 *
 563 *  @brief
 564 *     Returns CRTC vertical/horizontal counters
 565 *
 566 *  @param [out] vpos, hpos
 567 *****************************************************************************
 568 */
 569void dce110_timing_generator_get_crtc_scanoutpos(
 570        struct timing_generator *tg,
 571        uint32_t *v_blank_start,
 572        uint32_t *v_blank_end,
 573        uint32_t *h_position,
 574        uint32_t *v_position)
 575{
 576        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 577        struct crtc_position position;
 578
 579        uint32_t value  = dm_read_reg(tg->ctx,
 580                        CRTC_REG(mmCRTC_V_BLANK_START_END));
 581
 582        *v_blank_start = get_reg_field_value(value,
 583                                             CRTC_V_BLANK_START_END,
 584                                             CRTC_V_BLANK_START);
 585        *v_blank_end = get_reg_field_value(value,
 586                                           CRTC_V_BLANK_START_END,
 587                                           CRTC_V_BLANK_END);
 588
 589        dce110_timing_generator_get_position(
 590                        tg, &position);
 591
 592        *h_position = position.horizontal_count;
 593        *v_position = position.vertical_count;
 594}
 595
 596/* TODO: is it safe to assume that mask/shift of Primary and Underlay
 597 * are the same?
 598 * For example: today CRTC_H_TOTAL == CRTCV_H_TOTAL but is it always
 599 * guaranteed? */
 600void dce110_timing_generator_program_blanking(
 601        struct timing_generator *tg,
 602        const struct dc_crtc_timing *timing)
 603{
 604        uint32_t vsync_offset = timing->v_border_bottom +
 605                        timing->v_front_porch;
 606        uint32_t v_sync_start =timing->v_addressable + vsync_offset;
 607
 608        uint32_t hsync_offset = timing->h_border_right +
 609                        timing->h_front_porch;
 610        uint32_t h_sync_start = timing->h_addressable + hsync_offset;
 611        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 612
 613        struct dc_context *ctx = tg->ctx;
 614        uint32_t value = 0;
 615        uint32_t addr = 0;
 616        uint32_t tmp = 0;
 617
 618        addr = CRTC_REG(mmCRTC_H_TOTAL);
 619        value = dm_read_reg(ctx, addr);
 620        set_reg_field_value(
 621                value,
 622                timing->h_total - 1,
 623                CRTC_H_TOTAL,
 624                CRTC_H_TOTAL);
 625        dm_write_reg(ctx, addr, value);
 626
 627        addr = CRTC_REG(mmCRTC_V_TOTAL);
 628        value = dm_read_reg(ctx, addr);
 629        set_reg_field_value(
 630                value,
 631                timing->v_total - 1,
 632                CRTC_V_TOTAL,
 633                CRTC_V_TOTAL);
 634        dm_write_reg(ctx, addr, value);
 635
 636        /* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and
 637         * V_TOTAL_MIN are equal to V_TOTAL.
 638         */
 639        addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
 640        value = dm_read_reg(ctx, addr);
 641        set_reg_field_value(
 642                value,
 643                timing->v_total - 1,
 644                CRTC_V_TOTAL_MAX,
 645                CRTC_V_TOTAL_MAX);
 646        dm_write_reg(ctx, addr, value);
 647
 648        addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
 649        value = dm_read_reg(ctx, addr);
 650        set_reg_field_value(
 651                value,
 652                timing->v_total - 1,
 653                CRTC_V_TOTAL_MIN,
 654                CRTC_V_TOTAL_MIN);
 655        dm_write_reg(ctx, addr, value);
 656
 657        addr = CRTC_REG(mmCRTC_H_BLANK_START_END);
 658        value = dm_read_reg(ctx, addr);
 659
 660        tmp = timing->h_total -
 661                (h_sync_start + timing->h_border_left);
 662
 663        set_reg_field_value(
 664                value,
 665                tmp,
 666                CRTC_H_BLANK_START_END,
 667                CRTC_H_BLANK_END);
 668
 669        tmp = tmp + timing->h_addressable +
 670                timing->h_border_left + timing->h_border_right;
 671
 672        set_reg_field_value(
 673                value,
 674                tmp,
 675                CRTC_H_BLANK_START_END,
 676                CRTC_H_BLANK_START);
 677
 678        dm_write_reg(ctx, addr, value);
 679
 680        addr = CRTC_REG(mmCRTC_V_BLANK_START_END);
 681        value = dm_read_reg(ctx, addr);
 682
 683        tmp = timing->v_total - (v_sync_start + timing->v_border_top);
 684
 685        set_reg_field_value(
 686                value,
 687                tmp,
 688                CRTC_V_BLANK_START_END,
 689                CRTC_V_BLANK_END);
 690
 691        tmp = tmp + timing->v_addressable + timing->v_border_top +
 692                timing->v_border_bottom;
 693
 694        set_reg_field_value(
 695                value,
 696                tmp,
 697                CRTC_V_BLANK_START_END,
 698                CRTC_V_BLANK_START);
 699
 700        dm_write_reg(ctx, addr, value);
 701}
 702
 703void dce110_timing_generator_set_test_pattern(
 704        struct timing_generator *tg,
 705        /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
 706         * because this is not DP-specific (which is probably somewhere in DP
 707         * encoder) */
 708        enum controller_dp_test_pattern test_pattern,
 709        enum dc_color_depth color_depth)
 710{
 711        struct dc_context *ctx = tg->ctx;
 712        uint32_t value;
 713        uint32_t addr;
 714        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 715        enum test_pattern_color_format bit_depth;
 716        enum test_pattern_dyn_range dyn_range;
 717        enum test_pattern_mode mode;
 718        /* color ramp generator mixes 16-bits color */
 719        uint32_t src_bpc = 16;
 720        /* requested bpc */
 721        uint32_t dst_bpc;
 722        uint32_t index;
 723        /* RGB values of the color bars.
 724         * Produce two RGB colors: RGB0 - white (all Fs)
 725         * and RGB1 - black (all 0s)
 726         * (three RGB components for two colors)
 727         */
 728        uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
 729                                                0x0000, 0x0000};
 730        /* dest color (converted to the specified color format) */
 731        uint16_t dst_color[6];
 732        uint32_t inc_base;
 733
 734        /* translate to bit depth */
 735        switch (color_depth) {
 736        case COLOR_DEPTH_666:
 737                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
 738        break;
 739        case COLOR_DEPTH_888:
 740                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
 741        break;
 742        case COLOR_DEPTH_101010:
 743                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
 744        break;
 745        case COLOR_DEPTH_121212:
 746                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
 747        break;
 748        default:
 749                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
 750        break;
 751        }
 752
 753        switch (test_pattern) {
 754        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
 755        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
 756        {
 757                dyn_range = (test_pattern ==
 758                                CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
 759                                TEST_PATTERN_DYN_RANGE_CEA :
 760                                TEST_PATTERN_DYN_RANGE_VESA);
 761                mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
 762                value = 0;
 763                addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
 764
 765                set_reg_field_value(
 766                        value,
 767                        6,
 768                        CRTC_TEST_PATTERN_PARAMETERS,
 769                        CRTC_TEST_PATTERN_VRES);
 770                set_reg_field_value(
 771                        value,
 772                        6,
 773                        CRTC_TEST_PATTERN_PARAMETERS,
 774                        CRTC_TEST_PATTERN_HRES);
 775
 776                dm_write_reg(ctx, addr, value);
 777
 778                addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
 779                value = 0;
 780
 781                set_reg_field_value(
 782                        value,
 783                        1,
 784                        CRTC_TEST_PATTERN_CONTROL,
 785                        CRTC_TEST_PATTERN_EN);
 786
 787                set_reg_field_value(
 788                        value,
 789                        mode,
 790                        CRTC_TEST_PATTERN_CONTROL,
 791                        CRTC_TEST_PATTERN_MODE);
 792
 793                set_reg_field_value(
 794                        value,
 795                        dyn_range,
 796                        CRTC_TEST_PATTERN_CONTROL,
 797                        CRTC_TEST_PATTERN_DYNAMIC_RANGE);
 798                set_reg_field_value(
 799                        value,
 800                        bit_depth,
 801                        CRTC_TEST_PATTERN_CONTROL,
 802                        CRTC_TEST_PATTERN_COLOR_FORMAT);
 803                dm_write_reg(ctx, addr, value);
 804        }
 805        break;
 806
 807        case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
 808        case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
 809        {
 810                mode = (test_pattern ==
 811                        CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
 812                        TEST_PATTERN_MODE_VERTICALBARS :
 813                        TEST_PATTERN_MODE_HORIZONTALBARS);
 814
 815                switch (bit_depth) {
 816                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 817                        dst_bpc = 6;
 818                break;
 819                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 820                        dst_bpc = 8;
 821                break;
 822                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 823                        dst_bpc = 10;
 824                break;
 825                default:
 826                        dst_bpc = 8;
 827                break;
 828                }
 829
 830                /* adjust color to the required colorFormat */
 831                for (index = 0; index < 6; index++) {
 832                        /* dst = 2^dstBpc * src / 2^srcBpc = src >>
 833                         * (srcBpc - dstBpc);
 834                         */
 835                        dst_color[index] =
 836                                src_color[index] >> (src_bpc - dst_bpc);
 837                /* CRTC_TEST_PATTERN_DATA has 16 bits,
 838                 * lowest 6 are hardwired to ZERO
 839                 * color bits should be left aligned aligned to MSB
 840                 * XXXXXXXXXX000000 for 10 bit,
 841                 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
 842                 */
 843                        dst_color[index] <<= (16 - dst_bpc);
 844                }
 845
 846                value = 0;
 847                addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
 848                dm_write_reg(ctx, addr, value);
 849
 850                /* We have to write the mask before data, similar to pipeline.
 851                 * For example, for 8 bpc, if we want RGB0 to be magenta,
 852                 * and RGB1 to be cyan,
 853                 * we need to make 7 writes:
 854                 * MASK   DATA
 855                 * 000001 00000000 00000000                     set mask to R0
 856                 * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
 857                 * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
 858                 * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
 859                 * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
 860                 * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
 861                 * 100000 11111111 00000000     B1 255, 0xFF00
 862                 *
 863                 * we will make a loop of 6 in which we prepare the mask,
 864                 * then write, then prepare the color for next write.
 865                 * first iteration will write mask only,
 866                 * but each next iteration color prepared in
 867                 * previous iteration will be written within new mask,
 868                 * the last component will written separately,
 869                 * mask is not changing between 6th and 7th write
 870                 * and color will be prepared by last iteration
 871                 */
 872
 873                /* write color, color values mask in CRTC_TEST_PATTERN_MASK
 874                 * is B1, G1, R1, B0, G0, R0
 875                 */
 876                value = 0;
 877                addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
 878                for (index = 0; index < 6; index++) {
 879                        /* prepare color mask, first write PATTERN_DATA
 880                         * will have all zeros
 881                         */
 882                        set_reg_field_value(
 883                                value,
 884                                (1 << index),
 885                                CRTC_TEST_PATTERN_COLOR,
 886                                CRTC_TEST_PATTERN_MASK);
 887                        /* write color component */
 888                        dm_write_reg(ctx, addr, value);
 889                        /* prepare next color component,
 890                         * will be written in the next iteration
 891                         */
 892                        set_reg_field_value(
 893                                value,
 894                                dst_color[index],
 895                                CRTC_TEST_PATTERN_COLOR,
 896                                CRTC_TEST_PATTERN_DATA);
 897                }
 898                /* write last color component,
 899                 * it's been already prepared in the loop
 900                 */
 901                dm_write_reg(ctx, addr, value);
 902
 903                /* enable test pattern */
 904                addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
 905                value = 0;
 906
 907                set_reg_field_value(
 908                        value,
 909                        1,
 910                        CRTC_TEST_PATTERN_CONTROL,
 911                        CRTC_TEST_PATTERN_EN);
 912
 913                set_reg_field_value(
 914                        value,
 915                        mode,
 916                        CRTC_TEST_PATTERN_CONTROL,
 917                        CRTC_TEST_PATTERN_MODE);
 918
 919                set_reg_field_value(
 920                        value,
 921                        0,
 922                        CRTC_TEST_PATTERN_CONTROL,
 923                        CRTC_TEST_PATTERN_DYNAMIC_RANGE);
 924
 925                set_reg_field_value(
 926                        value,
 927                        bit_depth,
 928                        CRTC_TEST_PATTERN_CONTROL,
 929                        CRTC_TEST_PATTERN_COLOR_FORMAT);
 930
 931                dm_write_reg(ctx, addr, value);
 932        }
 933        break;
 934
 935        case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
 936        {
 937                mode = (bit_depth ==
 938                        TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
 939                        TEST_PATTERN_MODE_DUALRAMP_RGB :
 940                        TEST_PATTERN_MODE_SINGLERAMP_RGB);
 941
 942                switch (bit_depth) {
 943                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 944                        dst_bpc = 6;
 945                break;
 946                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 947                        dst_bpc = 8;
 948                break;
 949                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 950                        dst_bpc = 10;
 951                break;
 952                default:
 953                        dst_bpc = 8;
 954                break;
 955                }
 956
 957                /* increment for the first ramp for one color gradation
 958                 * 1 gradation for 6-bit color is 2^10
 959                 * gradations in 16-bit color
 960                 */
 961                inc_base = (src_bpc - dst_bpc);
 962
 963                value = 0;
 964                addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
 965
 966                switch (bit_depth) {
 967                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 968                {
 969                        set_reg_field_value(
 970                                value,
 971                                inc_base,
 972                                CRTC_TEST_PATTERN_PARAMETERS,
 973                                CRTC_TEST_PATTERN_INC0);
 974                        set_reg_field_value(
 975                                value,
 976                                0,
 977                                CRTC_TEST_PATTERN_PARAMETERS,
 978                                CRTC_TEST_PATTERN_INC1);
 979                        set_reg_field_value(
 980                                value,
 981                                6,
 982                                CRTC_TEST_PATTERN_PARAMETERS,
 983                                CRTC_TEST_PATTERN_HRES);
 984                        set_reg_field_value(
 985                                value,
 986                                6,
 987                                CRTC_TEST_PATTERN_PARAMETERS,
 988                                CRTC_TEST_PATTERN_VRES);
 989                        set_reg_field_value(
 990                                value,
 991                                0,
 992                                CRTC_TEST_PATTERN_PARAMETERS,
 993                                CRTC_TEST_PATTERN_RAMP0_OFFSET);
 994                }
 995                break;
 996                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 997                {
 998                        set_reg_field_value(
 999                                value,
1000                                inc_base,
1001                                CRTC_TEST_PATTERN_PARAMETERS,
1002                                CRTC_TEST_PATTERN_INC0);
1003                        set_reg_field_value(
1004                                value,
1005                                0,
1006                                CRTC_TEST_PATTERN_PARAMETERS,
1007                                CRTC_TEST_PATTERN_INC1);
1008                        set_reg_field_value(
1009                                value,
1010                                8,
1011                                CRTC_TEST_PATTERN_PARAMETERS,
1012                                CRTC_TEST_PATTERN_HRES);
1013                        set_reg_field_value(
1014                                value,
1015                                6,
1016                                CRTC_TEST_PATTERN_PARAMETERS,
1017                                CRTC_TEST_PATTERN_VRES);
1018                        set_reg_field_value(
1019                                value,
1020                                0,
1021                                CRTC_TEST_PATTERN_PARAMETERS,
1022                                CRTC_TEST_PATTERN_RAMP0_OFFSET);
1023                }
1024                break;
1025                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1026                {
1027                        set_reg_field_value(
1028                                value,
1029                                inc_base,
1030                                CRTC_TEST_PATTERN_PARAMETERS,
1031                                CRTC_TEST_PATTERN_INC0);
1032                        set_reg_field_value(
1033                                value,
1034                                inc_base + 2,
1035                                CRTC_TEST_PATTERN_PARAMETERS,
1036                                CRTC_TEST_PATTERN_INC1);
1037                        set_reg_field_value(
1038                                value,
1039                                8,
1040                                CRTC_TEST_PATTERN_PARAMETERS,
1041                                CRTC_TEST_PATTERN_HRES);
1042                        set_reg_field_value(
1043                                value,
1044                                5,
1045                                CRTC_TEST_PATTERN_PARAMETERS,
1046                                CRTC_TEST_PATTERN_VRES);
1047                        set_reg_field_value(
1048                                value,
1049                                384 << 6,
1050                                CRTC_TEST_PATTERN_PARAMETERS,
1051                                CRTC_TEST_PATTERN_RAMP0_OFFSET);
1052                }
1053                break;
1054                default:
1055                break;
1056                }
1057                dm_write_reg(ctx, addr, value);
1058
1059                value = 0;
1060                addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
1061                dm_write_reg(ctx, addr, value);
1062
1063                /* enable test pattern */
1064                addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
1065                value = 0;
1066
1067                set_reg_field_value(
1068                        value,
1069                        1,
1070                        CRTC_TEST_PATTERN_CONTROL,
1071                        CRTC_TEST_PATTERN_EN);
1072
1073                set_reg_field_value(
1074                        value,
1075                        mode,
1076                        CRTC_TEST_PATTERN_CONTROL,
1077                        CRTC_TEST_PATTERN_MODE);
1078
1079                set_reg_field_value(
1080                        value,
1081                        0,
1082                        CRTC_TEST_PATTERN_CONTROL,
1083                        CRTC_TEST_PATTERN_DYNAMIC_RANGE);
1084                /* add color depth translation here */
1085                set_reg_field_value(
1086                        value,
1087                        bit_depth,
1088                        CRTC_TEST_PATTERN_CONTROL,
1089                        CRTC_TEST_PATTERN_COLOR_FORMAT);
1090
1091                dm_write_reg(ctx, addr, value);
1092        }
1093        break;
1094        case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1095        {
1096                value = 0;
1097                dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL), value);
1098                dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_COLOR), value);
1099                dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS),
1100                                value);
1101        }
1102        break;
1103        default:
1104        break;
1105        }
1106}
1107
1108/*
1109 * dce110_timing_generator_validate_timing
1110 * The timing generators support a maximum display size of is 8192 x 8192 pixels,
1111 * including both active display and blanking periods. Check H Total and V Total.
1112 */
1113bool dce110_timing_generator_validate_timing(
1114        struct timing_generator *tg,
1115        const struct dc_crtc_timing *timing,
1116        enum signal_type signal)
1117{
1118        uint32_t h_blank;
1119        uint32_t h_back_porch, hsync_offset, h_sync_start;
1120
1121        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1122
1123        ASSERT(timing != NULL);
1124
1125        if (!timing)
1126                return false;
1127
1128        hsync_offset = timing->h_border_right + timing->h_front_porch;
1129        h_sync_start = timing->h_addressable + hsync_offset;
1130
1131        /* Currently we don't support 3D, so block all 3D timings */
1132        if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE)
1133                return false;
1134
1135        /* Temporarily blocking interlacing mode until it's supported */
1136        if (timing->flags.INTERLACE == 1)
1137                return false;
1138
1139        /* Check maximum number of pixels supported by Timing Generator
1140         * (Currently will never fail, in order to fail needs display which
1141         * needs more than 8192 horizontal and
1142         * more than 8192 vertical total pixels)
1143         */
1144        if (timing->h_total > tg110->max_h_total ||
1145                timing->v_total > tg110->max_v_total)
1146                return false;
1147
1148        h_blank = (timing->h_total - timing->h_addressable -
1149                timing->h_border_right -
1150                timing->h_border_left);
1151
1152        if (h_blank < tg110->min_h_blank)
1153                return false;
1154
1155        if (timing->h_front_porch < tg110->min_h_front_porch)
1156                return false;
1157
1158        h_back_porch = h_blank - (h_sync_start -
1159                timing->h_addressable -
1160                timing->h_border_right -
1161                timing->h_sync_width);
1162
1163        if (h_back_porch < tg110->min_h_back_porch)
1164                return false;
1165
1166        return true;
1167}
1168
1169/*
1170 * Wait till we are at the beginning of VBlank.
1171 */
1172void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg)
1173{
1174        /* We want to catch beginning of VBlank here, so if the first try are
1175         * in VBlank, we might be very close to Active, in this case wait for
1176         * another frame
1177         */
1178        while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1179                if (!dce110_timing_generator_is_counter_moving(tg)) {
1180                        /* error - no point to wait if counter is not moving */
1181                        break;
1182                }
1183        }
1184
1185        while (!dce110_timing_generator_is_in_vertical_blank(tg)) {
1186                if (!dce110_timing_generator_is_counter_moving(tg)) {
1187                        /* error - no point to wait if counter is not moving */
1188                        break;
1189                }
1190        }
1191}
1192
1193/*
1194 * Wait till we are in VActive (anywhere in VActive)
1195 */
1196void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg)
1197{
1198        while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1199                if (!dce110_timing_generator_is_counter_moving(tg)) {
1200                        /* error - no point to wait if counter is not moving */
1201                        break;
1202                }
1203        }
1204}
1205
1206/*
1207 *****************************************************************************
1208 *  Function: dce110_timing_generator_setup_global_swap_lock
1209 *
1210 *  @brief
1211 *     Setups Global Swap Lock group for current pipe
1212 *     Pipe can join or leave GSL group, become a TimingServer or TimingClient
1213 *
1214 *  @param [in] gsl_params: setup data
1215 *****************************************************************************
1216 */
1217void dce110_timing_generator_setup_global_swap_lock(
1218        struct timing_generator *tg,
1219        const struct dcp_gsl_params *gsl_params)
1220{
1221        uint32_t value;
1222        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1223        uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1224        uint32_t check_point = FLIP_READY_BACK_LOOKUP;
1225
1226        value = dm_read_reg(tg->ctx, address);
1227
1228        /* This pipe will belong to GSL Group zero. */
1229        set_reg_field_value(value,
1230                            1,
1231                            DCP_GSL_CONTROL,
1232                            DCP_GSL0_EN);
1233
1234        set_reg_field_value(value,
1235                            gsl_params->gsl_master == tg->inst,
1236                            DCP_GSL_CONTROL,
1237                            DCP_GSL_MASTER_EN);
1238
1239        set_reg_field_value(value,
1240                            HFLIP_READY_DELAY,
1241                            DCP_GSL_CONTROL,
1242                            DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1243
1244        /* Keep signal low (pending high) during 6 lines.
1245         * Also defines minimum interval before re-checking signal. */
1246        set_reg_field_value(value,
1247                            HFLIP_CHECK_DELAY,
1248                            DCP_GSL_CONTROL,
1249                            DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1250
1251        dm_write_reg(tg->ctx, CRTC_REG(mmDCP_GSL_CONTROL), value);
1252        value = 0;
1253
1254        set_reg_field_value(value,
1255                            gsl_params->gsl_master,
1256                            DCIO_GSL0_CNTL,
1257                            DCIO_GSL0_VSYNC_SEL);
1258
1259        set_reg_field_value(value,
1260                            0,
1261                            DCIO_GSL0_CNTL,
1262                            DCIO_GSL0_TIMING_SYNC_SEL);
1263
1264        set_reg_field_value(value,
1265                            0,
1266                            DCIO_GSL0_CNTL,
1267                            DCIO_GSL0_GLOBAL_UNLOCK_SEL);
1268
1269        dm_write_reg(tg->ctx, CRTC_REG(mmDCIO_GSL0_CNTL), value);
1270
1271
1272        {
1273                uint32_t value_crtc_vtotal;
1274
1275                value_crtc_vtotal = dm_read_reg(tg->ctx,
1276                                CRTC_REG(mmCRTC_V_TOTAL));
1277
1278                set_reg_field_value(value,
1279                                    0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
1280                                    DCP_GSL_CONTROL,
1281                                    DCP_GSL_SYNC_SOURCE);
1282
1283                /* Checkpoint relative to end of frame */
1284                check_point = get_reg_field_value(value_crtc_vtotal,
1285                                                  CRTC_V_TOTAL,
1286                                                  CRTC_V_TOTAL);
1287
1288                dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
1289        }
1290
1291        set_reg_field_value(value,
1292                            1,
1293                            DCP_GSL_CONTROL,
1294                            DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1295
1296        dm_write_reg(tg->ctx, address, value);
1297
1298        /********************************************************************/
1299        address = CRTC_REG(mmCRTC_GSL_CONTROL);
1300
1301        value = dm_read_reg(tg->ctx, address);
1302        set_reg_field_value(value,
1303                            check_point - FLIP_READY_BACK_LOOKUP,
1304                            CRTC_GSL_CONTROL,
1305                            CRTC_GSL_CHECK_LINE_NUM);
1306
1307        set_reg_field_value(value,
1308                            VFLIP_READY_DELAY,
1309                            CRTC_GSL_CONTROL,
1310                            CRTC_GSL_FORCE_DELAY);
1311
1312        dm_write_reg(tg->ctx, address, value);
1313}
1314
1315void dce110_timing_generator_tear_down_global_swap_lock(
1316        struct timing_generator *tg)
1317{
1318        /* Clear all the register writes done by
1319         * dce110_timing_generator_setup_global_swap_lock
1320         */
1321
1322        uint32_t value;
1323        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1324        uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1325
1326        value = 0;
1327
1328        /* This pipe will belong to GSL Group zero. */
1329        /* Settig HW default values from reg specs */
1330        set_reg_field_value(value,
1331                        0,
1332                        DCP_GSL_CONTROL,
1333                        DCP_GSL0_EN);
1334
1335        set_reg_field_value(value,
1336                        0,
1337                        DCP_GSL_CONTROL,
1338                        DCP_GSL_MASTER_EN);
1339
1340        set_reg_field_value(value,
1341                        0x2,
1342                        DCP_GSL_CONTROL,
1343                        DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1344
1345        set_reg_field_value(value,
1346                        0x6,
1347                        DCP_GSL_CONTROL,
1348                        DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1349
1350        /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */
1351        {
1352                dm_read_reg(tg->ctx, 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 */
1845void dce110_timing_generator_set_overscan_color_black(
1846        struct timing_generator *tg,
1847        const struct tg_color *color)
1848{
1849        struct dc_context *ctx = tg->ctx;
1850        uint32_t addr;
1851        uint32_t value = 0;
1852        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1853
1854        set_reg_field_value(
1855                        value,
1856                        color->color_b_cb,
1857                        CRTC_OVERSCAN_COLOR,
1858                        CRTC_OVERSCAN_COLOR_BLUE);
1859
1860        set_reg_field_value(
1861                        value,
1862                        color->color_r_cr,
1863                        CRTC_OVERSCAN_COLOR,
1864                        CRTC_OVERSCAN_COLOR_RED);
1865
1866        set_reg_field_value(
1867                        value,
1868                        color->color_g_y,
1869                        CRTC_OVERSCAN_COLOR,
1870                        CRTC_OVERSCAN_COLOR_GREEN);
1871
1872        addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1873        dm_write_reg(ctx, addr, value);
1874        addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1875        dm_write_reg(ctx, addr, value);
1876        /* This is desirable to have a constant DAC output voltage during the
1877         * blank time that is higher than the 0 volt reference level that the
1878         * DAC outputs when the NBLANK signal
1879         * is asserted low, such as for output to an analog TV. */
1880        addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1881        dm_write_reg(ctx, addr, value);
1882
1883        /* TO DO we have to program EXT registers and we need to know LB DATA
1884         * format because it is used when more 10 , i.e. 12 bits per color
1885         *
1886         * m_mmDxCRTC_OVERSCAN_COLOR_EXT
1887         * m_mmDxCRTC_BLACK_COLOR_EXT
1888         * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
1889         */
1890
1891}
1892
1893void dce110_tg_program_blank_color(struct timing_generator *tg,
1894                const struct tg_color *black_color)
1895{
1896        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1897        uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1898        uint32_t value = dm_read_reg(tg->ctx, addr);
1899
1900        set_reg_field_value(
1901                value,
1902                black_color->color_b_cb,
1903                CRTC_BLACK_COLOR,
1904                CRTC_BLACK_COLOR_B_CB);
1905        set_reg_field_value(
1906                value,
1907                black_color->color_g_y,
1908                CRTC_BLACK_COLOR,
1909                CRTC_BLACK_COLOR_G_Y);
1910        set_reg_field_value(
1911                value,
1912                black_color->color_r_cr,
1913                CRTC_BLACK_COLOR,
1914                CRTC_BLACK_COLOR_R_CR);
1915
1916        dm_write_reg(tg->ctx, addr, value);
1917
1918        addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1919        dm_write_reg(tg->ctx, addr, value);
1920}
1921
1922void dce110_tg_set_overscan_color(struct timing_generator *tg,
1923        const struct tg_color *overscan_color)
1924{
1925        struct dc_context *ctx = tg->ctx;
1926        uint32_t value = 0;
1927        uint32_t addr;
1928        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1929
1930        set_reg_field_value(
1931                value,
1932                overscan_color->color_b_cb,
1933                CRTC_OVERSCAN_COLOR,
1934                CRTC_OVERSCAN_COLOR_BLUE);
1935
1936        set_reg_field_value(
1937                value,
1938                overscan_color->color_g_y,
1939                CRTC_OVERSCAN_COLOR,
1940                CRTC_OVERSCAN_COLOR_GREEN);
1941
1942        set_reg_field_value(
1943                value,
1944                overscan_color->color_r_cr,
1945                CRTC_OVERSCAN_COLOR,
1946                CRTC_OVERSCAN_COLOR_RED);
1947
1948        addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1949        dm_write_reg(ctx, addr, value);
1950}
1951
1952void dce110_tg_program_timing(struct timing_generator *tg,
1953        const struct dc_crtc_timing *timing,
1954        int vready_offset,
1955        int vstartup_start,
1956        int vupdate_offset,
1957        int vupdate_width,
1958        const enum signal_type signal,
1959        bool use_vbios)
1960{
1961        if (use_vbios)
1962                dce110_timing_generator_program_timing_generator(tg, timing);
1963        else
1964                dce110_timing_generator_program_blanking(tg, timing);
1965}
1966
1967bool dce110_tg_is_blanked(struct timing_generator *tg)
1968{
1969        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1970        uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL));
1971
1972        if (get_reg_field_value(
1973                        value,
1974                        CRTC_BLANK_CONTROL,
1975                        CRTC_BLANK_DATA_EN) == 1 &&
1976                get_reg_field_value(
1977                        value,
1978                        CRTC_BLANK_CONTROL,
1979                        CRTC_CURRENT_BLANK_STATE) == 1)
1980                return true;
1981        return false;
1982}
1983
1984void dce110_tg_set_blank(struct timing_generator *tg,
1985                bool enable_blanking)
1986{
1987        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1988        uint32_t value = 0;
1989
1990        set_reg_field_value(
1991                value,
1992                1,
1993                CRTC_DOUBLE_BUFFER_CONTROL,
1994                CRTC_BLANK_DATA_DOUBLE_BUFFER_EN);
1995
1996        dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value);
1997        value = 0;
1998
1999        if (enable_blanking) {
2000                set_reg_field_value(
2001                        value,
2002                        1,
2003                        CRTC_BLANK_CONTROL,
2004                        CRTC_BLANK_DATA_EN);
2005
2006                dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value);
2007
2008        } else
2009                dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0);
2010}
2011
2012bool dce110_tg_validate_timing(struct timing_generator *tg,
2013        const struct dc_crtc_timing *timing)
2014{
2015        return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
2016}
2017
2018void dce110_tg_wait_for_state(struct timing_generator *tg,
2019        enum crtc_state state)
2020{
2021        switch (state) {
2022        case CRTC_STATE_VBLANK:
2023                dce110_timing_generator_wait_for_vblank(tg);
2024                break;
2025
2026        case CRTC_STATE_VACTIVE:
2027                dce110_timing_generator_wait_for_vactive(tg);
2028                break;
2029
2030        default:
2031                break;
2032        }
2033}
2034
2035void dce110_tg_set_colors(struct timing_generator *tg,
2036        const struct tg_color *blank_color,
2037        const struct tg_color *overscan_color)
2038{
2039        if (blank_color != NULL)
2040                dce110_tg_program_blank_color(tg, blank_color);
2041        if (overscan_color != NULL)
2042                dce110_tg_set_overscan_color(tg, overscan_color);
2043}
2044
2045/* Gets first line of blank region of the display timing for CRTC
2046 * and programms is as a trigger to fire vertical interrupt
2047 */
2048bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
2049{
2050        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2051        uint32_t v_blank_start = 0;
2052        uint32_t v_blank_end = 0;
2053        uint32_t val = 0;
2054        uint32_t h_position, v_position;
2055
2056        tg->funcs->get_scanoutpos(
2057                        tg,
2058                        &v_blank_start,
2059                        &v_blank_end,
2060                        &h_position,
2061                        &v_position);
2062
2063        if (v_blank_start == 0 || v_blank_end == 0)
2064                return false;
2065
2066        set_reg_field_value(
2067                val,
2068                v_blank_start,
2069                CRTC_VERTICAL_INTERRUPT0_POSITION,
2070                CRTC_VERTICAL_INTERRUPT0_LINE_START);
2071
2072        /* Set interval width for interrupt to fire to 1 scanline */
2073        set_reg_field_value(
2074                val,
2075                v_blank_start + width,
2076                CRTC_VERTICAL_INTERRUPT0_POSITION,
2077                CRTC_VERTICAL_INTERRUPT0_LINE_END);
2078
2079        dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
2080
2081        return true;
2082}
2083
2084static bool dce110_is_tg_enabled(struct timing_generator *tg)
2085{
2086        uint32_t addr = 0;
2087        uint32_t value = 0;
2088        uint32_t field = 0;
2089        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2090
2091        addr = CRTC_REG(mmCRTC_CONTROL);
2092        value = dm_read_reg(tg->ctx, addr);
2093        field = get_reg_field_value(value, CRTC_CONTROL,
2094                                    CRTC_CURRENT_MASTER_EN_STATE);
2095        return field == 1;
2096}
2097
2098bool dce110_configure_crc(struct timing_generator *tg,
2099                          const struct crc_params *params)
2100{
2101        uint32_t cntl_addr = 0;
2102        uint32_t addr = 0;
2103        uint32_t value;
2104        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2105
2106        /* Cannot configure crc on a CRTC that is disabled */
2107        if (!dce110_is_tg_enabled(tg))
2108                return false;
2109
2110        cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
2111
2112        /* First, disable CRC before we configure it. */
2113        dm_write_reg(tg->ctx, cntl_addr, 0);
2114
2115        if (!params->enable)
2116                return true;
2117
2118        /* Program frame boundaries */
2119        /* Window A x axis start and end. */
2120        value = 0;
2121        addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
2122        set_reg_field_value(value, params->windowa_x_start,
2123                            CRTC_CRC0_WINDOWA_X_CONTROL,
2124                            CRTC_CRC0_WINDOWA_X_START);
2125        set_reg_field_value(value, params->windowa_x_end,
2126                            CRTC_CRC0_WINDOWA_X_CONTROL,
2127                            CRTC_CRC0_WINDOWA_X_END);
2128        dm_write_reg(tg->ctx, addr, value);
2129
2130        /* Window A y axis start and end. */
2131        value = 0;
2132        addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL);
2133        set_reg_field_value(value, params->windowa_y_start,
2134                            CRTC_CRC0_WINDOWA_Y_CONTROL,
2135                            CRTC_CRC0_WINDOWA_Y_START);
2136        set_reg_field_value(value, params->windowa_y_end,
2137                            CRTC_CRC0_WINDOWA_Y_CONTROL,
2138                            CRTC_CRC0_WINDOWA_Y_END);
2139        dm_write_reg(tg->ctx, addr, value);
2140
2141        /* Window B x axis start and end. */
2142        value = 0;
2143        addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL);
2144        set_reg_field_value(value, params->windowb_x_start,
2145                            CRTC_CRC0_WINDOWB_X_CONTROL,
2146                            CRTC_CRC0_WINDOWB_X_START);
2147        set_reg_field_value(value, params->windowb_x_end,
2148                            CRTC_CRC0_WINDOWB_X_CONTROL,
2149                            CRTC_CRC0_WINDOWB_X_END);
2150        dm_write_reg(tg->ctx, addr, value);
2151
2152        /* Window B y axis start and end. */
2153        value = 0;
2154        addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL);
2155        set_reg_field_value(value, params->windowb_y_start,
2156                            CRTC_CRC0_WINDOWB_Y_CONTROL,
2157                            CRTC_CRC0_WINDOWB_Y_START);
2158        set_reg_field_value(value, params->windowb_y_end,
2159                            CRTC_CRC0_WINDOWB_Y_CONTROL,
2160                            CRTC_CRC0_WINDOWB_Y_END);
2161        dm_write_reg(tg->ctx, addr, value);
2162
2163        /* Set crc mode and selection, and enable. Only using CRC0*/
2164        value = 0;
2165        set_reg_field_value(value, params->continuous_mode ? 1 : 0,
2166                            CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
2167        set_reg_field_value(value, params->selection,
2168                            CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
2169        set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
2170        dm_write_reg(tg->ctx, cntl_addr, value);
2171
2172        return true;
2173}
2174
2175bool dce110_get_crc(struct timing_generator *tg,
2176                    uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
2177{
2178        uint32_t addr = 0;
2179        uint32_t value = 0;
2180        uint32_t field = 0;
2181        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2182
2183        addr = CRTC_REG(mmCRTC_CRC_CNTL);
2184        value = dm_read_reg(tg->ctx, addr);
2185        field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN);
2186
2187        /* Early return if CRC is not enabled for this CRTC */
2188        if (!field)
2189                return false;
2190
2191        addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
2192        value = dm_read_reg(tg->ctx, addr);
2193        *r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
2194        *g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
2195
2196        addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
2197        value = dm_read_reg(tg->ctx, addr);
2198        *b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
2199
2200        return true;
2201}
2202
2203static const struct timing_generator_funcs dce110_tg_funcs = {
2204                .validate_timing = dce110_tg_validate_timing,
2205                .program_timing = dce110_tg_program_timing,
2206                .enable_crtc = dce110_timing_generator_enable_crtc,
2207                .disable_crtc = dce110_timing_generator_disable_crtc,
2208                .is_counter_moving = dce110_timing_generator_is_counter_moving,
2209                .get_position = dce110_timing_generator_get_position,
2210                .get_frame_count = dce110_timing_generator_get_vblank_counter,
2211                .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
2212                .set_early_control = dce110_timing_generator_set_early_control,
2213                .wait_for_state = dce110_tg_wait_for_state,
2214                .set_blank = dce110_tg_set_blank,
2215                .is_blanked = dce110_tg_is_blanked,
2216                .set_colors = dce110_tg_set_colors,
2217                .set_overscan_blank_color =
2218                                dce110_timing_generator_set_overscan_color_black,
2219                .set_blank_color = dce110_timing_generator_program_blank_color,
2220                .disable_vga = dce110_timing_generator_disable_vga,
2221                .did_triggered_reset_occur =
2222                                dce110_timing_generator_did_triggered_reset_occur,
2223                .setup_global_swap_lock =
2224                                dce110_timing_generator_setup_global_swap_lock,
2225                .enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
2226                .enable_crtc_reset = dce110_timing_generator_enable_crtc_reset,
2227                .disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
2228                .tear_down_global_swap_lock =
2229                                dce110_timing_generator_tear_down_global_swap_lock,
2230                .enable_advanced_request =
2231                                dce110_timing_generator_enable_advanced_request,
2232                .set_drr =
2233                                dce110_timing_generator_set_drr,
2234                .get_last_used_drr_vtotal = NULL,
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