cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dce110_timing_generator.c (59168B)


      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}