cachepc-linux

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

dce110_hw_sequencer.c (88654B)


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