File Index
Files and directories
Sign in
FILE

dce110_timing_generator.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c C
   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	int pstate_keepout,
1959	const enum signal_type signal,
1960	bool use_vbios)
1961{
1962	if (use_vbios)
1963		dce110_timing_generator_program_timing_generator(tg, timing);
1964	else
1965		dce110_timing_generator_program_blanking(tg, timing);
1966}
1967
1968bool dce110_tg_is_blanked(struct timing_generator *tg)
1969{
1970	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1971	uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL));
1972
1973	if (get_reg_field_value(
1974			value,
1975			CRTC_BLANK_CONTROL,
1976			CRTC_BLANK_DATA_EN) == 1 &&
1977		get_reg_field_value(
1978			value,
1979			CRTC_BLANK_CONTROL,
1980			CRTC_CURRENT_BLANK_STATE) == 1)
1981		return true;
1982	return false;
1983}
1984
1985void dce110_tg_set_blank(struct timing_generator *tg,
1986		bool enable_blanking)
1987{
1988	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1989	uint32_t value = 0;
1990
1991	set_reg_field_value(
1992		value,
1993		1,
1994		CRTC_DOUBLE_BUFFER_CONTROL,
1995		CRTC_BLANK_DATA_DOUBLE_BUFFER_EN);
1996
1997	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value);
1998	value = 0;
1999
2000	if (enable_blanking) {
2001		set_reg_field_value(
2002			value,
2003			1,
2004			CRTC_BLANK_CONTROL,
2005			CRTC_BLANK_DATA_EN);
2006
2007		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value);
2008
2009	} else
2010		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0);
2011}
2012
2013bool dce110_tg_validate_timing(struct timing_generator *tg,
2014	const struct dc_crtc_timing *timing)
2015{
2016	return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
2017}
2018
2019/* "Container" vs. "pixel" is a concept within HW blocks, mostly those closer to the back-end. It works like this:
2020 *
2021 * - In most of the formats (RGB or YCbCr 4:4:4, 4:2:2 uncompressed and DSC 4:2:2 Simple) pixel rate is the same as
2022 *   container rate.
2023 *
2024 * - In 4:2:0 (DSC or uncompressed) there are two pixels per container, hence the target container rate has to be
2025 *   halved to maintain the correct pixel rate.
2026 *
2027 * - Unlike 4:2:2 uncompressed, DSC 4:2:2 Native also has two pixels per container (this happens when DSC is applied
2028 *   to it) and has to be treated the same as 4:2:0, i.e. target containter rate has to be halved in this case as well.
2029 *
2030 */
2031bool dce110_is_two_pixels_per_container(const struct dc_crtc_timing *timing)
2032{
2033	return timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
2034}
2035
2036void dce110_tg_wait_for_state(struct timing_generator *tg,
2037	enum crtc_state state)
2038{
2039	switch (state) {
2040	case CRTC_STATE_VBLANK:
2041		dce110_timing_generator_wait_for_vblank(tg);
2042		break;
2043
2044	case CRTC_STATE_VACTIVE:
2045		dce110_timing_generator_wait_for_vactive(tg);
2046		break;
2047
2048	default:
2049		break;
2050	}
2051}
2052
2053void dce110_tg_set_colors(struct timing_generator *tg,
2054	const struct tg_color *blank_color,
2055	const struct tg_color *overscan_color)
2056{
2057	if (blank_color != NULL)
2058		dce110_tg_program_blank_color(tg, blank_color);
2059	if (overscan_color != NULL)
2060		dce110_tg_set_overscan_color(tg, overscan_color);
2061}
2062
2063/* Gets first line of blank region of the display timing for CRTC
2064 * and programms is as a trigger to fire vertical interrupt
2065 */
2066bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
2067{
2068	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2069	uint32_t v_blank_start = 0;
2070	uint32_t v_blank_end = 0;
2071	uint32_t val = 0;
2072	uint32_t h_position, v_position;
2073
2074	tg->funcs->get_scanoutpos(
2075			tg,
2076			&v_blank_start,
2077			&v_blank_end,
2078			&h_position,
2079			&v_position);
2080
2081	if (v_blank_start == 0 || v_blank_end == 0)
2082		return false;
2083
2084	set_reg_field_value(
2085		val,
2086		v_blank_start,
2087		CRTC_VERTICAL_INTERRUPT0_POSITION,
2088		CRTC_VERTICAL_INTERRUPT0_LINE_START);
2089
2090	/* Set interval width for interrupt to fire to 1 scanline */
2091	set_reg_field_value(
2092		val,
2093		v_blank_start + width,
2094		CRTC_VERTICAL_INTERRUPT0_POSITION,
2095		CRTC_VERTICAL_INTERRUPT0_LINE_END);
2096
2097	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
2098
2099	return true;
2100}
2101
2102static bool dce110_is_tg_enabled(struct timing_generator *tg)
2103{
2104	uint32_t addr = 0;
2105	uint32_t value = 0;
2106	uint32_t field = 0;
2107	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2108
2109	addr = CRTC_REG(mmCRTC_CONTROL);
2110	value = dm_read_reg(tg->ctx, addr);
2111	field = get_reg_field_value(value, CRTC_CONTROL,
2112				    CRTC_CURRENT_MASTER_EN_STATE);
2113	return field == 1;
2114}
2115
2116bool dce110_configure_crc(struct timing_generator *tg,
2117			  const struct crc_params *params)
2118{
2119	uint32_t cntl_addr = 0;
2120	uint32_t addr = 0;
2121	uint32_t value;
2122	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2123
2124	/* Cannot configure crc on a CRTC that is disabled */
2125	if (!dce110_is_tg_enabled(tg))
2126		return false;
2127
2128	cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
2129
2130	if (!params->enable || params->reset)
2131		/* First, disable CRC before we configure it. */
2132		dm_write_reg(tg->ctx, cntl_addr, 0);
2133
2134	if (!params->enable)
2135		return true;
2136
2137	/* Program frame boundaries */
2138	switch (params->crc_eng_inst) {
2139	case 0:
2140		/* Window A x axis start and end. */
2141		value = 0;
2142		addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
2143		set_reg_field_value(value, params->windowa_x_start,
2144				    CRTC_CRC0_WINDOWA_X_CONTROL,
2145				    CRTC_CRC0_WINDOWA_X_START);
2146		set_reg_field_value(value, params->windowa_x_end,
2147				    CRTC_CRC0_WINDOWA_X_CONTROL,
2148				    CRTC_CRC0_WINDOWA_X_END);
2149		dm_write_reg(tg->ctx, addr, value);
2150
2151		/* Window A y axis start and end. */
2152		value = 0;
2153		addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL);
2154		set_reg_field_value(value, params->windowa_y_start,
2155				    CRTC_CRC0_WINDOWA_Y_CONTROL,
2156				    CRTC_CRC0_WINDOWA_Y_START);
2157		set_reg_field_value(value, params->windowa_y_end,
2158				    CRTC_CRC0_WINDOWA_Y_CONTROL,
2159				    CRTC_CRC0_WINDOWA_Y_END);
2160		dm_write_reg(tg->ctx, addr, value);
2161
2162		/* Window B x axis start and end. */
2163		value = 0;
2164		addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL);
2165		set_reg_field_value(value, params->windowb_x_start,
2166				    CRTC_CRC0_WINDOWB_X_CONTROL,
2167				    CRTC_CRC0_WINDOWB_X_START);
2168		set_reg_field_value(value, params->windowb_x_end,
2169				    CRTC_CRC0_WINDOWB_X_CONTROL,
2170				    CRTC_CRC0_WINDOWB_X_END);
2171		dm_write_reg(tg->ctx, addr, value);
2172
2173		/* Window B y axis start and end. */
2174		value = 0;
2175		addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL);
2176		set_reg_field_value(value, params->windowb_y_start,
2177				    CRTC_CRC0_WINDOWB_Y_CONTROL,
2178				    CRTC_CRC0_WINDOWB_Y_START);
2179		set_reg_field_value(value, params->windowb_y_end,
2180				    CRTC_CRC0_WINDOWB_Y_CONTROL,
2181				    CRTC_CRC0_WINDOWB_Y_END);
2182		dm_write_reg(tg->ctx, addr, value);
2183
2184		/* Set crc mode and selection, and enable.*/
2185		value = 0;
2186		set_reg_field_value(value, params->continuous_mode ? 1 : 0,
2187				    CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
2188		set_reg_field_value(value, params->selection,
2189				    CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
2190		set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
2191		dm_write_reg(tg->ctx, cntl_addr, value);
2192		break;
2193	case 1:
2194		/* Window A x axis start and end. */
2195		value = 0;
2196		addr = CRTC_REG(mmCRTC_CRC1_WINDOWA_X_CONTROL);
2197		set_reg_field_value(value, params->windowa_x_start,
2198				    CRTC_CRC1_WINDOWA_X_CONTROL,
2199				    CRTC_CRC1_WINDOWA_X_START);
2200		set_reg_field_value(value, params->windowa_x_end,
2201				    CRTC_CRC1_WINDOWA_X_CONTROL,
2202				    CRTC_CRC1_WINDOWA_X_END);
2203		dm_write_reg(tg->ctx, addr, value);
2204
2205		/* Window A y axis start and end. */
2206		value = 0;
2207		addr = CRTC_REG(mmCRTC_CRC1_WINDOWA_Y_CONTROL);
2208		set_reg_field_value(value, params->windowa_y_start,
2209				    CRTC_CRC1_WINDOWA_Y_CONTROL,
2210				    CRTC_CRC1_WINDOWA_Y_START);
2211		set_reg_field_value(value, params->windowa_y_end,
2212				    CRTC_CRC1_WINDOWA_Y_CONTROL,
2213				    CRTC_CRC1_WINDOWA_Y_END);
2214		dm_write_reg(tg->ctx, addr, value);
2215
2216		/* Window B x axis start and end. */
2217		value = 0;
2218		addr = CRTC_REG(mmCRTC_CRC1_WINDOWB_X_CONTROL);
2219		set_reg_field_value(value, params->windowb_x_start,
2220				    CRTC_CRC1_WINDOWB_X_CONTROL,
2221				    CRTC_CRC1_WINDOWB_X_START);
2222		set_reg_field_value(value, params->windowb_x_end,
2223				    CRTC_CRC1_WINDOWB_X_CONTROL,
2224				    CRTC_CRC1_WINDOWB_X_END);
2225		dm_write_reg(tg->ctx, addr, value);
2226
2227		/* Window B y axis start and end. */
2228		value = 0;
2229		addr = CRTC_REG(mmCRTC_CRC1_WINDOWB_Y_CONTROL);
2230		set_reg_field_value(value, params->windowb_y_start,
2231				    CRTC_CRC1_WINDOWB_Y_CONTROL,
2232				    CRTC_CRC1_WINDOWB_Y_START);
2233		set_reg_field_value(value, params->windowb_y_end,
2234				    CRTC_CRC1_WINDOWB_Y_CONTROL,
2235				    CRTC_CRC1_WINDOWB_Y_END);
2236		dm_write_reg(tg->ctx, addr, value);
2237
2238		/* Set crc mode and selection, and enable.*/
2239		value = 0;
2240		set_reg_field_value(value, params->continuous_mode ? 1 : 0,
2241				    CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
2242		set_reg_field_value(value, params->selection,
2243				    CRTC_CRC_CNTL, CRTC_CRC1_SELECT);
2244		set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
2245		dm_write_reg(tg->ctx, cntl_addr, value);
2246		break;
2247	default:
2248		return false;
2249	}
2250
2251	return true;
2252}
2253
2254bool dce110_get_crc(struct timing_generator *tg, uint8_t idx,
2255		    uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
2256{
2257	uint32_t addr = 0;
2258	uint32_t value = 0;
2259	uint32_t field = 0;
2260	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2261
2262	addr = CRTC_REG(mmCRTC_CRC_CNTL);
2263	value = dm_read_reg(tg->ctx, addr);
2264	field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN);
2265
2266	/* Early return if CRC is not enabled for this CRTC */
2267	if (!field)
2268		return false;
2269
2270	switch (idx) {
2271	case 0:
2272		addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
2273		value = dm_read_reg(tg->ctx, addr);
2274		*r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
2275		*g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
2276
2277		addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
2278		value = dm_read_reg(tg->ctx, addr);
2279		*b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
2280		break;
2281	case 1:
2282		addr = CRTC_REG(mmCRTC_CRC1_DATA_RG);
2283		value = dm_read_reg(tg->ctx, addr);
2284		*r_cr = get_reg_field_value(value, CRTC_CRC1_DATA_RG, CRC1_R_CR);
2285		*g_y = get_reg_field_value(value, CRTC_CRC1_DATA_RG, CRC1_G_Y);
2286
2287		addr = CRTC_REG(mmCRTC_CRC1_DATA_B);
2288		value = dm_read_reg(tg->ctx, addr);
2289		*b_cb = get_reg_field_value(value, CRTC_CRC1_DATA_B, CRC1_B_CB);
2290		break;
2291	default:
2292		return false;
2293	}
2294
2295	return true;
2296}
2297
2298static const struct timing_generator_funcs dce110_tg_funcs = {
2299		.validate_timing = dce110_tg_validate_timing,
2300		.program_timing = dce110_tg_program_timing,
2301		.enable_crtc = dce110_timing_generator_enable_crtc,
2302		.disable_crtc = dce110_timing_generator_disable_crtc,
2303		.is_counter_moving = dce110_timing_generator_is_counter_moving,
2304		.get_position = dce110_timing_generator_get_position,
2305		.get_frame_count = dce110_timing_generator_get_vblank_counter,
2306		.get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
2307		.set_early_control = dce110_timing_generator_set_early_control,
2308		.wait_for_state = dce110_tg_wait_for_state,
2309		.set_blank = dce110_tg_set_blank,
2310		.is_blanked = dce110_tg_is_blanked,
2311		.set_colors = dce110_tg_set_colors,
2312		.set_overscan_blank_color =
2313				dce110_timing_generator_set_overscan_color_black,
2314		.set_blank_color = dce110_timing_generator_program_blank_color,
2315		.disable_vga = dce110_timing_generator_disable_vga,
2316		.did_triggered_reset_occur =
2317				dce110_timing_generator_did_triggered_reset_occur,
2318		.setup_global_swap_lock =
2319				dce110_timing_generator_setup_global_swap_lock,
2320		.enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
2321		.enable_crtc_reset = dce110_timing_generator_enable_crtc_reset,
2322		.disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
2323		.tear_down_global_swap_lock =
2324				dce110_timing_generator_tear_down_global_swap_lock,
2325		.enable_advanced_request =
2326				dce110_timing_generator_enable_advanced_request,
2327		.set_drr =
2328				dce110_timing_generator_set_drr,
2329		.get_last_used_drr_vtotal = NULL,
2330		.set_static_screen_control =
2331			dce110_timing_generator_set_static_screen_control,
2332		.set_test_pattern = dce110_timing_generator_set_test_pattern,
2333		.arm_vert_intr = dce110_arm_vert_intr,
2334		.is_tg_enabled = dce110_is_tg_enabled,
2335		.configure_crc = dce110_configure_crc,
2336		.get_crc = dce110_get_crc,
2337		.is_two_pixels_per_container = dce110_is_two_pixels_per_container,
2338};
2339
2340void dce110_timing_generator_construct(
2341	struct dce110_timing_generator *tg110,
2342	struct dc_context *ctx,
2343	uint32_t instance,
2344	const struct dce110_timing_generator_offsets *offsets)
2345{
2346	tg110->controller_id = CONTROLLER_ID_D0 + instance;
2347	tg110->base.inst = instance;
2348
2349	tg110->offsets = *offsets;
2350
2351	tg110->base.funcs = &dce110_tg_funcs;
2352
2353	tg110->base.ctx = ctx;
2354	tg110->base.bp = ctx->dc_bios;
2355
2356	tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
2357	tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
2358
2359	tg110->min_h_blank = 56;
2360	tg110->min_h_front_porch = 4;
2361	tg110->min_h_back_porch = 4;
2362}
~/ Read-only file preview.