Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1/*
   2 * Copyright 2015 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#include "dc.h"
  28#include "dc_bios_types.h"
  29#include "core_types.h"
  30#include "core_status.h"
  31#include "resource.h"
  32#include "dm_helpers.h"
  33#include "dce110_timing_generator.h"
  34#include "dce/dce_hwseq.h"
  35#include "gpio_service_interface.h"
  36
  37#include "dce110_compressor.h"
  38
  39#include "bios/bios_parser_helper.h"
  40#include "timing_generator.h"
  41#include "mem_input.h"
  42#include "opp.h"
  43#include "ipp.h"
  44#include "transform.h"
  45#include "stream_encoder.h"
  46#include "link_encoder.h"
  47#include "link_enc_cfg.h"
  48#include "link_hwss.h"
  49#include "dc_link_dp.h"
  50#include "dccg.h"
  51#include "clock_source.h"
  52#include "clk_mgr.h"
  53#include "abm.h"
  54#include "audio.h"
  55#include "reg_helper.h"
  56#include "panel_cntl.h"
  57#include "inc/link_dpcd.h"
  58#include "dpcd_defs.h"
  59/* include DCE11 register header files */
  60#include "dce/dce_11_0_d.h"
  61#include "dce/dce_11_0_sh_mask.h"
  62#include "custom_float.h"
  63
  64#include "atomfirmware.h"
  65
  66#include "dcn10/dcn10_hw_sequencer.h"
  67
  68#include "link/link_dp_trace.h"
  69#include "dce110_hw_sequencer.h"
  70
  71#define GAMMA_HW_POINTS_NUM 256
  72
  73/*
  74 * All values are in milliseconds;
  75 * For eDP, after power-up/power/down,
  76 * 300/500 msec max. delay from LCDVCC to black video generation
  77 */
  78#define PANEL_POWER_UP_TIMEOUT 300
  79#define PANEL_POWER_DOWN_TIMEOUT 500
  80#define HPD_CHECK_INTERVAL 10
  81#define OLED_POST_T7_DELAY 100
  82#define OLED_PRE_T11_DELAY 150
  83
  84#define CTX \
  85	hws->ctx
  86
  87#define DC_LOGGER_INIT()
  88
  89#define REG(reg)\
  90	hws->regs->reg
  91
  92#undef FN
  93#define FN(reg_name, field_name) \
  94	hws->shifts->field_name, hws->masks->field_name
  95
  96struct dce110_hw_seq_reg_offsets {
  97	uint32_t crtc;
  98};
  99
 100static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
 101{
 102	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 103},
 104{
 105	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 106},
 107{
 108	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 109},
 110{
 111	.crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 112}
 113};
 114
 115#define HW_REG_BLND(reg, id)\
 116	(reg + reg_offsets[id].blnd)
 117
 118#define HW_REG_CRTC(reg, id)\
 119	(reg + reg_offsets[id].crtc)
 120
 121#define MAX_WATERMARK 0xFFFF
 122#define SAFE_NBP_MARK 0x7FFF
 123
 124/*******************************************************************************
 125 * Private definitions
 126 ******************************************************************************/
 127/***************************PIPE_CONTROL***********************************/
 128static void dce110_init_pte(struct dc_context *ctx)
 129{
 130	uint32_t addr;
 131	uint32_t value = 0;
 132	uint32_t chunk_int = 0;
 133	uint32_t chunk_mul = 0;
 134
 135	addr = mmUNP_DVMM_PTE_CONTROL;
 136	value = dm_read_reg(ctx, addr);
 137
 138	set_reg_field_value(
 139		value,
 140		0,
 141		DVMM_PTE_CONTROL,
 142		DVMM_USE_SINGLE_PTE);
 143
 144	set_reg_field_value(
 145		value,
 146		1,
 147		DVMM_PTE_CONTROL,
 148		DVMM_PTE_BUFFER_MODE0);
 149
 150	set_reg_field_value(
 151		value,
 152		1,
 153		DVMM_PTE_CONTROL,
 154		DVMM_PTE_BUFFER_MODE1);
 155
 156	dm_write_reg(ctx, addr, value);
 157
 158	addr = mmDVMM_PTE_REQ;
 159	value = dm_read_reg(ctx, addr);
 160
 161	chunk_int = get_reg_field_value(
 162		value,
 163		DVMM_PTE_REQ,
 164		HFLIP_PTEREQ_PER_CHUNK_INT);
 165
 166	chunk_mul = get_reg_field_value(
 167		value,
 168		DVMM_PTE_REQ,
 169		HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
 170
 171	if (chunk_int != 0x4 || chunk_mul != 0x4) {
 172
 173		set_reg_field_value(
 174			value,
 175			255,
 176			DVMM_PTE_REQ,
 177			MAX_PTEREQ_TO_ISSUE);
 178
 179		set_reg_field_value(
 180			value,
 181			4,
 182			DVMM_PTE_REQ,
 183			HFLIP_PTEREQ_PER_CHUNK_INT);
 184
 185		set_reg_field_value(
 186			value,
 187			4,
 188			DVMM_PTE_REQ,
 189			HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
 190
 191		dm_write_reg(ctx, addr, value);
 192	}
 193}
 194/**************************************************************************/
 195
 196static void enable_display_pipe_clock_gating(
 197	struct dc_context *ctx,
 198	bool clock_gating)
 199{
 200	/*TODO*/
 201}
 202
 203static bool dce110_enable_display_power_gating(
 204	struct dc *dc,
 205	uint8_t controller_id,
 206	struct dc_bios *dcb,
 207	enum pipe_gating_control power_gating)
 208{
 209	enum bp_result bp_result = BP_RESULT_OK;
 210	enum bp_pipe_control_action cntl;
 211	struct dc_context *ctx = dc->ctx;
 212	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
 213
 214	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
 215		return true;
 216
 217	if (power_gating == PIPE_GATING_CONTROL_INIT)
 218		cntl = ASIC_PIPE_INIT;
 219	else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
 220		cntl = ASIC_PIPE_ENABLE;
 221	else
 222		cntl = ASIC_PIPE_DISABLE;
 223
 224	if (controller_id == underlay_idx)
 225		controller_id = CONTROLLER_ID_UNDERLAY0 - 1;
 226
 227	if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){
 228
 229		bp_result = dcb->funcs->enable_disp_power_gating(
 230						dcb, controller_id + 1, cntl);
 231
 232		/* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
 233		 * by default when command table is called
 234		 *
 235		 * Bios parser accepts controller_id = 6 as indicative of
 236		 * underlay pipe in dce110. But we do not support more
 237		 * than 3.
 238		 */
 239		if (controller_id < CONTROLLER_ID_MAX - 1)
 240			dm_write_reg(ctx,
 241				HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
 242				0);
 243	}
 244
 245	if (power_gating != PIPE_GATING_CONTROL_ENABLE)
 246		dce110_init_pte(ctx);
 247
 248	if (bp_result == BP_RESULT_OK)
 249		return true;
 250	else
 251		return false;
 252}
 253
 254static void build_prescale_params(struct ipp_prescale_params *prescale_params,
 255		const struct dc_plane_state *plane_state)
 256{
 257	prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
 258
 259	switch (plane_state->format) {
 260	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
 261		prescale_params->scale = 0x2082;
 262		break;
 263	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
 264	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
 265		prescale_params->scale = 0x2020;
 266		break;
 267	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
 268	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
 269		prescale_params->scale = 0x2008;
 270		break;
 271	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
 272	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
 273	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
 274		prescale_params->scale = 0x2000;
 275		break;
 276	default:
 277		ASSERT(false);
 278		break;
 279	}
 280}
 281
 282static bool
 283dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
 284			       const struct dc_plane_state *plane_state)
 285{
 286	struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
 287	const struct dc_transfer_func *tf = NULL;
 288	struct ipp_prescale_params prescale_params = { 0 };
 289	bool result = true;
 290
 291	if (ipp == NULL)
 292		return false;
 293
 294	if (plane_state->in_transfer_func)
 295		tf = plane_state->in_transfer_func;
 296
 297	build_prescale_params(&prescale_params, plane_state);
 298	ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
 299
 300	if (plane_state->gamma_correction &&
 301			!plane_state->gamma_correction->is_identity &&
 302			dce_use_lut(plane_state->format))
 303		ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
 304
 305	if (tf == NULL) {
 306		/* Default case if no input transfer function specified */
 307		ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
 308	} else if (tf->type == TF_TYPE_PREDEFINED) {
 309		switch (tf->tf) {
 310		case TRANSFER_FUNCTION_SRGB:
 311			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
 312			break;
 313		case TRANSFER_FUNCTION_BT709:
 314			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC);
 315			break;
 316		case TRANSFER_FUNCTION_LINEAR:
 317			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
 318			break;
 319		case TRANSFER_FUNCTION_PQ:
 320		default:
 321			result = false;
 322			break;
 323		}
 324	} else if (tf->type == TF_TYPE_BYPASS) {
 325		ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
 326	} else {
 327		/*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
 328		result = false;
 329	}
 330
 331	return result;
 332}
 333
 334static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted,
 335				    struct curve_points *arr_points,
 336				    uint32_t hw_points_num)
 337{
 338	struct custom_float_format fmt;
 339
 340	struct pwl_result_data *rgb = rgb_resulted;
 341
 342	uint32_t i = 0;
 343
 344	fmt.exponenta_bits = 6;
 345	fmt.mantissa_bits = 12;
 346	fmt.sign = true;
 347
 348	if (!convert_to_custom_float_format(arr_points[0].x, &fmt,
 349					    &arr_points[0].custom_float_x)) {
 350		BREAK_TO_DEBUGGER();
 351		return false;
 352	}
 353
 354	if (!convert_to_custom_float_format(arr_points[0].offset, &fmt,
 355					    &arr_points[0].custom_float_offset)) {
 356		BREAK_TO_DEBUGGER();
 357		return false;
 358	}
 359
 360	if (!convert_to_custom_float_format(arr_points[0].slope, &fmt,
 361					    &arr_points[0].custom_float_slope)) {
 362		BREAK_TO_DEBUGGER();
 363		return false;
 364	}
 365
 366	fmt.mantissa_bits = 10;
 367	fmt.sign = false;
 368
 369	if (!convert_to_custom_float_format(arr_points[1].x, &fmt,
 370					    &arr_points[1].custom_float_x)) {
 371		BREAK_TO_DEBUGGER();
 372		return false;
 373	}
 374
 375	if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
 376					    &arr_points[1].custom_float_y)) {
 377		BREAK_TO_DEBUGGER();
 378		return false;
 379	}
 380
 381	if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
 382					    &arr_points[1].custom_float_slope)) {
 383		BREAK_TO_DEBUGGER();
 384		return false;
 385	}
 386
 387	fmt.mantissa_bits = 12;
 388	fmt.sign = true;
 389
 390	while (i != hw_points_num) {
 391		if (!convert_to_custom_float_format(rgb->red, &fmt,
 392						    &rgb->red_reg)) {
 393			BREAK_TO_DEBUGGER();
 394			return false;
 395		}
 396
 397		if (!convert_to_custom_float_format(rgb->green, &fmt,
 398						    &rgb->green_reg)) {
 399			BREAK_TO_DEBUGGER();
 400			return false;
 401		}
 402
 403		if (!convert_to_custom_float_format(rgb->blue, &fmt,
 404						    &rgb->blue_reg)) {
 405			BREAK_TO_DEBUGGER();
 406			return false;
 407		}
 408
 409		if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
 410						    &rgb->delta_red_reg)) {
 411			BREAK_TO_DEBUGGER();
 412			return false;
 413		}
 414
 415		if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
 416						    &rgb->delta_green_reg)) {
 417			BREAK_TO_DEBUGGER();
 418			return false;
 419		}
 420
 421		if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
 422						    &rgb->delta_blue_reg)) {
 423			BREAK_TO_DEBUGGER();
 424			return false;
 425		}
 426
 427		++rgb;
 428		++i;
 429	}
 430
 431	return true;
 432}
 433
 434#define MAX_LOW_POINT      25
 435#define NUMBER_REGIONS     16
 436#define NUMBER_SW_SEGMENTS 16
 437
 438static bool
 439dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
 440				      struct pwl_params *regamma_params)
 441{
 442	struct curve_points *arr_points;
 443	struct pwl_result_data *rgb_resulted;
 444	struct pwl_result_data *rgb;
 445	struct pwl_result_data *rgb_plus_1;
 446	struct fixed31_32 y_r;
 447	struct fixed31_32 y_g;
 448	struct fixed31_32 y_b;
 449	struct fixed31_32 y1_min;
 450	struct fixed31_32 y3_max;
 451
 452	int32_t region_start, region_end;
 453	uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points;
 454
 455	if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS)
 456		return false;
 457
 458	arr_points = regamma_params->arr_points;
 459	rgb_resulted = regamma_params->rgb_resulted;
 460	hw_points = 0;
 461
 462	memset(regamma_params, 0, sizeof(struct pwl_params));
 463
 464	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
 465		/* 16 segments
 466		 * segments are from 2^-11 to 2^5
 467		 */
 468		region_start = -11;
 469		region_end = region_start + NUMBER_REGIONS;
 470
 471		for (i = 0; i < NUMBER_REGIONS; i++)
 472			seg_distr[i] = 4;
 473
 474	} else {
 475		/* 10 segments
 476		 * segment is from 2^-10 to 2^1
 477		 * We include an extra segment for range [2^0, 2^1). This is to
 478		 * ensure that colors with normalized values of 1 don't miss the
 479		 * LUT.
 480		 */
 481		region_start = -10;
 482		region_end = 1;
 483
 484		seg_distr[0] = 4;
 485		seg_distr[1] = 4;
 486		seg_distr[2] = 4;
 487		seg_distr[3] = 4;
 488		seg_distr[4] = 4;
 489		seg_distr[5] = 4;
 490		seg_distr[6] = 4;
 491		seg_distr[7] = 4;
 492		seg_distr[8] = 4;
 493		seg_distr[9] = 4;
 494		seg_distr[10] = 0;
 495		seg_distr[11] = -1;
 496		seg_distr[12] = -1;
 497		seg_distr[13] = -1;
 498		seg_distr[14] = -1;
 499		seg_distr[15] = -1;
 500	}
 501
 502	for (k = 0; k < 16; k++) {
 503		if (seg_distr[k] != -1)
 504			hw_points += (1 << seg_distr[k]);
 505	}
 506
 507	j = 0;
 508	for (k = 0; k < (region_end - region_start); k++) {
 509		increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
 510		start_index = (region_start + k + MAX_LOW_POINT) *
 511				NUMBER_SW_SEGMENTS;
 512		for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
 513				i += increment) {
 514			if (j == hw_points - 1)
 515				break;
 516			rgb_resulted[j].red = output_tf->tf_pts.red[i];
 517			rgb_resulted[j].green = output_tf->tf_pts.green[i];
 518			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
 519			j++;
 520		}
 521	}
 522
 523	/* last point */
 524	start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
 525	rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
 526	rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
 527	rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
 528
 529	arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
 530					     dc_fixpt_from_int(region_start));
 531	arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
 532					     dc_fixpt_from_int(region_end));
 533
 534	y_r = rgb_resulted[0].red;
 535	y_g = rgb_resulted[0].green;
 536	y_b = rgb_resulted[0].blue;
 537
 538	y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
 539
 540	arr_points[0].y = y1_min;
 541	arr_points[0].slope = dc_fixpt_div(arr_points[0].y,
 542						 arr_points[0].x);
 543
 544	y_r = rgb_resulted[hw_points - 1].red;
 545	y_g = rgb_resulted[hw_points - 1].green;
 546	y_b = rgb_resulted[hw_points - 1].blue;
 547
 548	/* see comment above, m_arrPoints[1].y should be the Y value for the
 549	 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
 550	 */
 551	y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
 552
 553	arr_points[1].y = y3_max;
 554
 555	arr_points[1].slope = dc_fixpt_zero;
 556
 557	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
 558		/* for PQ, we want to have a straight line from last HW X point,
 559		 * and the slope to be such that we hit 1.0 at 10000 nits.
 560		 */
 561		const struct fixed31_32 end_value = dc_fixpt_from_int(125);
 562
 563		arr_points[1].slope = dc_fixpt_div(
 564				dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
 565				dc_fixpt_sub(end_value, arr_points[1].x));
 566	}
 567
 568	regamma_params->hw_points_num = hw_points;
 569
 570	k = 0;
 571	for (i = 1; i < 16; i++) {
 572		if (seg_distr[k] != -1) {
 573			regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
 574			regamma_params->arr_curve_points[i].offset =
 575					regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
 576		}
 577		k++;
 578	}
 579
 580	if (seg_distr[k] != -1)
 581		regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
 582
 583	rgb = rgb_resulted;
 584	rgb_plus_1 = rgb_resulted + 1;
 585
 586	i = 1;
 587
 588	while (i != hw_points + 1) {
 589		if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
 590			rgb_plus_1->red = rgb->red;
 591		if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
 592			rgb_plus_1->green = rgb->green;
 593		if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
 594			rgb_plus_1->blue = rgb->blue;
 595
 596		rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
 597		rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
 598		rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
 599
 600		++rgb_plus_1;
 601		++rgb;
 602		++i;
 603	}
 604
 605	convert_to_custom_float(rgb_resulted, arr_points, hw_points);
 606
 607	return true;
 608}
 609
 610static bool
 611dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
 612				const struct dc_stream_state *stream)
 613{
 614	struct transform *xfm = pipe_ctx->plane_res.xfm;
 615
 616	xfm->funcs->opp_power_on_regamma_lut(xfm, true);
 617	xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
 618
 619	if (stream->out_transfer_func &&
 620	    stream->out_transfer_func->type == TF_TYPE_PREDEFINED &&
 621	    stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) {
 622		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
 623	} else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func,
 624							 &xfm->regamma_params)) {
 625		xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
 626		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
 627	} else {
 628		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
 629	}
 630
 631	xfm->funcs->opp_power_on_regamma_lut(xfm, false);
 632
 633	return true;
 634}
 635
 636void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
 637{
 638	bool is_hdmi_tmds;
 639	bool is_dp;
 640
 641	ASSERT(pipe_ctx->stream);
 642
 643	if (pipe_ctx->stream_res.stream_enc == NULL)
 644		return;  /* this is not root pipe */
 645
 646	is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
 647	is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
 648
 649	if (!is_hdmi_tmds && !is_dp)
 650		return;
 651
 652	if (is_hdmi_tmds)
 653		pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
 654			pipe_ctx->stream_res.stream_enc,
 655			&pipe_ctx->stream_res.encoder_info_frame);
 656	else
 657		pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
 658			pipe_ctx->stream_res.stream_enc,
 659			&pipe_ctx->stream_res.encoder_info_frame);
 660}
 661
 662void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 663{
 664	enum dc_lane_count lane_count =
 665		pipe_ctx->stream->link->cur_link_settings.lane_count;
 666	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
 667	struct dc_link *link = pipe_ctx->stream->link;
 668	const struct dc *dc = link->dc;
 669	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 670	uint32_t active_total_with_borders;
 671	uint32_t early_control = 0;
 672	struct timing_generator *tg = pipe_ctx->stream_res.tg;
 673
 674	link_hwss->setup_stream_encoder(pipe_ctx);
 675
 676	dc->hwss.update_info_frame(pipe_ctx);
 677
 678	/* enable early control to avoid corruption on DP monitor*/
 679	active_total_with_borders =
 680			timing->h_addressable
 681				+ timing->h_border_left
 682				+ timing->h_border_right;
 683
 684	if (lane_count != 0)
 685		early_control = active_total_with_borders % lane_count;
 686
 687	if (early_control == 0)
 688		early_control = lane_count;
 689
 690	tg->funcs->set_early_control(tg, early_control);
 691}
 692
 693static enum bp_result link_transmitter_control(
 694		struct dc_bios *bios,
 695	struct bp_transmitter_control *cntl)
 696{
 697	enum bp_result result;
 698
 699	result = bios->funcs->transmitter_control(bios, cntl);
 700
 701	return result;
 702}
 703
 704/*
 705 * @brief
 706 * eDP only.
 707 */
 708void dce110_edp_wait_for_hpd_ready(
 709		struct dc_link *link,
 710		bool power_up)
 711{
 712	struct dc_context *ctx = link->ctx;
 713	struct graphics_object_id connector = link->link_enc->connector;
 714	struct gpio *hpd;
 715	bool edp_hpd_high = false;
 716	uint32_t time_elapsed = 0;
 717	uint32_t timeout = power_up ?
 718		PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
 719
 720	if (dal_graphics_object_id_get_connector_id(connector)
 721			!= CONNECTOR_ID_EDP) {
 722		BREAK_TO_DEBUGGER();
 723		return;
 724	}
 725
 726	if (!power_up)
 727		/*
 728		 * From KV, we will not HPD low after turning off VCC -
 729		 * instead, we will check the SW timer in power_up().
 730		 */
 731		return;
 732
 733	/*
 734	 * When we power on/off the eDP panel,
 735	 * we need to wait until SENSE bit is high/low.
 736	 */
 737
 738	/* obtain HPD */
 739	/* TODO what to do with this? */
 740	hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
 741
 742	if (!hpd) {
 743		BREAK_TO_DEBUGGER();
 744		return;
 745	}
 746
 747	if (link != NULL) {
 748		if (link->panel_config.pps.extra_t3_ms > 0) {
 749			int extra_t3_in_ms = link->panel_config.pps.extra_t3_ms;
 750
 751			msleep(extra_t3_in_ms);
 752		}
 753	}
 754
 755	dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
 756
 757	/* wait until timeout or panel detected */
 758
 759	do {
 760		uint32_t detected = 0;
 761
 762		dal_gpio_get_value(hpd, &detected);
 763
 764		if (!(detected ^ power_up)) {
 765			edp_hpd_high = true;
 766			break;
 767		}
 768
 769		msleep(HPD_CHECK_INTERVAL);
 770
 771		time_elapsed += HPD_CHECK_INTERVAL;
 772	} while (time_elapsed < timeout);
 773
 774	dal_gpio_close(hpd);
 775
 776	dal_gpio_destroy_irq(&hpd);
 777
 778	if (false == edp_hpd_high) {
 779		DC_LOG_WARNING(
 780				"%s: wait timed out!\n", __func__);
 781	}
 782}
 783
 784void dce110_edp_power_control(
 785		struct dc_link *link,
 786		bool power_up)
 787{
 788	struct dc_context *ctx = link->ctx;
 789	struct bp_transmitter_control cntl = { 0 };
 790	enum bp_result bp_result;
 791	uint8_t panel_instance;
 792
 793
 794	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
 795			!= CONNECTOR_ID_EDP) {
 796		BREAK_TO_DEBUGGER();
 797		return;
 798	}
 799
 800	if (!link->panel_cntl)
 801		return;
 802	if (power_up !=
 803		link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) {
 804
 805		unsigned long long current_ts = dm_get_timestamp(ctx);
 806		unsigned long long time_since_edp_poweroff_ms =
 807				div64_u64(dm_get_elapse_time_in_ns(
 808						ctx,
 809						current_ts,
 810						dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
 811		unsigned long long time_since_edp_poweron_ms =
 812				div64_u64(dm_get_elapse_time_in_ns(
 813						ctx,
 814						current_ts,
 815						dp_trace_get_edp_poweron_timestamp(link)), 1000000);
 816		DC_LOG_HW_RESUME_S3(
 817				"%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu",
 818				__func__,
 819				power_up,
 820				current_ts,
 821				dp_trace_get_edp_poweroff_timestamp(link),
 822				dp_trace_get_edp_poweron_timestamp(link),
 823				time_since_edp_poweroff_ms,
 824				time_since_edp_poweron_ms);
 825
 826		/* Send VBIOS command to prompt eDP panel power */
 827		if (power_up) {
 828			/* edp requires a min of 500ms from LCDVDD off to on */
 829			unsigned long long remaining_min_edp_poweroff_time_ms = 500;
 830
 831			/* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */
 832			if (link->local_sink != NULL)
 833				remaining_min_edp_poweroff_time_ms +=
 834					link->panel_config.pps.extra_t12_ms;
 835
 836			/* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */
 837			if (dp_trace_get_edp_poweroff_timestamp(link) != 0) {
 838				if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms)
 839					remaining_min_edp_poweroff_time_ms =
 840						remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms;
 841				else
 842					remaining_min_edp_poweroff_time_ms = 0;
 843			}
 844
 845			if (remaining_min_edp_poweroff_time_ms) {
 846				DC_LOG_HW_RESUME_S3(
 847						"%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n",
 848						__func__, remaining_min_edp_poweroff_time_ms);
 849				msleep(remaining_min_edp_poweroff_time_ms);
 850				DC_LOG_HW_RESUME_S3(
 851						"%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n",
 852						__func__, remaining_min_edp_poweroff_time_ms);
 853				dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
 854						__func__, remaining_min_edp_poweroff_time_ms);
 855			} else {
 856				DC_LOG_HW_RESUME_S3(
 857						"%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n",
 858						__func__, remaining_min_edp_poweroff_time_ms);
 859			}
 860		}
 861
 862		DC_LOG_HW_RESUME_S3(
 863				"%s: BEGIN: Panel Power action: %s\n",
 864				__func__, (power_up ? "On":"Off"));
 865
 866		cntl.action = power_up ?
 867			TRANSMITTER_CONTROL_POWER_ON :
 868			TRANSMITTER_CONTROL_POWER_OFF;
 869		cntl.transmitter = link->link_enc->transmitter;
 870		cntl.connector_obj_id = link->link_enc->connector;
 871		cntl.coherent = false;
 872		cntl.lanes_number = LANE_COUNT_FOUR;
 873		cntl.hpd_sel = link->link_enc->hpd_source;
 874		panel_instance = link->panel_cntl->inst;
 875
 876		if (ctx->dc->ctx->dmub_srv &&
 877				ctx->dc->debug.dmub_command_table) {
 878			if (cntl.action == TRANSMITTER_CONTROL_POWER_ON)
 879				bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
 880						LVTMA_CONTROL_POWER_ON,
 881						panel_instance);
 882			else
 883				bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
 884						LVTMA_CONTROL_POWER_OFF,
 885						panel_instance);
 886		}
 887
 888		bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
 889
 890		DC_LOG_HW_RESUME_S3(
 891				"%s: END: Panel Power action: %s bp_result=%u\n",
 892				__func__, (power_up ? "On":"Off"),
 893				bp_result);
 894
 895		dp_trace_set_edp_power_timestamp(link, power_up);
 896
 897		DC_LOG_HW_RESUME_S3(
 898				"%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n",
 899				__func__,
 900				dp_trace_get_edp_poweroff_timestamp(link),
 901				dp_trace_get_edp_poweron_timestamp(link));
 902
 903		if (bp_result != BP_RESULT_OK)
 904			DC_LOG_ERROR(
 905					"%s: Panel Power bp_result: %d\n",
 906					__func__, bp_result);
 907	} else {
 908		DC_LOG_HW_RESUME_S3(
 909				"%s: Skipping Panel Power action: %s\n",
 910				__func__, (power_up ? "On":"Off"));
 911	}
 912}
 913
 914void dce110_edp_wait_for_T12(
 915		struct dc_link *link)
 916{
 917	struct dc_context *ctx = link->ctx;
 918
 919	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
 920			!= CONNECTOR_ID_EDP) {
 921		BREAK_TO_DEBUGGER();
 922		return;
 923	}
 924
 925	if (!link->panel_cntl)
 926		return;
 927
 928	if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) &&
 929			dp_trace_get_edp_poweroff_timestamp(link) != 0) {
 930		unsigned int t12_duration = 500; // Default T12 as per spec
 931		unsigned long long current_ts = dm_get_timestamp(ctx);
 932		unsigned long long time_since_edp_poweroff_ms =
 933				div64_u64(dm_get_elapse_time_in_ns(
 934						ctx,
 935						current_ts,
 936						dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
 937
 938		t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12
 939
 940		if (time_since_edp_poweroff_ms < t12_duration)
 941			msleep(t12_duration - time_since_edp_poweroff_ms);
 942	}
 943}
 944
 945/*todo: cloned in stream enc, fix*/
 946/*
 947 * @brief
 948 * eDP only. Control the backlight of the eDP panel
 949 */
 950void dce110_edp_backlight_control(
 951		struct dc_link *link,
 952		bool enable)
 953{
 954	struct dc_context *ctx = link->ctx;
 955	struct bp_transmitter_control cntl = { 0 };
 956	uint8_t panel_instance;
 957	unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
 958	unsigned int post_T7_delay = OLED_POST_T7_DELAY;
 959
 960	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
 961		!= CONNECTOR_ID_EDP) {
 962		BREAK_TO_DEBUGGER();
 963		return;
 964	}
 965
 966	if (link->panel_cntl) {
 967		bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl);
 968
 969		if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) {
 970			DC_LOG_HW_RESUME_S3(
 971				"%s: panel already powered up/off. Do nothing.\n",
 972				__func__);
 973			return;
 974		}
 975	}
 976
 977	/* Send VBIOS command to control eDP panel backlight */
 978
 979	DC_LOG_HW_RESUME_S3(
 980			"%s: backlight action: %s\n",
 981			__func__, (enable ? "On":"Off"));
 982
 983	cntl.action = enable ?
 984		TRANSMITTER_CONTROL_BACKLIGHT_ON :
 985		TRANSMITTER_CONTROL_BACKLIGHT_OFF;
 986
 987	/*cntl.engine_id = ctx->engine;*/
 988	cntl.transmitter = link->link_enc->transmitter;
 989	cntl.connector_obj_id = link->link_enc->connector;
 990	/*todo: unhardcode*/
 991	cntl.lanes_number = LANE_COUNT_FOUR;
 992	cntl.hpd_sel = link->link_enc->hpd_source;
 993	cntl.signal = SIGNAL_TYPE_EDP;
 994
 995	/* For eDP, the following delays might need to be considered
 996	 * after link training completed:
 997	 * idle period - min. accounts for required BS-Idle pattern,
 998	 * max. allows for source frame synchronization);
 999	 * 50 msec max. delay from valid video data from source
1000	 * to video on dislpay or backlight enable.
1001	 *
1002	 * Disable the delay for now.
1003	 * Enable it in the future if necessary.
1004	 */
1005	/* dc_service_sleep_in_milliseconds(50); */
1006		/*edp 1.2*/
1007	panel_instance = link->panel_cntl->inst;
1008
1009	if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
1010		if (!link->dc->config.edp_no_power_sequencing)
1011		/*
1012		 * Sometimes, DP receiver chip power-controlled externally by an
1013		 * Embedded Controller could be treated and used as eDP,
1014		 * if it drives mobile display. In this case,
1015		 * we shouldn't be doing power-sequencing, hence we can skip
1016		 * waiting for T7-ready.
1017		 */
1018			edp_receiver_ready_T7(link);
1019		else
1020			DC_LOG_DC("edp_receiver_ready_T7 skipped\n");
1021	}
1022
1023	if (ctx->dc->ctx->dmub_srv &&
1024			ctx->dc->debug.dmub_command_table) {
1025		if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
1026			ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
1027					LVTMA_CONTROL_LCD_BLON,
1028					panel_instance);
1029		else
1030			ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
1031					LVTMA_CONTROL_LCD_BLOFF,
1032					panel_instance);
1033	}
1034
1035	link_transmitter_control(ctx->dc_bios, &cntl);
1036
1037	if (enable && link->dpcd_sink_ext_caps.bits.oled) {
1038		post_T7_delay += link->panel_config.pps.extra_post_t7_ms;
1039		msleep(post_T7_delay);
1040	}
1041
1042	if (link->dpcd_sink_ext_caps.bits.oled ||
1043		link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
1044		link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)
1045		dc_link_backlight_enable_aux(link, enable);
1046
1047	/*edp 1.2*/
1048	if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) {
1049		if (!link->dc->config.edp_no_power_sequencing)
1050		/*
1051		 * Sometimes, DP receiver chip power-controlled externally by an
1052		 * Embedded Controller could be treated and used as eDP,
1053		 * if it drives mobile display. In this case,
1054		 * we shouldn't be doing power-sequencing, hence we can skip
1055		 * waiting for T9-ready.
1056		 */
1057			edp_add_delay_for_T9(link);
1058		else
1059			DC_LOG_DC("edp_receiver_ready_T9 skipped\n");
1060	}
1061
1062	if (!enable && link->dpcd_sink_ext_caps.bits.oled) {
1063		pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms;
1064		msleep(pre_T11_delay);
1065	}
1066}
1067
1068void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
1069{
1070	/* notify audio driver for audio modes of monitor */
1071	struct dc *dc;
1072	struct clk_mgr *clk_mgr;
1073	unsigned int i, num_audio = 1;
1074	const struct link_hwss *link_hwss;
1075
1076	if (!pipe_ctx->stream)
1077		return;
1078
1079	dc = pipe_ctx->stream->ctx->dc;
1080	clk_mgr = dc->clk_mgr;
1081	link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
1082
1083	if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
1084		return;
1085
1086	if (pipe_ctx->stream_res.audio) {
1087		for (i = 0; i < MAX_PIPES; i++) {
1088			/*current_state not updated yet*/
1089			if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
1090				num_audio++;
1091		}
1092
1093		pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
1094
1095		if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa)
1096			/*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
1097			clk_mgr->funcs->enable_pme_wa(clk_mgr);
1098
1099		link_hwss->enable_audio_packet(pipe_ctx);
1100
1101		if (pipe_ctx->stream_res.audio)
1102			pipe_ctx->stream_res.audio->enabled = true;
1103	}
1104}
1105
1106void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
1107{
1108	struct dc *dc;
1109	struct clk_mgr *clk_mgr;
1110	const struct link_hwss *link_hwss;
1111
1112	if (!pipe_ctx || !pipe_ctx->stream)
1113		return;
1114
1115	dc = pipe_ctx->stream->ctx->dc;
1116	clk_mgr = dc->clk_mgr;
1117	link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
1118
1119	if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
1120		return;
1121
1122	link_hwss->disable_audio_packet(pipe_ctx);
1123
1124	if (pipe_ctx->stream_res.audio) {
1125		pipe_ctx->stream_res.audio->enabled = false;
1126
1127		if (clk_mgr->funcs->enable_pme_wa)
1128			/*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
1129			clk_mgr->funcs->enable_pme_wa(clk_mgr);
1130
1131		/* TODO: notify audio driver for if audio modes list changed
1132		 * add audio mode list change flag */
1133		/* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
1134		 * stream->stream_engine_id);
1135		 */
1136	}
1137}
1138
1139void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
1140{
1141	struct dc_stream_state *stream = pipe_ctx->stream;
1142	struct dc_link *link = stream->link;
1143	struct dc *dc = pipe_ctx->stream->ctx->dc;
1144	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1145
1146	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
1147		pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
1148			pipe_ctx->stream_res.stream_enc);
1149		pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute(
1150			pipe_ctx->stream_res.stream_enc);
1151	}
1152
1153	if (is_dp_128b_132b_signal(pipe_ctx)) {
1154		pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
1155					pipe_ctx->stream_res.hpo_dp_stream_enc);
1156	} else if (dc_is_dp_signal(pipe_ctx->stream->signal))
1157		pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
1158			pipe_ctx->stream_res.stream_enc);
1159
1160	dc->hwss.disable_audio_stream(pipe_ctx);
1161
1162	link_hwss->reset_stream_encoder(pipe_ctx);
1163
1164	if (is_dp_128b_132b_signal(pipe_ctx)) {
1165		/* TODO: This looks like a bug to me as we are disabling HPO IO when
1166		 * we are just disabling a single HPO stream. Shouldn't we disable HPO
1167		 * HW control only when HPOs for all streams are disabled?
1168		 */
1169		if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
1170			pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
1171					pipe_ctx->stream->ctx->dc->hwseq, false);
1172	}
1173}
1174
1175void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
1176		struct dc_link_settings *link_settings)
1177{
1178	struct encoder_unblank_param params = { { 0 } };
1179	struct dc_stream_state *stream = pipe_ctx->stream;
1180	struct dc_link *link = stream->link;
1181	struct dce_hwseq *hws = link->dc->hwseq;
1182
1183	/* only 3 items below are used by unblank */
1184	params.timing = pipe_ctx->stream->timing;
1185	params.link_settings.link_rate = link_settings->link_rate;
1186
1187	if (dc_is_dp_signal(pipe_ctx->stream->signal))
1188		pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
1189
1190	if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1191		hws->funcs.edp_backlight_control(link, true);
1192	}
1193}
1194
1195void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
1196{
1197	struct dc_stream_state *stream = pipe_ctx->stream;
1198	struct dc_link *link = stream->link;
1199	struct dce_hwseq *hws = link->dc->hwseq;
1200
1201	if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1202		hws->funcs.edp_backlight_control(link, false);
1203		link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
1204	}
1205
1206	if (is_dp_128b_132b_signal(pipe_ctx)) {
1207		/* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
1208		pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
1209				pipe_ctx->stream_res.hpo_dp_stream_enc);
1210	} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
1211		pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
1212
1213		if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) {
1214			/*
1215			 * After output is idle pattern some sinks need time to recognize the stream
1216			 * has changed or they enter protection state and hang.
1217			 */
1218			msleep(60);
1219		} else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
1220			if (!link->dc->config.edp_no_power_sequencing) {
1221				/*
1222				 * Sometimes, DP receiver chip power-controlled externally by an
1223				 * Embedded Controller could be treated and used as eDP,
1224				 * if it drives mobile display. In this case,
1225				 * we shouldn't be doing power-sequencing, hence we can skip
1226				 * waiting for T9-ready.
1227				 */
1228				edp_receiver_ready_T9(link);
1229			}
1230		}
1231	}
1232
1233}
1234
1235
1236void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
1237{
1238	if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
1239		pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
1240}
1241
1242static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
1243{
1244	switch (crtc_id) {
1245	case CONTROLLER_ID_D0:
1246		return DTO_SOURCE_ID0;
1247	case CONTROLLER_ID_D1:
1248		return DTO_SOURCE_ID1;
1249	case CONTROLLER_ID_D2:
1250		return DTO_SOURCE_ID2;
1251	case CONTROLLER_ID_D3:
1252		return DTO_SOURCE_ID3;
1253	case CONTROLLER_ID_D4:
1254		return DTO_SOURCE_ID4;
1255	case CONTROLLER_ID_D5:
1256		return DTO_SOURCE_ID5;
1257	default:
1258		return DTO_SOURCE_UNKNOWN;
1259	}
1260}
1261
1262static void build_audio_output(
1263	struct dc_state *state,
1264	const struct pipe_ctx *pipe_ctx,
1265	struct audio_output *audio_output)
1266{
1267	const struct dc_stream_state *stream = pipe_ctx->stream;
1268	audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id;
1269
1270	audio_output->signal = pipe_ctx->stream->signal;
1271
1272	/* audio_crtc_info  */
1273
1274	audio_output->crtc_info.h_total =
1275		stream->timing.h_total;
1276
1277	/*
1278	 * Audio packets are sent during actual CRTC blank physical signal, we
1279	 * need to specify actual active signal portion
1280	 */
1281	audio_output->crtc_info.h_active =
1282			stream->timing.h_addressable
1283			+ stream->timing.h_border_left
1284			+ stream->timing.h_border_right;
1285
1286	audio_output->crtc_info.v_active =
1287			stream->timing.v_addressable
1288			+ stream->timing.v_border_top
1289			+ stream->timing.v_border_bottom;
1290
1291	audio_output->crtc_info.pixel_repetition = 1;
1292
1293	audio_output->crtc_info.interlaced =
1294			stream->timing.flags.INTERLACE;
1295
1296	audio_output->crtc_info.refresh_rate =
1297		(stream->timing.pix_clk_100hz*100)/
1298		(stream->timing.h_total*stream->timing.v_total);
1299
1300	audio_output->crtc_info.color_depth =
1301		stream->timing.display_color_depth;
1302
1303	audio_output->crtc_info.requested_pixel_clock_100Hz =
1304			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
1305
1306	audio_output->crtc_info.calculated_pixel_clock_100Hz =
1307			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
1308
1309/*for HDMI, audio ACR is with deep color ratio factor*/
1310	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) &&
1311		audio_output->crtc_info.requested_pixel_clock_100Hz ==
1312				(stream->timing.pix_clk_100hz)) {
1313		if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
1314			audio_output->crtc_info.requested_pixel_clock_100Hz =
1315					audio_output->crtc_info.requested_pixel_clock_100Hz/2;
1316			audio_output->crtc_info.calculated_pixel_clock_100Hz =
1317					pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2;
1318
1319		}
1320	}
1321
1322	if (state->clk_mgr &&
1323		(pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
1324			pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
1325		audio_output->pll_info.dp_dto_source_clock_in_khz =
1326				state->clk_mgr->funcs->get_dp_ref_clk_frequency(
1327						state->clk_mgr);
1328	}
1329
1330	audio_output->pll_info.feed_back_divider =
1331			pipe_ctx->pll_settings.feedback_divider;
1332
1333	audio_output->pll_info.dto_source =
1334		translate_to_dto_source(
1335			pipe_ctx->stream_res.tg->inst + 1);
1336
1337	/* TODO hard code to enable for now. Need get from stream */
1338	audio_output->pll_info.ss_enabled = true;
1339
1340	audio_output->pll_info.ss_percentage =
1341			pipe_ctx->pll_settings.ss_percentage;
1342}
1343
1344static void program_scaler(const struct dc *dc,
1345		const struct pipe_ctx *pipe_ctx)
1346{
1347	struct tg_color color = {0};
1348
1349	/* TOFPGA */
1350	if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
1351		return;
1352
1353	if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
1354		get_surface_visual_confirm_color(pipe_ctx, &color);
1355	else
1356		color_space_to_black_color(dc,
1357				pipe_ctx->stream->output_color_space,
1358				&color);
1359
1360	pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
1361		pipe_ctx->plane_res.xfm,
1362		pipe_ctx->plane_res.scl_data.lb_params.depth,
1363		&pipe_ctx->stream->bit_depth_params);
1364
1365	if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {
1366		/*
1367		 * The way 420 is packed, 2 channels carry Y component, 1 channel
1368		 * alternate between Cb and Cr, so both channels need the pixel
1369		 * value for Y
1370		 */
1371		if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
1372			color.color_r_cr = color.color_g_y;
1373
1374		pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
1375				pipe_ctx->stream_res.tg,
1376				&color);
1377	}
1378
1379	pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
1380		&pipe_ctx->plane_res.scl_data);
1381}
1382
1383static enum dc_status dce110_enable_stream_timing(
1384		struct pipe_ctx *pipe_ctx,
1385		struct dc_state *context,
1386		struct dc *dc)
1387{
1388	struct dc_stream_state *stream = pipe_ctx->stream;
1389	struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
1390			pipe_ctx[pipe_ctx->pipe_idx];
1391	struct tg_color black_color = {0};
1392
1393	if (!pipe_ctx_old->stream) {
1394
1395		/* program blank color */
1396		color_space_to_black_color(dc,
1397				stream->output_color_space, &black_color);
1398		pipe_ctx->stream_res.tg->funcs->set_blank_color(
1399				pipe_ctx->stream_res.tg,
1400				&black_color);
1401
1402		/*
1403		 * Must blank CRTC after disabling power gating and before any
1404		 * programming, otherwise CRTC will be hung in bad state
1405		 */
1406		pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
1407
1408		if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
1409				pipe_ctx->clock_source,
1410				&pipe_ctx->stream_res.pix_clk_params,
1411				dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings),
1412				&pipe_ctx->pll_settings)) {
1413			BREAK_TO_DEBUGGER();
1414			return DC_ERROR_UNEXPECTED;
1415		}
1416
1417		if (dc_is_hdmi_tmds_signal(stream->signal)) {
1418			stream->link->phy_state.symclk_ref_cnts.otg = 1;
1419			if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
1420				stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
1421			else
1422				stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
1423		}
1424
1425		pipe_ctx->stream_res.tg->funcs->program_timing(
1426				pipe_ctx->stream_res.tg,
1427				&stream->timing,
1428				0,
1429				0,
1430				0,
1431				0,
1432				pipe_ctx->stream->signal,
1433				true);
1434	}
1435
1436	if (!pipe_ctx_old->stream) {
1437		if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(
1438				pipe_ctx->stream_res.tg)) {
1439			BREAK_TO_DEBUGGER();
1440			return DC_ERROR_UNEXPECTED;
1441		}
1442	}
1443
1444	return DC_OK;
1445}
1446
1447static enum dc_status apply_single_controller_ctx_to_hw(
1448		struct pipe_ctx *pipe_ctx,
1449		struct dc_state *context,
1450		struct dc *dc)
1451{
1452	struct dc_stream_state *stream = pipe_ctx->stream;
1453	struct dc_link *link = stream->link;
1454	struct drr_params params = {0};
1455	unsigned int event_triggers = 0;
1456	struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
1457	struct dce_hwseq *hws = dc->hwseq;
1458	const struct link_hwss *link_hwss = get_link_hwss(
1459			link, &pipe_ctx->link_res);
1460
1461
1462	if (hws->funcs.disable_stream_gating) {
1463		hws->funcs.disable_stream_gating(dc, pipe_ctx);
1464	}
1465
1466	if (pipe_ctx->stream_res.audio != NULL) {
1467		struct audio_output audio_output;
1468
1469		build_audio_output(context, pipe_ctx, &audio_output);
1470
1471		link_hwss->setup_audio_output(pipe_ctx, &audio_output,
1472				pipe_ctx->stream_res.audio->inst);
1473
1474		pipe_ctx->stream_res.audio->funcs->az_configure(
1475				pipe_ctx->stream_res.audio,
1476				pipe_ctx->stream->signal,
1477				&audio_output.crtc_info,
1478				&pipe_ctx->stream->audio_info);
1479	}
1480
1481	/* make sure no pipes syncd to the pipe being enabled */
1482	if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic)
1483		check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx);
1484
1485	pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
1486		pipe_ctx->stream_res.opp,
1487		&stream->bit_depth_params,
1488		&stream->clamping);
1489
1490	pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
1491			pipe_ctx->stream_res.opp,
1492			COLOR_SPACE_YCBCR601,
1493			stream->timing.display_color_depth,
1494			stream->signal);
1495
1496	while (odm_pipe) {
1497		odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion(
1498				odm_pipe->stream_res.opp,
1499				COLOR_SPACE_YCBCR601,
1500				stream->timing.display_color_depth,
1501				stream->signal);
1502
1503		odm_pipe->stream_res.opp->funcs->opp_program_fmt(
1504				odm_pipe->stream_res.opp,
1505				&stream->bit_depth_params,
1506				&stream->clamping);
1507		odm_pipe = odm_pipe->next_odm_pipe;
1508	}
1509
1510	/* DCN3.1 FPGA Workaround
1511	 * Need to enable HPO DP Stream Encoder before setting OTG master enable.
1512	 * To do so, move calling function enable_stream_timing to only be done AFTER calling
1513	 * function core_link_enable_stream
1514	 */
1515	if (!(hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)))
1516		/*  */
1517		/* Do not touch stream timing on seamless boot optimization. */
1518		if (!pipe_ctx->stream->apply_seamless_boot_optimization)
1519			hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
1520
1521	if (hws->funcs.setup_vupdate_interrupt)
1522		hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
1523
1524	params.vertical_total_min = stream->adjust.v_total_min;
1525	params.vertical_total_max = stream->adjust.v_total_max;
1526	if (pipe_ctx->stream_res.tg->funcs->set_drr)
1527		pipe_ctx->stream_res.tg->funcs->set_drr(
1528			pipe_ctx->stream_res.tg, &params);
1529
1530	// DRR should set trigger event to monitor surface update event
1531	if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
1532		event_triggers = 0x80;
1533	/* Event triggers and num frames initialized for DRR, but can be
1534	 * later updated for PSR use. Note DRR trigger events are generated
1535	 * regardless of whether num frames met.
1536	 */
1537	if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
1538		pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
1539				pipe_ctx->stream_res.tg, event_triggers, 2);
1540
1541	if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
1542		pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
1543			pipe_ctx->stream_res.stream_enc,
1544			pipe_ctx->stream_res.tg->inst);
1545
1546	if (dc_is_dp_signal(pipe_ctx->stream->signal))
1547		dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
1548
1549	if (!stream->dpms_off)
1550		core_link_enable_stream(context, pipe_ctx);
1551
1552	/* DCN3.1 FPGA Workaround
1553	 * Need to enable HPO DP Stream Encoder before setting OTG master enable.
1554	 * To do so, move calling function enable_stream_timing to only be done AFTER calling
1555	 * function core_link_enable_stream
1556	 */
1557	if (hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)) {
1558		if (!pipe_ctx->stream->apply_seamless_boot_optimization)
1559			hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
1560	}
1561
1562	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
1563
1564	/* Phantom and main stream share the same link (because the stream
1565	 * is constructed with the same sink). Make sure not to override
1566	 * and link programming on the main.
1567	 */
1568	if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
1569		pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
1570	}
1571	return DC_OK;
1572}
1573
1574/******************************************************************************/
1575
1576static void power_down_encoders(struct dc *dc)
1577{
1578	int i;
1579
1580	for (i = 0; i < dc->link_count; i++) {
1581		enum signal_type signal = dc->links[i]->connector_signal;
1582
1583		dc_link_blank_dp_stream(dc->links[i], false);
1584
1585		if (signal != SIGNAL_TYPE_EDP)
1586			signal = SIGNAL_TYPE_NONE;
1587
1588		if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY)
1589			dc->links[i]->link_enc->funcs->disable_output(
1590					dc->links[i]->link_enc, signal);
1591
1592		dc->links[i]->link_status.link_active = false;
1593		memset(&dc->links[i]->cur_link_settings, 0,
1594				sizeof(dc->links[i]->cur_link_settings));
1595	}
1596}
1597
1598static void power_down_controllers(struct dc *dc)
1599{
1600	int i;
1601
1602	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
1603		dc->res_pool->timing_generators[i]->funcs->disable_crtc(
1604				dc->res_pool->timing_generators[i]);
1605	}
1606}
1607
1608static void power_down_clock_sources(struct dc *dc)
1609{
1610	int i;
1611
1612	if (dc->res_pool->dp_clock_source->funcs->cs_power_down(
1613		dc->res_pool->dp_clock_source) == false)
1614		dm_error("Failed to power down pll! (dp clk src)\n");
1615
1616	for (i = 0; i < dc->res_pool->clk_src_count; i++) {
1617		if (dc->res_pool->clock_sources[i]->funcs->cs_power_down(
1618				dc->res_pool->clock_sources[i]) == false)
1619			dm_error("Failed to power down pll! (clk src index=%d)\n", i);
1620	}
1621}
1622
1623static void power_down_all_hw_blocks(struct dc *dc)
1624{
1625	power_down_encoders(dc);
1626
1627	power_down_controllers(dc);
1628
1629	power_down_clock_sources(dc);
1630
1631	if (dc->fbc_compressor)
1632		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
1633}
1634
1635static void disable_vga_and_power_gate_all_controllers(
1636		struct dc *dc)
1637{
1638	int i;
1639	struct timing_generator *tg;
1640	struct dc_context *ctx = dc->ctx;
1641
1642	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
1643		tg = dc->res_pool->timing_generators[i];
1644
1645		if (tg->funcs->disable_vga)
1646			tg->funcs->disable_vga(tg);
1647	}
1648	for (i = 0; i < dc->res_pool->pipe_count; i++) {
1649		/* Enable CLOCK gating for each pipe BEFORE controller
1650		 * powergating. */
1651		enable_display_pipe_clock_gating(ctx,
1652				true);
1653
1654		dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i;
1655		dc->hwss.disable_plane(dc,
1656			&dc->current_state->res_ctx.pipe_ctx[i]);
1657	}
1658}
1659
1660
1661static void get_edp_streams(struct dc_state *context,
1662		struct dc_stream_state **edp_streams,
1663		int *edp_stream_num)
1664{
1665	int i;
1666
1667	*edp_stream_num = 0;
1668	for (i = 0; i < context->stream_count; i++) {
1669		if (context->streams[i]->signal == SIGNAL_TYPE_EDP) {
1670			edp_streams[*edp_stream_num] = context->streams[i];
1671			if (++(*edp_stream_num) == MAX_NUM_EDP)
1672				return;
1673		}
1674	}
1675}
1676
1677static void get_edp_links_with_sink(
1678		struct dc *dc,
1679		struct dc_link **edp_links_with_sink,
1680		int *edp_with_sink_num)
1681{
1682	int i;
1683
1684	/* check if there is an eDP panel not in use */
1685	*edp_with_sink_num = 0;
1686	for (i = 0; i < dc->link_count; i++) {
1687		if (dc->links[i]->local_sink &&
1688			dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1689			edp_links_with_sink[*edp_with_sink_num] = dc->links[i];
1690			if (++(*edp_with_sink_num) == MAX_NUM_EDP)
1691				return;
1692		}
1693	}
1694}
1695
1696/*
1697 * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
1698 *  1. Power down all DC HW blocks
1699 *  2. Disable VGA engine on all controllers
1700 *  3. Enable power gating for controller
1701 *  4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
1702 */
1703void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
1704{
1705	struct dc_link *edp_links_with_sink[MAX_NUM_EDP];
1706	struct dc_link *edp_links[MAX_NUM_EDP];
1707	struct dc_stream_state *edp_streams[MAX_NUM_EDP];
1708	struct dc_link *edp_link_with_sink = NULL;
1709	struct dc_link *edp_link = NULL;
1710	struct dce_hwseq *hws = dc->hwseq;
1711	int edp_with_sink_num;
1712	int edp_num;
1713	int edp_stream_num;
1714	int i;
1715	bool can_apply_edp_fast_boot = false;
1716	bool can_apply_seamless_boot = false;
1717	bool keep_edp_vdd_on = false;
1718	DC_LOGGER_INIT();
1719
1720
1721	get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num);
1722	get_edp_links(dc, edp_links, &edp_num);
1723
1724	if (hws->funcs.init_pipes)
1725		hws->funcs.init_pipes(dc, context);
1726
1727	get_edp_streams(context, edp_streams, &edp_stream_num);
1728
1729	// Check fastboot support, disable on DCE8 because of blank screens
1730	if (edp_num && edp_stream_num && dc->ctx->dce_version != DCE_VERSION_8_0 &&
1731		    dc->ctx->dce_version != DCE_VERSION_8_1 &&
1732		    dc->ctx->dce_version != DCE_VERSION_8_3) {
1733		for (i = 0; i < edp_num; i++) {
1734			edp_link = edp_links[i];
1735			if (edp_link != edp_streams[0]->link)
1736				continue;
1737			// enable fastboot if backend is enabled on eDP
1738			if (edp_link->link_enc->funcs->is_dig_enabled &&
1739			    edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
1740			    edp_link->link_status.link_active) {
1741				struct dc_stream_state *edp_stream = edp_streams[0];
1742
1743				can_apply_edp_fast_boot = dc_validate_boot_timing(dc,
1744					edp_stream->sink, &edp_stream->timing);
1745				edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot;
1746				if (can_apply_edp_fast_boot)
1747					DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n");
1748
1749				break;
1750			}
1751		}
1752		// We are trying to enable eDP, don't power down VDD
1753		if (can_apply_edp_fast_boot)
1754			keep_edp_vdd_on = true;
1755	}
1756
1757	// Check seamless boot support
1758	for (i = 0; i < context->stream_count; i++) {
1759		if (context->streams[i]->apply_seamless_boot_optimization) {
1760			can_apply_seamless_boot = true;
1761			break;
1762		}
1763	}
1764
1765	/* eDP should not have stream in resume from S4 and so even with VBios post
1766	 * it should get turned off
1767	 */
1768	if (edp_with_sink_num)
1769		edp_link_with_sink = edp_links_with_sink[0];
1770
1771	if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) {
1772		if (edp_link_with_sink && !keep_edp_vdd_on) {
1773			/*turn off backlight before DP_blank and encoder powered down*/
1774			hws->funcs.edp_backlight_control(edp_link_with_sink, false);
1775		}
1776		/*resume from S3, no vbios posting, no need to power down again*/
1777		power_down_all_hw_blocks(dc);
1778		disable_vga_and_power_gate_all_controllers(dc);
1779		if (edp_link_with_sink && !keep_edp_vdd_on)
1780			dc->hwss.edp_power_control(edp_link_with_sink, false);
1781	}
1782	bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1);
1783}
1784
1785static uint32_t compute_pstate_blackout_duration(
1786	struct bw_fixed blackout_duration,
1787	const struct dc_stream_state *stream)
1788{
1789	uint32_t total_dest_line_time_ns;
1790	uint32_t pstate_blackout_duration_ns;
1791
1792	pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
1793
1794	total_dest_line_time_ns = 1000000UL *
1795		(stream->timing.h_total * 10) /
1796		stream->timing.pix_clk_100hz +
1797		pstate_blackout_duration_ns;
1798
1799	return total_dest_line_time_ns;
1800}
1801
1802static void dce110_set_displaymarks(
1803	const struct dc *dc,
1804	struct dc_state *context)
1805{
1806	uint8_t i, num_pipes;
1807	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
1808
1809	for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) {
1810		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1811		uint32_t total_dest_line_time_ns;
1812
1813		if (pipe_ctx->stream == NULL)
1814			continue;
1815
1816		total_dest_line_time_ns = compute_pstate_blackout_duration(
1817			dc->bw_vbios->blackout_duration, pipe_ctx->stream);
1818		pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
1819			pipe_ctx->plane_res.mi,
1820			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1821			context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1822			context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes],
1823			context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
1824			total_dest_line_time_ns);
1825		if (i == underlay_idx) {
1826			num_pipes++;
1827			pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
1828				pipe_ctx->plane_res.mi,
1829				context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1830				context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1831				context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
1832				total_dest_line_time_ns);
1833		}
1834		num_pipes++;
1835	}
1836}
1837
1838void dce110_set_safe_displaymarks(
1839		struct resource_context *res_ctx,
1840		const struct resource_pool *pool)
1841{
1842	int i;
1843	int underlay_idx = pool->underlay_pipe_index;
1844	struct dce_watermarks max_marks = {
1845		MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK };
1846	struct dce_watermarks nbp_marks = {
1847		SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
1848	struct dce_watermarks min_marks = { 0, 0, 0, 0};
1849
1850	for (i = 0; i < MAX_PIPES; i++) {
1851		if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
1852			continue;
1853
1854		res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
1855				res_ctx->pipe_ctx[i].plane_res.mi,
1856				nbp_marks,
1857				max_marks,
1858				min_marks,
1859				max_marks,
1860				MAX_WATERMARK);
1861
1862		if (i == underlay_idx)
1863			res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
1864				res_ctx->pipe_ctx[i].plane_res.mi,
1865				nbp_marks,
1866				max_marks,
1867				max_marks,
1868				MAX_WATERMARK);
1869
1870	}
1871}
1872
1873/*******************************************************************************
1874 * Public functions
1875 ******************************************************************************/
1876
1877static void set_drr(struct pipe_ctx **pipe_ctx,
1878		int num_pipes, struct dc_crtc_timing_adjust adjust)
1879{
1880	int i = 0;
1881	struct drr_params params = {0};
1882	// DRR should set trigger event to monitor surface update event
1883	unsigned int event_triggers = 0x80;
1884	// Note DRR trigger events are generated regardless of whether num frames met.
1885	unsigned int num_frames = 2;
1886
1887	params.vertical_total_max = adjust.v_total_max;
1888	params.vertical_total_min = adjust.v_total_min;
1889
1890	/* TODO: If multiple pipes are to be supported, you need
1891	 * some GSL stuff. Static screen triggers may be programmed differently
1892	 * as well.
1893	 */
1894	for (i = 0; i < num_pipes; i++) {
1895		pipe_ctx[i]->stream_res.tg->funcs->set_drr(
1896			pipe_ctx[i]->stream_res.tg, &params);
1897
1898		if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
1899			pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
1900					pipe_ctx[i]->stream_res.tg,
1901					event_triggers, num_frames);
1902	}
1903}
1904
1905static void get_position(struct pipe_ctx **pipe_ctx,
1906		int num_pipes,
1907		struct crtc_position *position)
1908{
1909	int i = 0;
1910
1911	/* TODO: handle pipes > 1
1912	 */
1913	for (i = 0; i < num_pipes; i++)
1914		pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
1915}
1916
1917static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
1918		int num_pipes, const struct dc_static_screen_params *params)
1919{
1920	unsigned int i;
1921	unsigned int triggers = 0;
1922
1923	if (params->triggers.overlay_update)
1924		triggers |= 0x100;
1925	if (params->triggers.surface_update)
1926		triggers |= 0x80;
1927	if (params->triggers.cursor_update)
1928		triggers |= 0x2;
1929	if (params->triggers.force_trigger)
1930		triggers |= 0x1;
1931
1932	if (num_pipes) {
1933		struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
1934
1935		if (dc->fbc_compressor)
1936			triggers |= 0x84;
1937	}
1938
1939	for (i = 0; i < num_pipes; i++)
1940		pipe_ctx[i]->stream_res.tg->funcs->
1941			set_static_screen_control(pipe_ctx[i]->stream_res.tg,
1942					triggers, params->num_frames);
1943}
1944
1945/*
1946 *  Check if FBC can be enabled
1947 */
1948static bool should_enable_fbc(struct dc *dc,
1949		struct dc_state *context,
1950		uint32_t *pipe_idx)
1951{
1952	uint32_t i;
1953	struct pipe_ctx *pipe_ctx = NULL;
1954	struct resource_context *res_ctx = &context->res_ctx;
1955	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
1956
1957
1958	ASSERT(dc->fbc_compressor);
1959
1960	/* FBC memory should be allocated */
1961	if (!dc->ctx->fbc_gpu_addr)
1962		return false;
1963
1964	/* Only supports single display */
1965	if (context->stream_count != 1)
1966		return false;
1967
1968	for (i = 0; i < dc->res_pool->pipe_count; i++) {
1969		if (res_ctx->pipe_ctx[i].stream) {
1970
1971			pipe_ctx = &res_ctx->pipe_ctx[i];
1972
1973			if (!pipe_ctx)
1974				continue;
1975
1976			/* fbc not applicable on underlay pipe */
1977			if (pipe_ctx->pipe_idx != underlay_idx) {
1978				*pipe_idx = i;
1979				break;
1980			}
1981		}
1982	}
1983
1984	if (i == dc->res_pool->pipe_count)
1985		return false;
1986
1987	if (!pipe_ctx->stream->link)
1988		return false;
1989
1990	/* Only supports eDP */
1991	if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
1992		return false;
1993
1994	/* PSR should not be enabled */
1995	if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
1996		return false;
1997
1998	/* Nothing to compress */
1999	if (!pipe_ctx->plane_state)
2000		return false;
2001
2002	/* Only for non-linear tiling */
2003	if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
2004		return false;
2005
2006	return true;
2007}
2008
2009/*
2010 *  Enable FBC
2011 */
2012static void enable_fbc(
2013		struct dc *dc,
2014		struct dc_state *context)
2015{
2016	uint32_t pipe_idx = 0;
2017
2018	if (should_enable_fbc(dc, context, &pipe_idx)) {
2019		/* Program GRPH COMPRESSED ADDRESS and PITCH */
2020		struct compr_addr_and_pitch_params params = {0, 0, 0};
2021		struct compressor *compr = dc->fbc_compressor;
2022		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
2023
2024		params.source_view_width = pipe_ctx->stream->timing.h_addressable;
2025		params.source_view_height = pipe_ctx->stream->timing.v_addressable;
2026		params.inst = pipe_ctx->stream_res.tg->inst;
2027		compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
2028
2029		compr->funcs->surface_address_and_pitch(compr, &params);
2030		compr->funcs->set_fbc_invalidation_triggers(compr, 1);
2031
2032		compr->funcs->enable_fbc(compr, &params);
2033	}
2034}
2035
2036static void dce110_reset_hw_ctx_wrap(
2037		struct dc *dc,
2038		struct dc_state *context)
2039{
2040	int i;
2041
2042	/* Reset old context */
2043	/* look up the targets that have been removed since last commit */
2044	for (i = 0; i < MAX_PIPES; i++) {
2045		struct pipe_ctx *pipe_ctx_old =
2046			&dc->current_state->res_ctx.pipe_ctx[i];
2047		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2048
2049		/* Note: We need to disable output if clock sources change,
2050		 * since bios does optimization and doesn't apply if changing
2051		 * PHY when not already disabled.
2052		 */
2053
2054		/* Skip underlay pipe since it will be handled in commit surface*/
2055		if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe)
2056			continue;
2057
2058		if (!pipe_ctx->stream ||
2059				pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
2060			struct clock_source *old_clk = pipe_ctx_old->clock_source;
2061
2062			/* Disable if new stream is null. O/w, if stream is
2063			 * disabled already, no need to disable again.
2064			 */
2065			if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
2066				core_link_disable_stream(pipe_ctx_old);
2067
2068				/* free acquired resources*/
2069				if (pipe_ctx_old->stream_res.audio) {
2070					/*disable az_endpoint*/
2071					pipe_ctx_old->stream_res.audio->funcs->
2072							az_disable(pipe_ctx_old->stream_res.audio);
2073
2074					/*free audio*/
2075					if (dc->caps.dynamic_audio == true) {
2076						/*we have to dynamic arbitrate the audio endpoints*/
2077						/*we free the resource, need reset is_audio_acquired*/
2078						update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
2079								pipe_ctx_old->stream_res.audio, false);
2080						pipe_ctx_old->stream_res.audio = NULL;
2081					}
2082				}
2083			}
2084
2085			pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
2086			if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
2087				dm_error("DC: failed to blank crtc!\n");
2088				BREAK_TO_DEBUGGER();
2089			}
2090			pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg);
2091			pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0;
2092			pipe_ctx_old->plane_res.mi->funcs->free_mem_input(
2093					pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
2094
2095			if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx,
2096										dc->res_pool,
2097										old_clk))
2098				old_clk->funcs->cs_power_down(old_clk);
2099
2100			dc->hwss.disable_plane(dc, pipe_ctx_old);
2101
2102			pipe_ctx_old->stream = NULL;
2103		}
2104	}
2105}
2106
2107static void dce110_setup_audio_dto(
2108		struct dc *dc,
2109		struct dc_state *context)
2110{
2111	int i;
2112
2113	/* program audio wall clock. use HDMI as clock source if HDMI
2114	 * audio active. Otherwise, use DP as clock source
2115	 * first, loop to find any HDMI audio, if not, loop find DP audio
2116	 */
2117	/* Setup audio rate clock source */
2118	/* Issue:
2119	* Audio lag happened on DP monitor when unplug a HDMI monitor
2120	*
2121	* Cause:
2122	* In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL
2123	* is set to either dto0 or dto1, audio should work fine.
2124	* In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1,
2125	* set to dto0 will cause audio lag.
2126	*
2127	* Solution:
2128	* Not optimized audio wall dto setup. When mode set, iterate pipe_ctx,
2129	* find first available pipe with audio, setup audio wall DTO per topology
2130	* instead of per pipe.
2131	*/
2132	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2133		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2134
2135		if (pipe_ctx->stream == NULL)
2136			continue;
2137
2138		if (pipe_ctx->top_pipe)
2139			continue;
2140		if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
2141			continue;
2142		if (pipe_ctx->stream_res.audio != NULL) {
2143			struct audio_output audio_output;
2144
2145			build_audio_output(context, pipe_ctx, &audio_output);
2146
2147			if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {
2148				struct dtbclk_dto_params dto_params = {0};
2149
2150				dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
2151					dc->res_pool->dccg, &dto_params);
2152
2153				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
2154						pipe_ctx->stream_res.audio,
2155						pipe_ctx->stream->signal,
2156						&audio_output.crtc_info,
2157						&audio_output.pll_info);
2158			} else
2159				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
2160					pipe_ctx->stream_res.audio,
2161					pipe_ctx->stream->signal,
2162					&audio_output.crtc_info,
2163					&audio_output.pll_info);
2164			break;
2165		}
2166	}
2167
2168	/* no HDMI audio is found, try DP audio */
2169	if (i == dc->res_pool->pipe_count) {
2170		for (i = 0; i < dc->res_pool->pipe_count; i++) {
2171			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2172
2173			if (pipe_ctx->stream == NULL)
2174				continue;
2175
2176			if (pipe_ctx->top_pipe)
2177				continue;
2178
2179			if (!dc_is_dp_signal(pipe_ctx->stream->signal))
2180				continue;
2181
2182			if (pipe_ctx->stream_res.audio != NULL) {
2183				struct audio_output audio_output;
2184
2185				build_audio_output(context, pipe_ctx, &audio_output);
2186
2187				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
2188					pipe_ctx->stream_res.audio,
2189					pipe_ctx->stream->signal,
2190					&audio_output.crtc_info,
2191					&audio_output.pll_info);
2192				break;
2193			}
2194		}
2195	}
2196}
2197
2198enum dc_status dce110_apply_ctx_to_hw(
2199		struct dc *dc,
2200		struct dc_state *context)
2201{
2202	struct dce_hwseq *hws = dc->hwseq;
2203	struct dc_bios *dcb = dc->ctx->dc_bios;
2204	enum dc_status status;
2205	int i;
2206
2207	/* reset syncd pipes from disabled pipes */
2208	if (dc->config.use_pipe_ctx_sync_logic)
2209		reset_syncd_pipes_from_disabled_pipes(dc, context);
2210
2211	/* Reset old context */
2212	/* look up the targets that have been removed since last commit */
2213	hws->funcs.reset_hw_ctx_wrap(dc, context);
2214
2215	/* Skip applying if no targets */
2216	if (context->stream_count <= 0)
2217		return DC_OK;
2218
2219	/* Apply new context */
2220	dcb->funcs->set_scratch_critical_state(dcb, true);
2221
2222	/* below is for real asic only */
2223	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2224		struct pipe_ctx *pipe_ctx_old =
2225					&dc->current_state->res_ctx.pipe_ctx[i];
2226		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2227
2228		if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe)
2229			continue;
2230
2231		if (pipe_ctx->stream == pipe_ctx_old->stream) {
2232			if (pipe_ctx_old->clock_source != pipe_ctx->clock_source)
2233				dce_crtc_switch_to_clk_src(dc->hwseq,
2234						pipe_ctx->clock_source, i);
2235			continue;
2236		}
2237
2238		hws->funcs.enable_display_power_gating(
2239				dc, i, dc->ctx->dc_bios,
2240				PIPE_GATING_CONTROL_DISABLE);
2241	}
2242
2243	if (dc->fbc_compressor)
2244		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
2245
2246	dce110_setup_audio_dto(dc, context);
2247
2248	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2249		struct pipe_ctx *pipe_ctx_old =
2250					&dc->current_state->res_ctx.pipe_ctx[i];
2251		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2252
2253		if (pipe_ctx->stream == NULL)
2254			continue;
2255
2256		if (pipe_ctx->stream == pipe_ctx_old->stream &&
2257			pipe_ctx->stream->link->link_state_valid) {
2258			continue;
2259		}
2260
2261		if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
2262			continue;
2263
2264		if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
2265			continue;
2266
2267		status = apply_single_controller_ctx_to_hw(
2268				pipe_ctx,
2269				context,
2270				dc);
2271
2272		if (DC_OK != status)
2273			return status;
2274	}
2275
2276	if (dc->fbc_compressor)
2277		enable_fbc(dc, dc->current_state);
2278
2279	dcb->funcs->set_scratch_critical_state(dcb, false);
2280
2281	return DC_OK;
2282}
2283
2284/*******************************************************************************
2285 * Front End programming
2286 ******************************************************************************/
2287static void set_default_colors(struct pipe_ctx *pipe_ctx)
2288{
2289	struct default_adjustment default_adjust = { 0 };
2290
2291	default_adjust.force_hw_default = false;
2292	default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
2293	default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
2294	default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
2295	default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
2296
2297	/* display color depth */
2298	default_adjust.color_depth =
2299		pipe_ctx->stream->timing.display_color_depth;
2300
2301	/* Lb color depth */
2302	default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
2303
2304	pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
2305					pipe_ctx->plane_res.xfm, &default_adjust);
2306}
2307
2308
2309/*******************************************************************************
2310 * In order to turn on/off specific surface we will program
2311 * Blender + CRTC
2312 *
2313 * In case that we have two surfaces and they have a different visibility
2314 * we can't turn off the CRTC since it will turn off the entire display
2315 *
2316 * |----------------------------------------------- |
2317 * |bottom pipe|curr pipe  |              |         |
2318 * |Surface    |Surface    | Blender      |  CRCT   |
2319 * |visibility |visibility | Configuration|         |
2320 * |------------------------------------------------|
2321 * |   off     |    off    | CURRENT_PIPE | blank   |
2322 * |   off     |    on     | CURRENT_PIPE | unblank |
2323 * |   on      |    off    | OTHER_PIPE   | unblank |
2324 * |   on      |    on     | BLENDING     | unblank |
2325 * -------------------------------------------------|
2326 *
2327 ******************************************************************************/
2328static void program_surface_visibility(const struct dc *dc,
2329		struct pipe_ctx *pipe_ctx)
2330{
2331	enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE;
2332	bool blank_target = false;
2333
2334	if (pipe_ctx->bottom_pipe) {
2335
2336		/* For now we are supporting only two pipes */
2337		ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL);
2338
2339		if (pipe_ctx->bottom_pipe->plane_state->visible) {
2340			if (pipe_ctx->plane_state->visible)
2341				blender_mode = BLND_MODE_BLENDING;
2342			else
2343				blender_mode = BLND_MODE_OTHER_PIPE;
2344
2345		} else if (!pipe_ctx->plane_state->visible)
2346			blank_target = true;
2347
2348	} else if (!pipe_ctx->plane_state->visible)
2349		blank_target = true;
2350
2351	dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
2352	pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
2353
2354}
2355
2356static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
2357{
2358	int i = 0;
2359	struct xfm_grph_csc_adjustment adjust;
2360	memset(&adjust, 0, sizeof(adjust));
2361	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
2362
2363
2364	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
2365		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
2366
2367		for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
2368			adjust.temperature_matrix[i] =
2369				pipe_ctx->stream->gamut_remap_matrix.matrix[i];
2370	}
2371
2372	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
2373}
2374static void update_plane_addr(const struct dc *dc,
2375		struct pipe_ctx *pipe_ctx)
2376{
2377	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2378
2379	if (plane_state == NULL)
2380		return;
2381
2382	pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
2383			pipe_ctx->plane_res.mi,
2384			&plane_state->address,
2385			plane_state->flip_immediate);
2386
2387	plane_state->status.requested_address = plane_state->address;
2388}
2389
2390static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
2391{
2392	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2393
2394	if (plane_state == NULL)
2395		return;
2396
2397	plane_state->status.is_flip_pending =
2398			pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
2399					pipe_ctx->plane_res.mi);
2400
2401	if (plane_state->status.is_flip_pending && !plane_state->visible)
2402		pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address;
2403
2404	plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
2405	if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
2406			pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) {
2407		plane_state->status.is_right_eye =\
2408				!pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
2409	}
2410}
2411
2412void dce110_power_down(struct dc *dc)
2413{
2414	power_down_all_hw_blocks(dc);
2415	disable_vga_and_power_gate_all_controllers(dc);
2416}
2417
2418static bool wait_for_reset_trigger_to_occur(
2419	struct dc_context *dc_ctx,
2420	struct timing_generator *tg)
2421{
2422	bool rc = false;
2423
2424	/* To avoid endless loop we wait at most
2425	 * frames_to_wait_on_triggered_reset frames for the reset to occur. */
2426	const uint32_t frames_to_wait_on_triggered_reset = 10;
2427	uint32_t i;
2428
2429	for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
2430
2431		if (!tg->funcs->is_counter_moving(tg)) {
2432			DC_ERROR("TG counter is not moving!\n");
2433			break;
2434		}
2435
2436		if (tg->funcs->did_triggered_reset_occur(tg)) {
2437			rc = true;
2438			/* usually occurs at i=1 */
2439			DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
2440					i);
2441			break;
2442		}
2443
2444		/* Wait for one frame. */
2445		tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
2446		tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
2447	}
2448
2449	if (false == rc)
2450		DC_ERROR("GSL: Timeout on reset trigger!\n");
2451
2452	return rc;
2453}
2454
2455/* Enable timing synchronization for a group of Timing Generators. */
2456static void dce110_enable_timing_synchronization(
2457		struct dc *dc,
2458		int group_index,
2459		int group_size,
2460		struct pipe_ctx *grouped_pipes[])
2461{
2462	struct dc_context *dc_ctx = dc->ctx;
2463	struct dcp_gsl_params gsl_params = { 0 };
2464	int i;
2465
2466	DC_SYNC_INFO("GSL: Setting-up...\n");
2467
2468	/* Designate a single TG in the group as a master.
2469	 * Since HW doesn't care which one, we always assign
2470	 * the 1st one in the group. */
2471	gsl_params.gsl_group = 0;
2472	gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst;
2473
2474	for (i = 0; i < group_size; i++)
2475		grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
2476					grouped_pipes[i]->stream_res.tg, &gsl_params);
2477
2478	/* Reset slave controllers on master VSync */
2479	DC_SYNC_INFO("GSL: enabling trigger-reset\n");
2480
2481	for (i = 1 /* skip the master */; i < group_size; i++)
2482		grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
2483				grouped_pipes[i]->stream_res.tg,
2484				gsl_params.gsl_group);
2485
2486	for (i = 1 /* skip the master */; i < group_size; i++) {
2487		DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
2488		wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
2489		grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
2490				grouped_pipes[i]->stream_res.tg);
2491	}
2492
2493	/* GSL Vblank synchronization is a one time sync mechanism, assumption
2494	 * is that the sync'ed displays will not drift out of sync over time*/
2495	DC_SYNC_INFO("GSL: Restoring register states.\n");
2496	for (i = 0; i < group_size; i++)
2497		grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
2498
2499	DC_SYNC_INFO("GSL: Set-up complete.\n");
2500}
2501
2502static void dce110_enable_per_frame_crtc_position_reset(
2503		struct dc *dc,
2504		int group_size,
2505		struct pipe_ctx *grouped_pipes[])
2506{
2507	struct dc_context *dc_ctx = dc->ctx;
2508	struct dcp_gsl_params gsl_params = { 0 };
2509	int i;
2510
2511	gsl_params.gsl_group = 0;
2512	gsl_params.gsl_master = 0;
2513
2514	for (i = 0; i < group_size; i++)
2515		grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
2516					grouped_pipes[i]->stream_res.tg, &gsl_params);
2517
2518	DC_SYNC_INFO("GSL: enabling trigger-reset\n");
2519
2520	for (i = 1; i < group_size; i++)
2521		grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
2522				grouped_pipes[i]->stream_res.tg,
2523				gsl_params.gsl_master,
2524				&grouped_pipes[i]->stream->triggered_crtc_reset);
2525
2526	DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
2527	for (i = 1; i < group_size; i++)
2528		wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
2529
2530	for (i = 0; i < group_size; i++)
2531		grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
2532
2533}
2534
2535static void init_pipes(struct dc *dc, struct dc_state *context)
2536{
2537	// Do nothing
2538}
2539
2540static void init_hw(struct dc *dc)
2541{
2542	int i;
2543	struct dc_bios *bp;
2544	struct transform *xfm;
2545	struct abm *abm;
2546	struct dmcu *dmcu;
2547	struct dce_hwseq *hws = dc->hwseq;
2548	uint32_t backlight = MAX_BACKLIGHT_LEVEL;
2549
2550	bp = dc->ctx->dc_bios;
2551	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2552		xfm = dc->res_pool->transforms[i];
2553		xfm->funcs->transform_reset(xfm);
2554
2555		hws->funcs.enable_display_power_gating(
2556				dc, i, bp,
2557				PIPE_GATING_CONTROL_INIT);
2558		hws->funcs.enable_display_power_gating(
2559				dc, i, bp,
2560				PIPE_GATING_CONTROL_DISABLE);
2561		hws->funcs.enable_display_pipe_clock_gating(
2562			dc->ctx,
2563			true);
2564	}
2565
2566	dce_clock_gating_power_up(dc->hwseq, false);
2567	/***************************************/
2568
2569	for (i = 0; i < dc->link_count; i++) {
2570		/****************************************/
2571		/* Power up AND update implementation according to the
2572		 * required signal (which may be different from the
2573		 * default signal on connector). */
2574		struct dc_link *link = dc->links[i];
2575
2576		link->link_enc->funcs->hw_init(link->link_enc);
2577	}
2578
2579	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2580		struct timing_generator *tg = dc->res_pool->timing_generators[i];
2581
2582		tg->funcs->disable_vga(tg);
2583
2584		/* Blank controller using driver code instead of
2585		 * command table. */
2586		tg->funcs->set_blank(tg, true);
2587		hwss_wait_for_blank_complete(tg);
2588	}
2589
2590	for (i = 0; i < dc->res_pool->audio_count; i++) {
2591		struct audio *audio = dc->res_pool->audios[i];
2592		audio->funcs->hw_init(audio);
2593	}
2594
2595	for (i = 0; i < dc->link_count; i++) {
2596		struct dc_link *link = dc->links[i];
2597
2598		if (link->panel_cntl)
2599			backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
2600	}
2601
2602	abm = dc->res_pool->abm;
2603	if (abm != NULL)
2604		abm->funcs->abm_init(abm, backlight);
2605
2606	dmcu = dc->res_pool->dmcu;
2607	if (dmcu != NULL && abm != NULL)
2608		abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
2609
2610	if (dc->fbc_compressor)
2611		dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
2612
2613}
2614
2615
2616void dce110_prepare_bandwidth(
2617		struct dc *dc,
2618		struct dc_state *context)
2619{
2620	struct clk_mgr *dccg = dc->clk_mgr;
2621
2622	dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
2623
2624	dccg->funcs->update_clocks(
2625			dccg,
2626			context,
2627			false);
2628}
2629
2630void dce110_optimize_bandwidth(
2631		struct dc *dc,
2632		struct dc_state *context)
2633{
2634	struct clk_mgr *dccg = dc->clk_mgr;
2635
2636	dce110_set_displaymarks(dc, context);
2637
2638	dccg->funcs->update_clocks(
2639			dccg,
2640			context,
2641			true);
2642}
2643
2644static void dce110_program_front_end_for_pipe(
2645		struct dc *dc, struct pipe_ctx *pipe_ctx)
2646{
2647	struct mem_input *mi = pipe_ctx->plane_res.mi;
2648	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2649	struct xfm_grph_csc_adjustment adjust;
2650	struct out_csc_color_matrix tbl_entry;
2651	unsigned int i;
2652	struct dce_hwseq *hws = dc->hwseq;
2653
2654	DC_LOGGER_INIT();
2655	memset(&tbl_entry, 0, sizeof(tbl_entry));
2656
2657	memset(&adjust, 0, sizeof(adjust));
2658	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
2659
2660	dce_enable_fe_clock(dc->hwseq, mi->inst, true);
2661
2662	set_default_colors(pipe_ctx);
2663	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
2664			== true) {
2665		tbl_entry.color_space =
2666			pipe_ctx->stream->output_color_space;
2667
2668		for (i = 0; i < 12; i++)
2669			tbl_entry.regval[i] =
2670			pipe_ctx->stream->csc_color_matrix.matrix[i];
2671
2672		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
2673				(pipe_ctx->plane_res.xfm, &tbl_entry);
2674	}
2675
2676	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
2677		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
2678
2679		for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
2680			adjust.temperature_matrix[i] =
2681				pipe_ctx->stream->gamut_remap_matrix.matrix[i];
2682	}
2683
2684	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
2685
2686	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
2687
2688	program_scaler(dc, pipe_ctx);
2689
2690	mi->funcs->mem_input_program_surface_config(
2691			mi,
2692			plane_state->format,
2693			&plane_state->tiling_info,
2694			&plane_state->plane_size,
2695			plane_state->rotation,
2696			NULL,
2697			false);
2698	if (mi->funcs->set_blank)
2699		mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
2700
2701	if (dc->config.gpu_vm_support)
2702		mi->funcs->mem_input_program_pte_vm(
2703				pipe_ctx->plane_res.mi,
2704				plane_state->format,
2705				&plane_state->tiling_info,
2706				plane_state->rotation);
2707
2708	/* Moved programming gamma from dc to hwss */
2709	if (pipe_ctx->plane_state->update_flags.bits.full_update ||
2710			pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
2711			pipe_ctx->plane_state->update_flags.bits.gamma_change)
2712		hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
2713
2714	if (pipe_ctx->plane_state->update_flags.bits.full_update)
2715		hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
2716
2717	DC_LOG_SURFACE(
2718			"Pipe:%d %p: addr hi:0x%x, "
2719			"addr low:0x%x, "
2720			"src: %d, %d, %d,"
2721			" %d; dst: %d, %d, %d, %d;"
2722			"clip: %d, %d, %d, %d\n",
2723			pipe_ctx->pipe_idx,
2724			(void *) pipe_ctx->plane_state,
2725			pipe_ctx->plane_state->address.grph.addr.high_part,
2726			pipe_ctx->plane_state->address.grph.addr.low_part,
2727			pipe_ctx->plane_state->src_rect.x,
2728			pipe_ctx->plane_state->src_rect.y,
2729			pipe_ctx->plane_state->src_rect.width,
2730			pipe_ctx->plane_state->src_rect.height,
2731			pipe_ctx->plane_state->dst_rect.x,
2732			pipe_ctx->plane_state->dst_rect.y,
2733			pipe_ctx->plane_state->dst_rect.width,
2734			pipe_ctx->plane_state->dst_rect.height,
2735			pipe_ctx->plane_state->clip_rect.x,
2736			pipe_ctx->plane_state->clip_rect.y,
2737			pipe_ctx->plane_state->clip_rect.width,
2738			pipe_ctx->plane_state->clip_rect.height);
2739
2740	DC_LOG_SURFACE(
2741			"Pipe %d: width, height, x, y\n"
2742			"viewport:%d, %d, %d, %d\n"
2743			"recout:  %d, %d, %d, %d\n",
2744			pipe_ctx->pipe_idx,
2745			pipe_ctx->plane_res.scl_data.viewport.width,
2746			pipe_ctx->plane_res.scl_data.viewport.height,
2747			pipe_ctx->plane_res.scl_data.viewport.x,
2748			pipe_ctx->plane_res.scl_data.viewport.y,
2749			pipe_ctx->plane_res.scl_data.recout.width,
2750			pipe_ctx->plane_res.scl_data.recout.height,
2751			pipe_ctx->plane_res.scl_data.recout.x,
2752			pipe_ctx->plane_res.scl_data.recout.y);
2753}
2754
2755static void dce110_apply_ctx_for_surface(
2756		struct dc *dc,
2757		const struct dc_stream_state *stream,
2758		int num_planes,
2759		struct dc_state *context)
2760{
2761	int i;
2762
2763	if (num_planes == 0)
2764		return;
2765
2766	if (dc->fbc_compressor)
2767		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
2768
2769	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2770		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2771
2772		if (pipe_ctx->stream != stream)
2773			continue;
2774
2775		/* Need to allocate mem before program front end for Fiji */
2776		pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
2777				pipe_ctx->plane_res.mi,
2778				pipe_ctx->stream->timing.h_total,
2779				pipe_ctx->stream->timing.v_total,
2780				pipe_ctx->stream->timing.pix_clk_100hz / 10,
2781				context->stream_count);
2782
2783		dce110_program_front_end_for_pipe(dc, pipe_ctx);
2784
2785		dc->hwss.update_plane_addr(dc, pipe_ctx);
2786
2787		program_surface_visibility(dc, pipe_ctx);
2788
2789	}
2790
2791	if (dc->fbc_compressor)
2792		enable_fbc(dc, context);
2793}
2794
2795static void dce110_post_unlock_program_front_end(
2796		struct dc *dc,
2797		struct dc_state *context)
2798{
2799}
2800
2801static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
2802{
2803	struct dce_hwseq *hws = dc->hwseq;
2804	int fe_idx = pipe_ctx->plane_res.mi ?
2805		pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
2806
2807	/* Do not power down fe when stream is active on dce*/
2808	if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
2809		return;
2810
2811	hws->funcs.enable_display_power_gating(
2812		dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
2813
2814	dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
2815				dc->res_pool->transforms[fe_idx]);
2816}
2817
2818static void dce110_wait_for_mpcc_disconnect(
2819		struct dc *dc,
2820		struct resource_pool *res_pool,
2821		struct pipe_ctx *pipe_ctx)
2822{
2823	/* do nothing*/
2824}
2825
2826static void program_output_csc(struct dc *dc,
2827		struct pipe_ctx *pipe_ctx,
2828		enum dc_color_space colorspace,
2829		uint16_t *matrix,
2830		int opp_id)
2831{
2832	int i;
2833	struct out_csc_color_matrix tbl_entry;
2834
2835	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
2836		enum dc_color_space color_space = pipe_ctx->stream->output_color_space;
2837
2838		for (i = 0; i < 12; i++)
2839			tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
2840
2841		tbl_entry.color_space = color_space;
2842
2843		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
2844				pipe_ctx->plane_res.xfm, &tbl_entry);
2845	}
2846}
2847
2848static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
2849{
2850	struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
2851	struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
2852	struct mem_input *mi = pipe_ctx->plane_res.mi;
2853	struct dc_cursor_mi_param param = {
2854		.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
2855		.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz,
2856		.viewport = pipe_ctx->plane_res.scl_data.viewport,
2857		.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
2858		.v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
2859		.rotation = pipe_ctx->plane_state->rotation,
2860		.mirror = pipe_ctx->plane_state->horizontal_mirror
2861	};
2862
2863	/**
2864	 * If the cursor's source viewport is clipped then we need to
2865	 * translate the cursor to appear in the correct position on
2866	 * the screen.
2867	 *
2868	 * This translation isn't affected by scaling so it needs to be
2869	 * done *after* we adjust the position for the scale factor.
2870	 *
2871	 * This is only done by opt-in for now since there are still
2872	 * some usecases like tiled display that might enable the
2873	 * cursor on both streams while expecting dc to clip it.
2874	 */
2875	if (pos_cpy.translate_by_source) {
2876		pos_cpy.x += pipe_ctx->plane_state->src_rect.x;
2877		pos_cpy.y += pipe_ctx->plane_state->src_rect.y;
2878	}
2879
2880	if (pipe_ctx->plane_state->address.type
2881			== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
2882		pos_cpy.enable = false;
2883
2884	if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
2885		pos_cpy.enable = false;
2886
2887	if (ipp->funcs->ipp_cursor_set_position)
2888		ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
2889	if (mi->funcs->set_cursor_position)
2890		mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
2891}
2892
2893static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
2894{
2895	struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
2896
2897	if (pipe_ctx->plane_res.ipp &&
2898	    pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
2899		pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
2900				pipe_ctx->plane_res.ipp, attributes);
2901
2902	if (pipe_ctx->plane_res.mi &&
2903	    pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
2904		pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
2905				pipe_ctx->plane_res.mi, attributes);
2906
2907	if (pipe_ctx->plane_res.xfm &&
2908	    pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
2909		pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
2910				pipe_ctx->plane_res.xfm, attributes);
2911}
2912
2913bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
2914		uint32_t backlight_pwm_u16_16,
2915		uint32_t frame_ramp)
2916{
2917	struct dc_link *link = pipe_ctx->stream->link;
2918	struct dc  *dc = link->ctx->dc;
2919	struct abm *abm = pipe_ctx->stream_res.abm;
2920	struct panel_cntl *panel_cntl = link->panel_cntl;
2921	struct dmcu *dmcu = dc->res_pool->dmcu;
2922	bool fw_set_brightness = true;
2923	/* DMCU -1 for all controller id values,
2924	 * therefore +1 here
2925	 */
2926	uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
2927
2928	if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
2929		return false;
2930
2931	if (dmcu)
2932		fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
2933
2934	if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
2935		panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
2936	else
2937		abm->funcs->set_backlight_level_pwm(
2938				abm,
2939				backlight_pwm_u16_16,
2940				frame_ramp,
2941				controller_id,
2942				link->panel_cntl->inst);
2943
2944	return true;
2945}
2946
2947void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
2948{
2949	struct abm *abm = pipe_ctx->stream_res.abm;
2950	struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
2951
2952	if (abm)
2953		abm->funcs->set_abm_immediate_disable(abm,
2954				pipe_ctx->stream->link->panel_cntl->inst);
2955
2956	if (panel_cntl)
2957		panel_cntl->funcs->store_backlight_level(panel_cntl);
2958}
2959
2960void dce110_set_pipe(struct pipe_ctx *pipe_ctx)
2961{
2962	struct abm *abm = pipe_ctx->stream_res.abm;
2963	struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
2964	uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1;
2965
2966	if (abm && panel_cntl)
2967		abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst);
2968}
2969
2970void dce110_enable_lvds_link_output(struct dc_link *link,
2971		const struct link_resource *link_res,
2972		enum clock_source_id clock_source,
2973		uint32_t pixel_clock)
2974{
2975	link->link_enc->funcs->enable_lvds_output(
2976			link->link_enc,
2977			clock_source,
2978			pixel_clock);
2979	link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
2980}
2981
2982void dce110_enable_tmds_link_output(struct dc_link *link,
2983		const struct link_resource *link_res,
2984		enum signal_type signal,
2985		enum clock_source_id clock_source,
2986		enum dc_color_depth color_depth,
2987		uint32_t pixel_clock)
2988{
2989	link->link_enc->funcs->enable_tmds_output(
2990			link->link_enc,
2991			clock_source,
2992			color_depth,
2993			signal,
2994			pixel_clock);
2995	link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
2996}
2997
2998void dce110_enable_dp_link_output(
2999		struct dc_link *link,
3000		const struct link_resource *link_res,
3001		enum signal_type signal,
3002		enum clock_source_id clock_source,
3003		const struct dc_link_settings *link_settings)
3004{
3005	struct dc  *dc = link->ctx->dc;
3006	struct dmcu *dmcu = dc->res_pool->dmcu;
3007	struct pipe_ctx *pipes =
3008			link->dc->current_state->res_ctx.pipe_ctx;
3009	struct clock_source *dp_cs =
3010			link->dc->res_pool->dp_clock_source;
3011	const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
3012	unsigned int i;
3013
3014
3015	if (link->connector_signal == SIGNAL_TYPE_EDP) {
3016		if (!link->dc->config.edp_no_power_sequencing)
3017			link->dc->hwss.edp_power_control(link, true);
3018		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
3019	}
3020
3021	/* If the current pixel clock source is not DTO(happens after
3022	 * switching from HDMI passive dongle to DP on the same connector),
3023	 * switch the pixel clock source to DTO.
3024	 */
3025
3026	for (i = 0; i < MAX_PIPES; i++) {
3027		if (pipes[i].stream != NULL &&
3028				pipes[i].stream->link == link) {
3029			if (pipes[i].clock_source != NULL &&
3030					pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
3031				pipes[i].clock_source = dp_cs;
3032				pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
3033						pipes[i].stream->timing.pix_clk_100hz;
3034				pipes[i].clock_source->funcs->program_pix_clk(
3035						pipes[i].clock_source,
3036						&pipes[i].stream_res.pix_clk_params,
3037						dp_get_link_encoding_format(link_settings),
3038						&pipes[i].pll_settings);
3039			}
3040		}
3041	}
3042
3043	if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
3044		if (dc->clk_mgr->funcs->notify_link_rate_change)
3045			dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
3046	}
3047
3048	if (dmcu != NULL && dmcu->funcs->lock_phy)
3049		dmcu->funcs->lock_phy(dmcu);
3050
3051	if (link_hwss->ext.enable_dp_link_output)
3052		link_hwss->ext.enable_dp_link_output(link, link_res, signal,
3053				clock_source, link_settings);
3054
3055	link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
3056
3057	if (dmcu != NULL && dmcu->funcs->unlock_phy)
3058		dmcu->funcs->unlock_phy(dmcu);
3059
3060	dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
3061}
3062
3063void dce110_disable_link_output(struct dc_link *link,
3064		const struct link_resource *link_res,
3065		enum signal_type signal)
3066{
3067	struct dc *dc = link->ctx->dc;
3068	const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
3069	struct dmcu *dmcu = dc->res_pool->dmcu;
3070
3071	if (signal == SIGNAL_TYPE_EDP &&
3072			link->dc->hwss.edp_backlight_control)
3073		link->dc->hwss.edp_backlight_control(link, false);
3074	else if (dmcu != NULL && dmcu->funcs->lock_phy)
3075		dmcu->funcs->lock_phy(dmcu);
3076
3077	link_hwss->disable_link_output(link, link_res, signal);
3078	link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
3079
3080	if (signal == SIGNAL_TYPE_EDP &&
3081			link->dc->hwss.edp_backlight_control)
3082		link->dc->hwss.edp_power_control(link, false);
3083	else if (dmcu != NULL && dmcu->funcs->lock_phy)
3084		dmcu->funcs->unlock_phy(dmcu);
3085	dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
3086}
3087
3088static const struct hw_sequencer_funcs dce110_funcs = {
3089	.program_gamut_remap = program_gamut_remap,
3090	.program_output_csc = program_output_csc,
3091	.init_hw = init_hw,
3092	.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
3093	.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
3094	.post_unlock_program_front_end = dce110_post_unlock_program_front_end,
3095	.update_plane_addr = update_plane_addr,
3096	.update_pending_status = dce110_update_pending_status,
3097	.enable_accelerated_mode = dce110_enable_accelerated_mode,
3098	.enable_timing_synchronization = dce110_enable_timing_synchronization,
3099	.enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
3100	.update_info_frame = dce110_update_info_frame,
3101	.enable_stream = dce110_enable_stream,
3102	.disable_stream = dce110_disable_stream,
3103	.unblank_stream = dce110_unblank_stream,
3104	.blank_stream = dce110_blank_stream,
3105	.enable_audio_stream = dce110_enable_audio_stream,
3106	.disable_audio_stream = dce110_disable_audio_stream,
3107	.disable_plane = dce110_power_down_fe,
3108	.pipe_control_lock = dce_pipe_control_lock,
3109	.interdependent_update_lock = NULL,
3110	.cursor_lock = dce_pipe_control_lock,
3111	.prepare_bandwidth = dce110_prepare_bandwidth,
3112	.optimize_bandwidth = dce110_optimize_bandwidth,
3113	.set_drr = set_drr,
3114	.get_position = get_position,
3115	.set_static_screen_control = set_static_screen_control,
3116	.setup_stereo = NULL,
3117	.set_avmute = dce110_set_avmute,
3118	.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
3119	.edp_backlight_control = dce110_edp_backlight_control,
3120	.edp_power_control = dce110_edp_power_control,
3121	.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
3122	.set_cursor_position = dce110_set_cursor_position,
3123	.set_cursor_attribute = dce110_set_cursor_attribute,
3124	.set_backlight_level = dce110_set_backlight_level,
3125	.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
3126	.set_pipe = dce110_set_pipe,
3127	.enable_lvds_link_output = dce110_enable_lvds_link_output,
3128	.enable_tmds_link_output = dce110_enable_tmds_link_output,
3129	.enable_dp_link_output = dce110_enable_dp_link_output,
3130	.disable_link_output = dce110_disable_link_output,
3131};
3132
3133static const struct hwseq_private_funcs dce110_private_funcs = {
3134	.init_pipes = init_pipes,
3135	.update_plane_addr = update_plane_addr,
3136	.set_input_transfer_func = dce110_set_input_transfer_func,
3137	.set_output_transfer_func = dce110_set_output_transfer_func,
3138	.power_down = dce110_power_down,
3139	.enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
3140	.enable_display_power_gating = dce110_enable_display_power_gating,
3141	.reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
3142	.enable_stream_timing = dce110_enable_stream_timing,
3143	.disable_stream_gating = NULL,
3144	.enable_stream_gating = NULL,
3145	.edp_backlight_control = dce110_edp_backlight_control,
3146};
3147
3148void dce110_hw_sequencer_construct(struct dc *dc)
3149{
3150	dc->hwss = dce110_funcs;
3151	dc->hwseq->funcs = dce110_private_funcs;
3152}
3153