14562236bSHarry Wentland /*
24562236bSHarry Wentland  * Copyright 2015 Advanced Micro Devices, Inc.
34562236bSHarry Wentland  *
44562236bSHarry Wentland  * Permission is hereby granted, free of charge, to any person obtaining a
54562236bSHarry Wentland  * copy of this software and associated documentation files (the "Software"),
64562236bSHarry Wentland  * to deal in the Software without restriction, including without limitation
74562236bSHarry Wentland  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84562236bSHarry Wentland  * and/or sell copies of the Software, and to permit persons to whom the
94562236bSHarry Wentland  * Software is furnished to do so, subject to the following conditions:
104562236bSHarry Wentland  *
114562236bSHarry Wentland  * The above copyright notice and this permission notice shall be included in
124562236bSHarry Wentland  * all copies or substantial portions of the Software.
134562236bSHarry Wentland  *
144562236bSHarry Wentland  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154562236bSHarry Wentland  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164562236bSHarry Wentland  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
174562236bSHarry Wentland  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
184562236bSHarry Wentland  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
194562236bSHarry Wentland  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
204562236bSHarry Wentland  * OTHER DEALINGS IN THE SOFTWARE.
214562236bSHarry Wentland  *
224562236bSHarry Wentland  * Authors: AMD
234562236bSHarry Wentland  *
244562236bSHarry Wentland  */
254562236bSHarry Wentland #include "dm_services.h"
264562236bSHarry Wentland #include "dc.h"
274562236bSHarry Wentland #include "dc_bios_types.h"
284562236bSHarry Wentland #include "core_types.h"
294562236bSHarry Wentland #include "core_status.h"
304562236bSHarry Wentland #include "resource.h"
314562236bSHarry Wentland #include "dm_helpers.h"
324562236bSHarry Wentland #include "dce110_hw_sequencer.h"
334562236bSHarry Wentland #include "dce110_timing_generator.h"
3498489c02SLeo (Sunpeng) Li #include "dce/dce_hwseq.h"
3587401969SAndrew Jiang #include "gpio_service_interface.h"
364562236bSHarry Wentland 
373eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
381663ae1cSBhawanpreet Lakha #include "dce110_compressor.h"
391663ae1cSBhawanpreet Lakha #endif
401663ae1cSBhawanpreet Lakha 
414562236bSHarry Wentland #include "bios/bios_parser_helper.h"
424562236bSHarry Wentland #include "timing_generator.h"
434562236bSHarry Wentland #include "mem_input.h"
444562236bSHarry Wentland #include "opp.h"
454562236bSHarry Wentland #include "ipp.h"
464562236bSHarry Wentland #include "transform.h"
474562236bSHarry Wentland #include "stream_encoder.h"
484562236bSHarry Wentland #include "link_encoder.h"
4987401969SAndrew Jiang #include "link_hwss.h"
504562236bSHarry Wentland #include "clock_source.h"
515e7773a2SAnthony Koo #include "abm.h"
524562236bSHarry Wentland #include "audio.h"
5308b16886SZeyu Fan #include "reg_helper.h"
544562236bSHarry Wentland 
554562236bSHarry Wentland /* include DCE11 register header files */
564562236bSHarry Wentland #include "dce/dce_11_0_d.h"
574562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h"
58e266fdf6SVitaly Prosyak #include "custom_float.h"
594562236bSHarry Wentland 
6087401969SAndrew Jiang /*
6187401969SAndrew Jiang  * All values are in milliseconds;
6287401969SAndrew Jiang  * For eDP, after power-up/power/down,
6387401969SAndrew Jiang  * 300/500 msec max. delay from LCDVCC to black video generation
6487401969SAndrew Jiang  */
6587401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300
6687401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500
6787401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10
6887401969SAndrew Jiang 
695eefbc40SYue Hin Lau #define CTX \
705eefbc40SYue Hin Lau 	hws->ctx
715eefbc40SYue Hin Lau #define REG(reg)\
725eefbc40SYue Hin Lau 	hws->regs->reg
735eefbc40SYue Hin Lau 
745eefbc40SYue Hin Lau #undef FN
755eefbc40SYue Hin Lau #define FN(reg_name, field_name) \
765eefbc40SYue Hin Lau 	hws->shifts->field_name, hws->masks->field_name
775eefbc40SYue Hin Lau 
784562236bSHarry Wentland struct dce110_hw_seq_reg_offsets {
794562236bSHarry Wentland 	uint32_t crtc;
804562236bSHarry Wentland };
814562236bSHarry Wentland 
824562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
834562236bSHarry Wentland {
844562236bSHarry Wentland 	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
854562236bSHarry Wentland },
864562236bSHarry Wentland {
874562236bSHarry Wentland 	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
884562236bSHarry Wentland },
894562236bSHarry Wentland {
904562236bSHarry Wentland 	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
914562236bSHarry Wentland },
924562236bSHarry Wentland {
934562236bSHarry Wentland 	.crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL),
944562236bSHarry Wentland }
954562236bSHarry Wentland };
964562236bSHarry Wentland 
974562236bSHarry Wentland #define HW_REG_BLND(reg, id)\
984562236bSHarry Wentland 	(reg + reg_offsets[id].blnd)
994562236bSHarry Wentland 
1004562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\
1014562236bSHarry Wentland 	(reg + reg_offsets[id].crtc)
1024562236bSHarry Wentland 
1034562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF
1044562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF
1054562236bSHarry Wentland 
1064562236bSHarry Wentland /*******************************************************************************
1074562236bSHarry Wentland  * Private definitions
1084562236bSHarry Wentland  ******************************************************************************/
1094562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/
1104562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx)
1114562236bSHarry Wentland {
1124562236bSHarry Wentland 	uint32_t addr;
1134562236bSHarry Wentland 	uint32_t value = 0;
1144562236bSHarry Wentland 	uint32_t chunk_int = 0;
1154562236bSHarry Wentland 	uint32_t chunk_mul = 0;
1164562236bSHarry Wentland 
1174562236bSHarry Wentland 	addr = mmUNP_DVMM_PTE_CONTROL;
1184562236bSHarry Wentland 	value = dm_read_reg(ctx, addr);
1194562236bSHarry Wentland 
1204562236bSHarry Wentland 	set_reg_field_value(
1214562236bSHarry Wentland 		value,
1224562236bSHarry Wentland 		0,
1234562236bSHarry Wentland 		DVMM_PTE_CONTROL,
1244562236bSHarry Wentland 		DVMM_USE_SINGLE_PTE);
1254562236bSHarry Wentland 
1264562236bSHarry Wentland 	set_reg_field_value(
1274562236bSHarry Wentland 		value,
1284562236bSHarry Wentland 		1,
1294562236bSHarry Wentland 		DVMM_PTE_CONTROL,
1304562236bSHarry Wentland 		DVMM_PTE_BUFFER_MODE0);
1314562236bSHarry Wentland 
1324562236bSHarry Wentland 	set_reg_field_value(
1334562236bSHarry Wentland 		value,
1344562236bSHarry Wentland 		1,
1354562236bSHarry Wentland 		DVMM_PTE_CONTROL,
1364562236bSHarry Wentland 		DVMM_PTE_BUFFER_MODE1);
1374562236bSHarry Wentland 
1384562236bSHarry Wentland 	dm_write_reg(ctx, addr, value);
1394562236bSHarry Wentland 
1404562236bSHarry Wentland 	addr = mmDVMM_PTE_REQ;
1414562236bSHarry Wentland 	value = dm_read_reg(ctx, addr);
1424562236bSHarry Wentland 
1434562236bSHarry Wentland 	chunk_int = get_reg_field_value(
1444562236bSHarry Wentland 		value,
1454562236bSHarry Wentland 		DVMM_PTE_REQ,
1464562236bSHarry Wentland 		HFLIP_PTEREQ_PER_CHUNK_INT);
1474562236bSHarry Wentland 
1484562236bSHarry Wentland 	chunk_mul = get_reg_field_value(
1494562236bSHarry Wentland 		value,
1504562236bSHarry Wentland 		DVMM_PTE_REQ,
1514562236bSHarry Wentland 		HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
1524562236bSHarry Wentland 
1534562236bSHarry Wentland 	if (chunk_int != 0x4 || chunk_mul != 0x4) {
1544562236bSHarry Wentland 
1554562236bSHarry Wentland 		set_reg_field_value(
1564562236bSHarry Wentland 			value,
1574562236bSHarry Wentland 			255,
1584562236bSHarry Wentland 			DVMM_PTE_REQ,
1594562236bSHarry Wentland 			MAX_PTEREQ_TO_ISSUE);
1604562236bSHarry Wentland 
1614562236bSHarry Wentland 		set_reg_field_value(
1624562236bSHarry Wentland 			value,
1634562236bSHarry Wentland 			4,
1644562236bSHarry Wentland 			DVMM_PTE_REQ,
1654562236bSHarry Wentland 			HFLIP_PTEREQ_PER_CHUNK_INT);
1664562236bSHarry Wentland 
1674562236bSHarry Wentland 		set_reg_field_value(
1684562236bSHarry Wentland 			value,
1694562236bSHarry Wentland 			4,
1704562236bSHarry Wentland 			DVMM_PTE_REQ,
1714562236bSHarry Wentland 			HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
1724562236bSHarry Wentland 
1734562236bSHarry Wentland 		dm_write_reg(ctx, addr, value);
1744562236bSHarry Wentland 	}
1754562236bSHarry Wentland }
1764562236bSHarry Wentland /**************************************************************************/
1774562236bSHarry Wentland 
1784562236bSHarry Wentland static void enable_display_pipe_clock_gating(
1794562236bSHarry Wentland 	struct dc_context *ctx,
1804562236bSHarry Wentland 	bool clock_gating)
1814562236bSHarry Wentland {
1824562236bSHarry Wentland 	/*TODO*/
1834562236bSHarry Wentland }
1844562236bSHarry Wentland 
1854562236bSHarry Wentland static bool dce110_enable_display_power_gating(
186fb3466a4SBhawanpreet Lakha 	struct dc *dc,
1874562236bSHarry Wentland 	uint8_t controller_id,
1884562236bSHarry Wentland 	struct dc_bios *dcb,
1894562236bSHarry Wentland 	enum pipe_gating_control power_gating)
1904562236bSHarry Wentland {
1914562236bSHarry Wentland 	enum bp_result bp_result = BP_RESULT_OK;
1924562236bSHarry Wentland 	enum bp_pipe_control_action cntl;
1934562236bSHarry Wentland 	struct dc_context *ctx = dc->ctx;
1944562236bSHarry Wentland 	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
1954562236bSHarry Wentland 
1964562236bSHarry Wentland 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
1974562236bSHarry Wentland 		return true;
1984562236bSHarry Wentland 
1994562236bSHarry Wentland 	if (power_gating == PIPE_GATING_CONTROL_INIT)
2004562236bSHarry Wentland 		cntl = ASIC_PIPE_INIT;
2014562236bSHarry Wentland 	else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
2024562236bSHarry Wentland 		cntl = ASIC_PIPE_ENABLE;
2034562236bSHarry Wentland 	else
2044562236bSHarry Wentland 		cntl = ASIC_PIPE_DISABLE;
2054562236bSHarry Wentland 
2064562236bSHarry Wentland 	if (controller_id == underlay_idx)
2074562236bSHarry Wentland 		controller_id = CONTROLLER_ID_UNDERLAY0 - 1;
2084562236bSHarry Wentland 
2094562236bSHarry Wentland 	if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){
2104562236bSHarry Wentland 
2114562236bSHarry Wentland 		bp_result = dcb->funcs->enable_disp_power_gating(
2124562236bSHarry Wentland 						dcb, controller_id + 1, cntl);
2134562236bSHarry Wentland 
2144562236bSHarry Wentland 		/* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
2154562236bSHarry Wentland 		 * by default when command table is called
2164562236bSHarry Wentland 		 *
2174562236bSHarry Wentland 		 * Bios parser accepts controller_id = 6 as indicative of
2184562236bSHarry Wentland 		 * underlay pipe in dce110. But we do not support more
2194562236bSHarry Wentland 		 * than 3.
2204562236bSHarry Wentland 		 */
2214562236bSHarry Wentland 		if (controller_id < CONTROLLER_ID_MAX - 1)
2224562236bSHarry Wentland 			dm_write_reg(ctx,
2234562236bSHarry Wentland 				HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
2244562236bSHarry Wentland 				0);
2254562236bSHarry Wentland 	}
2264562236bSHarry Wentland 
2274562236bSHarry Wentland 	if (power_gating != PIPE_GATING_CONTROL_ENABLE)
2284562236bSHarry Wentland 		dce110_init_pte(ctx);
2294562236bSHarry Wentland 
2304562236bSHarry Wentland 	if (bp_result == BP_RESULT_OK)
2314562236bSHarry Wentland 		return true;
2324562236bSHarry Wentland 	else
2334562236bSHarry Wentland 		return false;
2344562236bSHarry Wentland }
2354562236bSHarry Wentland 
2364562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params,
2373be5262eSHarry Wentland 		const struct dc_plane_state *plane_state)
2384562236bSHarry Wentland {
2394562236bSHarry Wentland 	prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
2404562236bSHarry Wentland 
2413be5262eSHarry Wentland 	switch (plane_state->format) {
2424562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2438693049aSTony Cheng 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2444562236bSHarry Wentland 		prescale_params->scale = 0x2020;
2454562236bSHarry Wentland 		break;
2464562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2474562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2484562236bSHarry Wentland 		prescale_params->scale = 0x2008;
2494562236bSHarry Wentland 		break;
2504562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2514562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2524562236bSHarry Wentland 		prescale_params->scale = 0x2000;
2534562236bSHarry Wentland 		break;
2544562236bSHarry Wentland 	default:
2554562236bSHarry Wentland 		ASSERT(false);
256d7194cf6SAric Cyr 		break;
2574562236bSHarry Wentland 	}
2584562236bSHarry Wentland }
2594562236bSHarry Wentland 
260d7194cf6SAric Cyr static bool dce110_set_input_transfer_func(
261fb735a9fSAnthony Koo 	struct pipe_ctx *pipe_ctx,
2623be5262eSHarry Wentland 	const struct dc_plane_state *plane_state)
2634562236bSHarry Wentland {
26486a66c4eSHarry Wentland 	struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
2657b0c470fSLeo (Sunpeng) Li 	const struct dc_transfer_func *tf = NULL;
26690e508baSAnthony Koo 	struct ipp_prescale_params prescale_params = { 0 };
26790e508baSAnthony Koo 	bool result = true;
26890e508baSAnthony Koo 
26990e508baSAnthony Koo 	if (ipp == NULL)
27090e508baSAnthony Koo 		return false;
27190e508baSAnthony Koo 
2723be5262eSHarry Wentland 	if (plane_state->in_transfer_func)
2733be5262eSHarry Wentland 		tf = plane_state->in_transfer_func;
27490e508baSAnthony Koo 
2753be5262eSHarry Wentland 	build_prescale_params(&prescale_params, plane_state);
27690e508baSAnthony Koo 	ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
27790e508baSAnthony Koo 
2783be5262eSHarry Wentland 	if (plane_state->gamma_correction && dce_use_lut(plane_state))
2793be5262eSHarry Wentland 		ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
280d7194cf6SAric Cyr 
28190e508baSAnthony Koo 	if (tf == NULL) {
28290e508baSAnthony Koo 		/* Default case if no input transfer function specified */
28390e508baSAnthony Koo 		ipp->funcs->ipp_set_degamma(ipp,
284306dadf0SAmy Zhang 				IPP_DEGAMMA_MODE_HW_sRGB);
2857b0c470fSLeo (Sunpeng) Li 	} else if (tf->type == TF_TYPE_PREDEFINED) {
2867b0c470fSLeo (Sunpeng) Li 		switch (tf->tf) {
28790e508baSAnthony Koo 		case TRANSFER_FUNCTION_SRGB:
28890e508baSAnthony Koo 			ipp->funcs->ipp_set_degamma(ipp,
28990e508baSAnthony Koo 					IPP_DEGAMMA_MODE_HW_sRGB);
29090e508baSAnthony Koo 			break;
29190e508baSAnthony Koo 		case TRANSFER_FUNCTION_BT709:
29290e508baSAnthony Koo 			ipp->funcs->ipp_set_degamma(ipp,
29390e508baSAnthony Koo 					IPP_DEGAMMA_MODE_HW_xvYCC);
29490e508baSAnthony Koo 			break;
29590e508baSAnthony Koo 		case TRANSFER_FUNCTION_LINEAR:
29690e508baSAnthony Koo 			ipp->funcs->ipp_set_degamma(ipp,
29790e508baSAnthony Koo 					IPP_DEGAMMA_MODE_BYPASS);
29890e508baSAnthony Koo 			break;
29990e508baSAnthony Koo 		case TRANSFER_FUNCTION_PQ:
30090e508baSAnthony Koo 			result = false;
30190e508baSAnthony Koo 			break;
30290e508baSAnthony Koo 		default:
30390e508baSAnthony Koo 			result = false;
304d7194cf6SAric Cyr 			break;
30590e508baSAnthony Koo 		}
3067b0c470fSLeo (Sunpeng) Li 	} else if (tf->type == TF_TYPE_BYPASS) {
30770063a59SAmy Zhang 		ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
30890e508baSAnthony Koo 	} else {
30990e508baSAnthony Koo 		/*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
31090e508baSAnthony Koo 		result = false;
31190e508baSAnthony Koo 	}
31290e508baSAnthony Koo 
31390e508baSAnthony Koo 	return result;
31490e508baSAnthony Koo }
31590e508baSAnthony Koo 
316fcd2f4bfSAmy Zhang static bool convert_to_custom_float(
317fcd2f4bfSAmy Zhang 		struct pwl_result_data *rgb_resulted,
318fcd2f4bfSAmy Zhang 		struct curve_points *arr_points,
319fcd2f4bfSAmy Zhang 		uint32_t hw_points_num)
320fcd2f4bfSAmy Zhang {
321fcd2f4bfSAmy Zhang 	struct custom_float_format fmt;
322fcd2f4bfSAmy Zhang 
323fcd2f4bfSAmy Zhang 	struct pwl_result_data *rgb = rgb_resulted;
324fcd2f4bfSAmy Zhang 
325fcd2f4bfSAmy Zhang 	uint32_t i = 0;
326fcd2f4bfSAmy Zhang 
327fcd2f4bfSAmy Zhang 	fmt.exponenta_bits = 6;
328fcd2f4bfSAmy Zhang 	fmt.mantissa_bits = 12;
329fcd2f4bfSAmy Zhang 	fmt.sign = true;
330fcd2f4bfSAmy Zhang 
331fcd2f4bfSAmy Zhang 	if (!convert_to_custom_float_format(
332fcd2f4bfSAmy Zhang 		arr_points[0].x,
333fcd2f4bfSAmy Zhang 		&fmt,
334fcd2f4bfSAmy Zhang 		&arr_points[0].custom_float_x)) {
335fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
336fcd2f4bfSAmy Zhang 		return false;
337fcd2f4bfSAmy Zhang 	}
338fcd2f4bfSAmy Zhang 
339fcd2f4bfSAmy Zhang 	if (!convert_to_custom_float_format(
340fcd2f4bfSAmy Zhang 		arr_points[0].offset,
341fcd2f4bfSAmy Zhang 		&fmt,
342fcd2f4bfSAmy Zhang 		&arr_points[0].custom_float_offset)) {
343fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
344fcd2f4bfSAmy Zhang 		return false;
345fcd2f4bfSAmy Zhang 	}
346fcd2f4bfSAmy Zhang 
347fcd2f4bfSAmy Zhang 	if (!convert_to_custom_float_format(
348fcd2f4bfSAmy Zhang 		arr_points[0].slope,
349fcd2f4bfSAmy Zhang 		&fmt,
350fcd2f4bfSAmy Zhang 		&arr_points[0].custom_float_slope)) {
351fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
352fcd2f4bfSAmy Zhang 		return false;
353fcd2f4bfSAmy Zhang 	}
354fcd2f4bfSAmy Zhang 
355fcd2f4bfSAmy Zhang 	fmt.mantissa_bits = 10;
356fcd2f4bfSAmy Zhang 	fmt.sign = false;
357fcd2f4bfSAmy Zhang 
358fcd2f4bfSAmy Zhang 	if (!convert_to_custom_float_format(
359fcd2f4bfSAmy Zhang 		arr_points[1].x,
360fcd2f4bfSAmy Zhang 		&fmt,
361fcd2f4bfSAmy Zhang 		&arr_points[1].custom_float_x)) {
362fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
363fcd2f4bfSAmy Zhang 		return false;
364fcd2f4bfSAmy Zhang 	}
365fcd2f4bfSAmy Zhang 
366fcd2f4bfSAmy Zhang 	if (!convert_to_custom_float_format(
367fcd2f4bfSAmy Zhang 		arr_points[1].y,
368fcd2f4bfSAmy Zhang 		&fmt,
369fcd2f4bfSAmy Zhang 		&arr_points[1].custom_float_y)) {
370fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
371fcd2f4bfSAmy Zhang 		return false;
372fcd2f4bfSAmy Zhang 	}
373fcd2f4bfSAmy Zhang 
374fcd2f4bfSAmy Zhang 	if (!convert_to_custom_float_format(
375fcd2f4bfSAmy Zhang 		arr_points[2].slope,
376fcd2f4bfSAmy Zhang 		&fmt,
377fcd2f4bfSAmy Zhang 		&arr_points[2].custom_float_slope)) {
378fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
379fcd2f4bfSAmy Zhang 		return false;
380fcd2f4bfSAmy Zhang 	}
381fcd2f4bfSAmy Zhang 
382fcd2f4bfSAmy Zhang 	fmt.mantissa_bits = 12;
383fcd2f4bfSAmy Zhang 	fmt.sign = true;
384fcd2f4bfSAmy Zhang 
385fcd2f4bfSAmy Zhang 	while (i != hw_points_num) {
386fcd2f4bfSAmy Zhang 		if (!convert_to_custom_float_format(
387fcd2f4bfSAmy Zhang 			rgb->red,
388fcd2f4bfSAmy Zhang 			&fmt,
389fcd2f4bfSAmy Zhang 			&rgb->red_reg)) {
390fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
391fcd2f4bfSAmy Zhang 			return false;
392fcd2f4bfSAmy Zhang 		}
393fcd2f4bfSAmy Zhang 
394fcd2f4bfSAmy Zhang 		if (!convert_to_custom_float_format(
395fcd2f4bfSAmy Zhang 			rgb->green,
396fcd2f4bfSAmy Zhang 			&fmt,
397fcd2f4bfSAmy Zhang 			&rgb->green_reg)) {
398fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
399fcd2f4bfSAmy Zhang 			return false;
400fcd2f4bfSAmy Zhang 		}
401fcd2f4bfSAmy Zhang 
402fcd2f4bfSAmy Zhang 		if (!convert_to_custom_float_format(
403fcd2f4bfSAmy Zhang 			rgb->blue,
404fcd2f4bfSAmy Zhang 			&fmt,
405fcd2f4bfSAmy Zhang 			&rgb->blue_reg)) {
406fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
407fcd2f4bfSAmy Zhang 			return false;
408fcd2f4bfSAmy Zhang 		}
409fcd2f4bfSAmy Zhang 
410fcd2f4bfSAmy Zhang 		if (!convert_to_custom_float_format(
411fcd2f4bfSAmy Zhang 			rgb->delta_red,
412fcd2f4bfSAmy Zhang 			&fmt,
413fcd2f4bfSAmy Zhang 			&rgb->delta_red_reg)) {
414fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
415fcd2f4bfSAmy Zhang 			return false;
416fcd2f4bfSAmy Zhang 		}
417fcd2f4bfSAmy Zhang 
418fcd2f4bfSAmy Zhang 		if (!convert_to_custom_float_format(
419fcd2f4bfSAmy Zhang 			rgb->delta_green,
420fcd2f4bfSAmy Zhang 			&fmt,
421fcd2f4bfSAmy Zhang 			&rgb->delta_green_reg)) {
422fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
423fcd2f4bfSAmy Zhang 			return false;
424fcd2f4bfSAmy Zhang 		}
425fcd2f4bfSAmy Zhang 
426fcd2f4bfSAmy Zhang 		if (!convert_to_custom_float_format(
427fcd2f4bfSAmy Zhang 			rgb->delta_blue,
428fcd2f4bfSAmy Zhang 			&fmt,
429fcd2f4bfSAmy Zhang 			&rgb->delta_blue_reg)) {
430fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
431fcd2f4bfSAmy Zhang 			return false;
432fcd2f4bfSAmy Zhang 		}
433fcd2f4bfSAmy Zhang 
434fcd2f4bfSAmy Zhang 		++rgb;
435fcd2f4bfSAmy Zhang 		++i;
436fcd2f4bfSAmy Zhang 	}
437fcd2f4bfSAmy Zhang 
438fcd2f4bfSAmy Zhang 	return true;
439fcd2f4bfSAmy Zhang }
440fcd2f4bfSAmy Zhang 
441e266fdf6SVitaly Prosyak static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func
442fcd2f4bfSAmy Zhang 		*output_tf, struct pwl_params *regamma_params)
443fcd2f4bfSAmy Zhang {
44423ae4f8eSAmy Zhang 	struct curve_points *arr_points;
44523ae4f8eSAmy Zhang 	struct pwl_result_data *rgb_resulted;
44623ae4f8eSAmy Zhang 	struct pwl_result_data *rgb;
44723ae4f8eSAmy Zhang 	struct pwl_result_data *rgb_plus_1;
448fcd2f4bfSAmy Zhang 	struct fixed31_32 y_r;
449fcd2f4bfSAmy Zhang 	struct fixed31_32 y_g;
450fcd2f4bfSAmy Zhang 	struct fixed31_32 y_b;
451fcd2f4bfSAmy Zhang 	struct fixed31_32 y1_min;
452fcd2f4bfSAmy Zhang 	struct fixed31_32 y3_max;
453fcd2f4bfSAmy Zhang 
454fcd2f4bfSAmy Zhang 	int32_t segment_start, segment_end;
45523ae4f8eSAmy Zhang 	uint32_t i, j, k, seg_distr[16], increment, start_index, hw_points;
45623ae4f8eSAmy Zhang 
45770063a59SAmy Zhang 	if (output_tf == NULL || regamma_params == NULL ||
45870063a59SAmy Zhang 			output_tf->type == TF_TYPE_BYPASS)
45923ae4f8eSAmy Zhang 		return false;
46023ae4f8eSAmy Zhang 
46123ae4f8eSAmy Zhang 	arr_points = regamma_params->arr_points;
46223ae4f8eSAmy Zhang 	rgb_resulted = regamma_params->rgb_resulted;
46323ae4f8eSAmy Zhang 	hw_points = 0;
464fcd2f4bfSAmy Zhang 
465fcd2f4bfSAmy Zhang 	memset(regamma_params, 0, sizeof(struct pwl_params));
466fcd2f4bfSAmy Zhang 
467fcd2f4bfSAmy Zhang 	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
468534db198SAmy Zhang 		/* 16 segments
469fcd2f4bfSAmy Zhang 		 * segments are from 2^-11 to 2^5
470fcd2f4bfSAmy Zhang 		 */
471fcd2f4bfSAmy Zhang 		segment_start = -11;
472fcd2f4bfSAmy Zhang 		segment_end = 5;
473fcd2f4bfSAmy Zhang 
474534db198SAmy Zhang 		seg_distr[0] = 2;
475534db198SAmy Zhang 		seg_distr[1] = 2;
476534db198SAmy Zhang 		seg_distr[2] = 2;
477534db198SAmy Zhang 		seg_distr[3] = 2;
478534db198SAmy Zhang 		seg_distr[4] = 2;
479534db198SAmy Zhang 		seg_distr[5] = 2;
480534db198SAmy Zhang 		seg_distr[6] = 3;
481534db198SAmy Zhang 		seg_distr[7] = 4;
482534db198SAmy Zhang 		seg_distr[8] = 4;
483534db198SAmy Zhang 		seg_distr[9] = 4;
484534db198SAmy Zhang 		seg_distr[10] = 4;
485534db198SAmy Zhang 		seg_distr[11] = 5;
486534db198SAmy Zhang 		seg_distr[12] = 5;
487534db198SAmy Zhang 		seg_distr[13] = 5;
488534db198SAmy Zhang 		seg_distr[14] = 5;
489534db198SAmy Zhang 		seg_distr[15] = 5;
490534db198SAmy Zhang 
491fcd2f4bfSAmy Zhang 	} else {
492534db198SAmy Zhang 		/* 10 segments
493fcd2f4bfSAmy Zhang 		 * segment is from 2^-10 to 2^0
494fcd2f4bfSAmy Zhang 		 */
495fcd2f4bfSAmy Zhang 		segment_start = -10;
496fcd2f4bfSAmy Zhang 		segment_end = 0;
497534db198SAmy Zhang 
498534db198SAmy Zhang 		seg_distr[0] = 3;
499534db198SAmy Zhang 		seg_distr[1] = 4;
500534db198SAmy Zhang 		seg_distr[2] = 4;
501534db198SAmy Zhang 		seg_distr[3] = 4;
502534db198SAmy Zhang 		seg_distr[4] = 4;
503534db198SAmy Zhang 		seg_distr[5] = 4;
504534db198SAmy Zhang 		seg_distr[6] = 4;
505534db198SAmy Zhang 		seg_distr[7] = 4;
506534db198SAmy Zhang 		seg_distr[8] = 5;
507534db198SAmy Zhang 		seg_distr[9] = 5;
508534db198SAmy Zhang 		seg_distr[10] = -1;
509534db198SAmy Zhang 		seg_distr[11] = -1;
510534db198SAmy Zhang 		seg_distr[12] = -1;
511534db198SAmy Zhang 		seg_distr[13] = -1;
512534db198SAmy Zhang 		seg_distr[14] = -1;
513534db198SAmy Zhang 		seg_distr[15] = -1;
514fcd2f4bfSAmy Zhang 	}
515fcd2f4bfSAmy Zhang 
516534db198SAmy Zhang 	for (k = 0; k < 16; k++) {
517534db198SAmy Zhang 		if (seg_distr[k] != -1)
518534db198SAmy Zhang 			hw_points += (1 << seg_distr[k]);
519534db198SAmy Zhang 	}
520534db198SAmy Zhang 
521fcd2f4bfSAmy Zhang 	j = 0;
522534db198SAmy Zhang 	for (k = 0; k < (segment_end - segment_start); k++) {
523534db198SAmy Zhang 		increment = 32 / (1 << seg_distr[k]);
524534db198SAmy Zhang 		start_index = (segment_start + k + 25) * 32;
525534db198SAmy Zhang 		for (i = start_index; i < start_index + 32; i += increment) {
526534db198SAmy Zhang 			if (j == hw_points - 1)
527fcd2f4bfSAmy Zhang 				break;
528fcd2f4bfSAmy Zhang 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
529fcd2f4bfSAmy Zhang 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
530fcd2f4bfSAmy Zhang 			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
531fcd2f4bfSAmy Zhang 			j++;
532fcd2f4bfSAmy Zhang 		}
533534db198SAmy Zhang 	}
534534db198SAmy Zhang 
535534db198SAmy Zhang 	/* last point */
536534db198SAmy Zhang 	start_index = (segment_end + 25) * 32;
537534db198SAmy Zhang 	rgb_resulted[hw_points - 1].red =
538534db198SAmy Zhang 			output_tf->tf_pts.red[start_index];
539534db198SAmy Zhang 	rgb_resulted[hw_points - 1].green =
540534db198SAmy Zhang 			output_tf->tf_pts.green[start_index];
541534db198SAmy Zhang 	rgb_resulted[hw_points - 1].blue =
542534db198SAmy Zhang 			output_tf->tf_pts.blue[start_index];
543fcd2f4bfSAmy Zhang 
544fcd2f4bfSAmy Zhang 	arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
545fcd2f4bfSAmy Zhang 			dal_fixed31_32_from_int(segment_start));
546fcd2f4bfSAmy Zhang 	arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
547fcd2f4bfSAmy Zhang 			dal_fixed31_32_from_int(segment_end));
548fcd2f4bfSAmy Zhang 	arr_points[2].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
549fcd2f4bfSAmy Zhang 			dal_fixed31_32_from_int(segment_end));
550fcd2f4bfSAmy Zhang 
551fcd2f4bfSAmy Zhang 	y_r = rgb_resulted[0].red;
552fcd2f4bfSAmy Zhang 	y_g = rgb_resulted[0].green;
553fcd2f4bfSAmy Zhang 	y_b = rgb_resulted[0].blue;
554fcd2f4bfSAmy Zhang 
555fcd2f4bfSAmy Zhang 	y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
556fcd2f4bfSAmy Zhang 
557fcd2f4bfSAmy Zhang 	arr_points[0].y = y1_min;
558fcd2f4bfSAmy Zhang 	arr_points[0].slope = dal_fixed31_32_div(
559fcd2f4bfSAmy Zhang 					arr_points[0].y,
560fcd2f4bfSAmy Zhang 					arr_points[0].x);
561fcd2f4bfSAmy Zhang 
562fcd2f4bfSAmy Zhang 	y_r = rgb_resulted[hw_points - 1].red;
563fcd2f4bfSAmy Zhang 	y_g = rgb_resulted[hw_points - 1].green;
564fcd2f4bfSAmy Zhang 	y_b = rgb_resulted[hw_points - 1].blue;
565fcd2f4bfSAmy Zhang 
566fcd2f4bfSAmy Zhang 	/* see comment above, m_arrPoints[1].y should be the Y value for the
567fcd2f4bfSAmy Zhang 	 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
568fcd2f4bfSAmy Zhang 	 */
569fcd2f4bfSAmy Zhang 	y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
570fcd2f4bfSAmy Zhang 
571fcd2f4bfSAmy Zhang 	arr_points[1].y = y3_max;
572fcd2f4bfSAmy Zhang 	arr_points[2].y = y3_max;
573fcd2f4bfSAmy Zhang 
574fcd2f4bfSAmy Zhang 	arr_points[1].slope = dal_fixed31_32_zero;
575fcd2f4bfSAmy Zhang 	arr_points[2].slope = dal_fixed31_32_zero;
576fcd2f4bfSAmy Zhang 
577fcd2f4bfSAmy Zhang 	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
578fcd2f4bfSAmy Zhang 		/* for PQ, we want to have a straight line from last HW X point,
579fcd2f4bfSAmy Zhang 		 * and the slope to be such that we hit 1.0 at 10000 nits.
580fcd2f4bfSAmy Zhang 		 */
581fcd2f4bfSAmy Zhang 		const struct fixed31_32 end_value =
582fcd2f4bfSAmy Zhang 				dal_fixed31_32_from_int(125);
583fcd2f4bfSAmy Zhang 
584fcd2f4bfSAmy Zhang 		arr_points[1].slope = dal_fixed31_32_div(
585fcd2f4bfSAmy Zhang 			dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
586fcd2f4bfSAmy Zhang 			dal_fixed31_32_sub(end_value, arr_points[1].x));
587fcd2f4bfSAmy Zhang 		arr_points[2].slope = dal_fixed31_32_div(
588fcd2f4bfSAmy Zhang 			dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
589fcd2f4bfSAmy Zhang 			dal_fixed31_32_sub(end_value, arr_points[1].x));
590fcd2f4bfSAmy Zhang 	}
591fcd2f4bfSAmy Zhang 
592fcd2f4bfSAmy Zhang 	regamma_params->hw_points_num = hw_points;
593fcd2f4bfSAmy Zhang 
594534db198SAmy Zhang 	i = 1;
595534db198SAmy Zhang 	for (k = 0; k < 16 && i < 16; k++) {
596534db198SAmy Zhang 		if (seg_distr[k] != -1) {
597534db198SAmy Zhang 			regamma_params->arr_curve_points[k].segments_num =
598534db198SAmy Zhang 					seg_distr[k];
599534db198SAmy Zhang 			regamma_params->arr_curve_points[i].offset =
600534db198SAmy Zhang 					regamma_params->arr_curve_points[k].
601534db198SAmy Zhang 					offset + (1 << seg_distr[k]);
602fcd2f4bfSAmy Zhang 		}
603534db198SAmy Zhang 		i++;
604534db198SAmy Zhang 	}
605534db198SAmy Zhang 
606534db198SAmy Zhang 	if (seg_distr[k] != -1)
607534db198SAmy Zhang 		regamma_params->arr_curve_points[k].segments_num =
608534db198SAmy Zhang 				seg_distr[k];
609fcd2f4bfSAmy Zhang 
61023ae4f8eSAmy Zhang 	rgb = rgb_resulted;
61123ae4f8eSAmy Zhang 	rgb_plus_1 = rgb_resulted + 1;
612fcd2f4bfSAmy Zhang 
613fcd2f4bfSAmy Zhang 	i = 1;
614fcd2f4bfSAmy Zhang 
615fcd2f4bfSAmy Zhang 	while (i != hw_points + 1) {
616fcd2f4bfSAmy Zhang 		if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
617fcd2f4bfSAmy Zhang 			rgb_plus_1->red = rgb->red;
618fcd2f4bfSAmy Zhang 		if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
619fcd2f4bfSAmy Zhang 			rgb_plus_1->green = rgb->green;
620fcd2f4bfSAmy Zhang 		if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
621fcd2f4bfSAmy Zhang 			rgb_plus_1->blue = rgb->blue;
622fcd2f4bfSAmy Zhang 
623fcd2f4bfSAmy Zhang 		rgb->delta_red = dal_fixed31_32_sub(
624fcd2f4bfSAmy Zhang 			rgb_plus_1->red,
625fcd2f4bfSAmy Zhang 			rgb->red);
626fcd2f4bfSAmy Zhang 		rgb->delta_green = dal_fixed31_32_sub(
627fcd2f4bfSAmy Zhang 			rgb_plus_1->green,
628fcd2f4bfSAmy Zhang 			rgb->green);
629fcd2f4bfSAmy Zhang 		rgb->delta_blue = dal_fixed31_32_sub(
630fcd2f4bfSAmy Zhang 			rgb_plus_1->blue,
631fcd2f4bfSAmy Zhang 			rgb->blue);
632fcd2f4bfSAmy Zhang 
633fcd2f4bfSAmy Zhang 		++rgb_plus_1;
634fcd2f4bfSAmy Zhang 		++rgb;
635fcd2f4bfSAmy Zhang 		++i;
636fcd2f4bfSAmy Zhang 	}
637fcd2f4bfSAmy Zhang 
638fcd2f4bfSAmy Zhang 	convert_to_custom_float(rgb_resulted, arr_points, hw_points);
639fcd2f4bfSAmy Zhang 
640fcd2f4bfSAmy Zhang 	return true;
641fcd2f4bfSAmy Zhang }
642fcd2f4bfSAmy Zhang 
64390e508baSAnthony Koo static bool dce110_set_output_transfer_func(
64490e508baSAnthony Koo 	struct pipe_ctx *pipe_ctx,
6450971c40eSHarry Wentland 	const struct dc_stream_state *stream)
64690e508baSAnthony Koo {
64786a66c4eSHarry Wentland 	struct transform *xfm = pipe_ctx->plane_res.xfm;
6484562236bSHarry Wentland 
6497a09f5beSYue Hin Lau 	xfm->funcs->opp_power_on_regamma_lut(xfm, true);
6507a09f5beSYue Hin Lau 	xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
6514562236bSHarry Wentland 
6524fa086b9SLeo (Sunpeng) Li 	if (stream->out_transfer_func &&
6534fa086b9SLeo (Sunpeng) Li 		stream->out_transfer_func->type ==
654fcd2f4bfSAmy Zhang 			TF_TYPE_PREDEFINED &&
6554fa086b9SLeo (Sunpeng) Li 		stream->out_transfer_func->tf ==
656fcd2f4bfSAmy Zhang 			TRANSFER_FUNCTION_SRGB) {
6577a09f5beSYue Hin Lau 		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
658fcd2f4bfSAmy Zhang 	} else if (dce110_translate_regamma_to_hw_format(
6597a09f5beSYue Hin Lau 				stream->out_transfer_func, &xfm->regamma_params)) {
6607a09f5beSYue Hin Lau 		xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
6617a09f5beSYue Hin Lau 		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
6624562236bSHarry Wentland 	} else {
6637a09f5beSYue Hin Lau 		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
6644562236bSHarry Wentland 	}
6654562236bSHarry Wentland 
6667a09f5beSYue Hin Lau 	xfm->funcs->opp_power_on_regamma_lut(xfm, false);
6674562236bSHarry Wentland 
668cc0cb445SLeon Elazar 	return true;
6694562236bSHarry Wentland }
6704562236bSHarry Wentland 
6714562236bSHarry Wentland static enum dc_status bios_parser_crtc_source_select(
6724562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx)
6734562236bSHarry Wentland {
6744562236bSHarry Wentland 	struct dc_bios *dcb;
6754562236bSHarry Wentland 	/* call VBIOS table to set CRTC source for the HW
6764562236bSHarry Wentland 	 * encoder block
6774562236bSHarry Wentland 	 * note: video bios clears all FMT setting here. */
6784562236bSHarry Wentland 	struct bp_crtc_source_select crtc_source_select = {0};
679b73a22d3SHarry Wentland 	const struct dc_sink *sink = pipe_ctx->stream->sink;
6804562236bSHarry Wentland 
6818e9c4c8cSHarry Wentland 	crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id;
6824562236bSHarry Wentland 	crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1;
6834562236bSHarry Wentland 	/*TODO: Need to un-hardcode color depth, dp_audio and account for
6844562236bSHarry Wentland 	 * the case where signal and sink signal is different (translator
6854562236bSHarry Wentland 	 * encoder)*/
6864562236bSHarry Wentland 	crtc_source_select.signal = pipe_ctx->stream->signal;
6874562236bSHarry Wentland 	crtc_source_select.enable_dp_audio = false;
6884562236bSHarry Wentland 	crtc_source_select.sink_signal = pipe_ctx->stream->signal;
6891b7441b0SCharlene Liu 
6901b7441b0SCharlene Liu 	switch (pipe_ctx->stream->timing.display_color_depth) {
6911b7441b0SCharlene Liu 	case COLOR_DEPTH_666:
6921b7441b0SCharlene Liu 		crtc_source_select.display_output_bit_depth = PANEL_6BIT_COLOR;
6931b7441b0SCharlene Liu 		break;
6941b7441b0SCharlene Liu 	case COLOR_DEPTH_888:
6954562236bSHarry Wentland 		crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR;
6961b7441b0SCharlene Liu 		break;
6971b7441b0SCharlene Liu 	case COLOR_DEPTH_101010:
6981b7441b0SCharlene Liu 		crtc_source_select.display_output_bit_depth = PANEL_10BIT_COLOR;
6991b7441b0SCharlene Liu 		break;
7001b7441b0SCharlene Liu 	case COLOR_DEPTH_121212:
7011b7441b0SCharlene Liu 		crtc_source_select.display_output_bit_depth = PANEL_12BIT_COLOR;
7021b7441b0SCharlene Liu 		break;
7031b7441b0SCharlene Liu 	default:
7041b7441b0SCharlene Liu 		BREAK_TO_DEBUGGER();
7051b7441b0SCharlene Liu 		crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR;
7061b7441b0SCharlene Liu 		break;
7071b7441b0SCharlene Liu 	}
7084562236bSHarry Wentland 
7094562236bSHarry Wentland 	dcb = sink->ctx->dc_bios;
7104562236bSHarry Wentland 
7114562236bSHarry Wentland 	if (BP_RESULT_OK != dcb->funcs->crtc_source_select(
7124562236bSHarry Wentland 		dcb,
7134562236bSHarry Wentland 		&crtc_source_select)) {
7144562236bSHarry Wentland 		return DC_ERROR_UNEXPECTED;
7154562236bSHarry Wentland 	}
7164562236bSHarry Wentland 
7174562236bSHarry Wentland 	return DC_OK;
7184562236bSHarry Wentland }
7194562236bSHarry Wentland 
7204562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
7214562236bSHarry Wentland {
72286e2e1beSHersen Wu 	ASSERT(pipe_ctx->stream);
72386e2e1beSHersen Wu 
7248e9c4c8cSHarry Wentland 	if (pipe_ctx->stream_res.stream_enc == NULL)
72586e2e1beSHersen Wu 		return;  /* this is not root pipe */
72686e2e1beSHersen Wu 
7274562236bSHarry Wentland 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
7288e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
7298e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
73096c50c0dSHarry Wentland 			&pipe_ctx->stream_res.encoder_info_frame);
7314562236bSHarry Wentland 	else if (dc_is_dp_signal(pipe_ctx->stream->signal))
7328e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
7338e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
73496c50c0dSHarry Wentland 			&pipe_ctx->stream_res.encoder_info_frame);
7354562236bSHarry Wentland }
7364562236bSHarry Wentland 
7374562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
7384562236bSHarry Wentland {
7394562236bSHarry Wentland 	enum dc_lane_count lane_count =
740d0778ebfSHarry Wentland 		pipe_ctx->stream->sink->link->cur_link_settings.lane_count;
7414562236bSHarry Wentland 
7424fa086b9SLeo (Sunpeng) Li 	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
743d0778ebfSHarry Wentland 	struct dc_link *link = pipe_ctx->stream->sink->link;
7444562236bSHarry Wentland 
7454562236bSHarry Wentland 	/* 1. update AVI info frame (HDMI, DP)
7464562236bSHarry Wentland 	 * we always need to update info frame
7474562236bSHarry Wentland 	*/
7484562236bSHarry Wentland 	uint32_t active_total_with_borders;
7494562236bSHarry Wentland 	uint32_t early_control = 0;
7506b670fa9SHarry Wentland 	struct timing_generator *tg = pipe_ctx->stream_res.tg;
7514562236bSHarry Wentland 
7524562236bSHarry Wentland 	/* TODOFPGA may change to hwss.update_info_frame */
7534562236bSHarry Wentland 	dce110_update_info_frame(pipe_ctx);
7544562236bSHarry Wentland 	/* enable early control to avoid corruption on DP monitor*/
7554562236bSHarry Wentland 	active_total_with_borders =
7564562236bSHarry Wentland 			timing->h_addressable
7574562236bSHarry Wentland 				+ timing->h_border_left
7584562236bSHarry Wentland 				+ timing->h_border_right;
7594562236bSHarry Wentland 
7604562236bSHarry Wentland 	if (lane_count != 0)
7614562236bSHarry Wentland 		early_control = active_total_with_borders % lane_count;
7624562236bSHarry Wentland 
7634562236bSHarry Wentland 	if (early_control == 0)
7644562236bSHarry Wentland 		early_control = lane_count;
7654562236bSHarry Wentland 
7664562236bSHarry Wentland 	tg->funcs->set_early_control(tg, early_control);
7674562236bSHarry Wentland 
7684562236bSHarry Wentland 	/* enable audio only within mode set */
769afaacef4SHarry Wentland 	if (pipe_ctx->stream_res.audio != NULL) {
7704562236bSHarry Wentland 		if (dc_is_dp_signal(pipe_ctx->stream->signal))
7718e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
7724562236bSHarry Wentland 	}
7734562236bSHarry Wentland 
7744562236bSHarry Wentland 	/* For MST, there are multiply stream go to only one link.
7754562236bSHarry Wentland 	 * connect DIG back_end to front_end while enable_stream and
7764562236bSHarry Wentland 	 * disconnect them during disable_stream
7774562236bSHarry Wentland 	 * BY this, it is logic clean to separate stream and link */
7784562236bSHarry Wentland 	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
7798e9c4c8cSHarry Wentland 						    pipe_ctx->stream_res.stream_enc->id, true);
7804562236bSHarry Wentland 
7814562236bSHarry Wentland }
7824562236bSHarry Wentland 
7835eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/
7845eefbc40SYue Hin Lau static bool is_panel_backlight_on(struct dce_hwseq *hws)
7855eefbc40SYue Hin Lau {
7865eefbc40SYue Hin Lau 	uint32_t value;
7875eefbc40SYue Hin Lau 
7885eefbc40SYue Hin Lau 	REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
7895eefbc40SYue Hin Lau 
7905eefbc40SYue Hin Lau 	return value;
7915eefbc40SYue Hin Lau }
7925eefbc40SYue Hin Lau 
79387401969SAndrew Jiang static bool is_panel_powered_on(struct dce_hwseq *hws)
79487401969SAndrew Jiang {
79587401969SAndrew Jiang 	uint32_t value;
79687401969SAndrew Jiang 
79787401969SAndrew Jiang 	REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
79887401969SAndrew Jiang 	return value == 1;
79987401969SAndrew Jiang }
80087401969SAndrew Jiang 
8015eefbc40SYue Hin Lau static enum bp_result link_transmitter_control(
80287401969SAndrew Jiang 		struct dc_bios *bios,
8035eefbc40SYue Hin Lau 	struct bp_transmitter_control *cntl)
8045eefbc40SYue Hin Lau {
8055eefbc40SYue Hin Lau 	enum bp_result result;
8065eefbc40SYue Hin Lau 
80787401969SAndrew Jiang 	result = bios->funcs->transmitter_control(bios, cntl);
8085eefbc40SYue Hin Lau 
8095eefbc40SYue Hin Lau 	return result;
8105eefbc40SYue Hin Lau }
8115eefbc40SYue Hin Lau 
81287401969SAndrew Jiang /*
81387401969SAndrew Jiang  * @brief
81487401969SAndrew Jiang  * eDP only.
81587401969SAndrew Jiang  */
81687401969SAndrew Jiang void hwss_edp_wait_for_hpd_ready(
817069d418fSAndrew Jiang 		struct dc_link *link,
81887401969SAndrew Jiang 		bool power_up)
81987401969SAndrew Jiang {
820069d418fSAndrew Jiang 	struct dc_context *ctx = link->ctx;
821069d418fSAndrew Jiang 	struct graphics_object_id connector = link->link_enc->connector;
82287401969SAndrew Jiang 	struct gpio *hpd;
82387401969SAndrew Jiang 	bool edp_hpd_high = false;
82487401969SAndrew Jiang 	uint32_t time_elapsed = 0;
82587401969SAndrew Jiang 	uint32_t timeout = power_up ?
82687401969SAndrew Jiang 		PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
82787401969SAndrew Jiang 
82887401969SAndrew Jiang 	if (dal_graphics_object_id_get_connector_id(connector)
82987401969SAndrew Jiang 			!= CONNECTOR_ID_EDP) {
83087401969SAndrew Jiang 		BREAK_TO_DEBUGGER();
83187401969SAndrew Jiang 		return;
83287401969SAndrew Jiang 	}
83387401969SAndrew Jiang 
83487401969SAndrew Jiang 	if (!power_up)
83587401969SAndrew Jiang 		/*
83687401969SAndrew Jiang 		 * From KV, we will not HPD low after turning off VCC -
83787401969SAndrew Jiang 		 * instead, we will check the SW timer in power_up().
83887401969SAndrew Jiang 		 */
83987401969SAndrew Jiang 		return;
84087401969SAndrew Jiang 
84187401969SAndrew Jiang 	/*
84287401969SAndrew Jiang 	 * When we power on/off the eDP panel,
84387401969SAndrew Jiang 	 * we need to wait until SENSE bit is high/low.
84487401969SAndrew Jiang 	 */
84587401969SAndrew Jiang 
84687401969SAndrew Jiang 	/* obtain HPD */
84787401969SAndrew Jiang 	/* TODO what to do with this? */
84887401969SAndrew Jiang 	hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
84987401969SAndrew Jiang 
85087401969SAndrew Jiang 	if (!hpd) {
85187401969SAndrew Jiang 		BREAK_TO_DEBUGGER();
85287401969SAndrew Jiang 		return;
85387401969SAndrew Jiang 	}
85487401969SAndrew Jiang 
85587401969SAndrew Jiang 	dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
85687401969SAndrew Jiang 
85787401969SAndrew Jiang 	/* wait until timeout or panel detected */
85887401969SAndrew Jiang 
85987401969SAndrew Jiang 	do {
86087401969SAndrew Jiang 		uint32_t detected = 0;
86187401969SAndrew Jiang 
86287401969SAndrew Jiang 		dal_gpio_get_value(hpd, &detected);
86387401969SAndrew Jiang 
86487401969SAndrew Jiang 		if (!(detected ^ power_up)) {
86587401969SAndrew Jiang 			edp_hpd_high = true;
86687401969SAndrew Jiang 			break;
86787401969SAndrew Jiang 		}
86887401969SAndrew Jiang 
86987401969SAndrew Jiang 		msleep(HPD_CHECK_INTERVAL);
87087401969SAndrew Jiang 
87187401969SAndrew Jiang 		time_elapsed += HPD_CHECK_INTERVAL;
87287401969SAndrew Jiang 	} while (time_elapsed < timeout);
87387401969SAndrew Jiang 
87487401969SAndrew Jiang 	dal_gpio_close(hpd);
87587401969SAndrew Jiang 
87687401969SAndrew Jiang 	dal_gpio_destroy_irq(&hpd);
87787401969SAndrew Jiang 
87887401969SAndrew Jiang 	if (false == edp_hpd_high) {
87987401969SAndrew Jiang 		dm_logger_write(ctx->logger, LOG_ERROR,
88087401969SAndrew Jiang 				"%s: wait timed out!\n", __func__);
88187401969SAndrew Jiang 	}
88287401969SAndrew Jiang }
88387401969SAndrew Jiang 
88487401969SAndrew Jiang void hwss_edp_power_control(
885069d418fSAndrew Jiang 		struct dc_link *link,
88687401969SAndrew Jiang 		bool power_up)
88787401969SAndrew Jiang {
888069d418fSAndrew Jiang 	struct dc_context *ctx = link->ctx;
88987401969SAndrew Jiang 	struct dce_hwseq *hwseq = ctx->dc->hwseq;
89087401969SAndrew Jiang 	struct bp_transmitter_control cntl = { 0 };
89187401969SAndrew Jiang 	enum bp_result bp_result;
89287401969SAndrew Jiang 
89387401969SAndrew Jiang 
894069d418fSAndrew Jiang 	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
89587401969SAndrew Jiang 			!= CONNECTOR_ID_EDP) {
89687401969SAndrew Jiang 		BREAK_TO_DEBUGGER();
89787401969SAndrew Jiang 		return;
89887401969SAndrew Jiang 	}
89987401969SAndrew Jiang 
90087401969SAndrew Jiang 	if (power_up != is_panel_powered_on(hwseq)) {
90187401969SAndrew Jiang 		/* Send VBIOS command to prompt eDP panel power */
90287401969SAndrew Jiang 
90387401969SAndrew Jiang 		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
90487401969SAndrew Jiang 				"%s: Panel Power action: %s\n",
90587401969SAndrew Jiang 				__func__, (power_up ? "On":"Off"));
90687401969SAndrew Jiang 
90787401969SAndrew Jiang 		cntl.action = power_up ?
90887401969SAndrew Jiang 			TRANSMITTER_CONTROL_POWER_ON :
90987401969SAndrew Jiang 			TRANSMITTER_CONTROL_POWER_OFF;
910069d418fSAndrew Jiang 		cntl.transmitter = link->link_enc->transmitter;
911069d418fSAndrew Jiang 		cntl.connector_obj_id = link->link_enc->connector;
91287401969SAndrew Jiang 		cntl.coherent = false;
91387401969SAndrew Jiang 		cntl.lanes_number = LANE_COUNT_FOUR;
914069d418fSAndrew Jiang 		cntl.hpd_sel = link->link_enc->hpd_source;
91587401969SAndrew Jiang 
91687401969SAndrew Jiang 		bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
91787401969SAndrew Jiang 
91887401969SAndrew Jiang 		if (bp_result != BP_RESULT_OK)
91987401969SAndrew Jiang 			dm_logger_write(ctx->logger, LOG_ERROR,
92087401969SAndrew Jiang 					"%s: Panel Power bp_result: %d\n",
92187401969SAndrew Jiang 					__func__, bp_result);
92287401969SAndrew Jiang 	} else {
92387401969SAndrew Jiang 		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
92487401969SAndrew Jiang 				"%s: Skipping Panel Power action: %s\n",
92587401969SAndrew Jiang 				__func__, (power_up ? "On":"Off"));
92687401969SAndrew Jiang 	}
92787401969SAndrew Jiang 
928069d418fSAndrew Jiang 	hwss_edp_wait_for_hpd_ready(link, true);
92987401969SAndrew Jiang }
9305eefbc40SYue Hin Lau 
9315eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/
9325eefbc40SYue Hin Lau /*
9335eefbc40SYue Hin Lau  * @brief
9345eefbc40SYue Hin Lau  * eDP only. Control the backlight of the eDP panel
9355eefbc40SYue Hin Lau  */
93687401969SAndrew Jiang void hwss_edp_backlight_control(
9375eefbc40SYue Hin Lau 		struct dc_link *link,
9385eefbc40SYue Hin Lau 		bool enable)
9395eefbc40SYue Hin Lau {
940069d418fSAndrew Jiang 	struct dc_context *ctx = link->ctx;
941069d418fSAndrew Jiang 	struct dce_hwseq *hws = ctx->dc->hwseq;
9425eefbc40SYue Hin Lau 	struct bp_transmitter_control cntl = { 0 };
9435eefbc40SYue Hin Lau 
944069d418fSAndrew Jiang 	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
9455eefbc40SYue Hin Lau 		!= CONNECTOR_ID_EDP) {
9465eefbc40SYue Hin Lau 		BREAK_TO_DEBUGGER();
9475eefbc40SYue Hin Lau 		return;
9485eefbc40SYue Hin Lau 	}
9495eefbc40SYue Hin Lau 
9505eefbc40SYue Hin Lau 	if (enable && is_panel_backlight_on(hws)) {
9515eefbc40SYue Hin Lau 		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
9525eefbc40SYue Hin Lau 				"%s: panel already powered up. Do nothing.\n",
9535eefbc40SYue Hin Lau 				__func__);
9545eefbc40SYue Hin Lau 		return;
9555eefbc40SYue Hin Lau 	}
9565eefbc40SYue Hin Lau 
9575eefbc40SYue Hin Lau 	/* Send VBIOS command to control eDP panel backlight */
9585eefbc40SYue Hin Lau 
9595eefbc40SYue Hin Lau 	dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
9605eefbc40SYue Hin Lau 			"%s: backlight action: %s\n",
9615eefbc40SYue Hin Lau 			__func__, (enable ? "On":"Off"));
9625eefbc40SYue Hin Lau 
9635eefbc40SYue Hin Lau 	cntl.action = enable ?
9645eefbc40SYue Hin Lau 		TRANSMITTER_CONTROL_BACKLIGHT_ON :
9655eefbc40SYue Hin Lau 		TRANSMITTER_CONTROL_BACKLIGHT_OFF;
96687401969SAndrew Jiang 
9675eefbc40SYue Hin Lau 	/*cntl.engine_id = ctx->engine;*/
9685eefbc40SYue Hin Lau 	cntl.transmitter = link->link_enc->transmitter;
9695eefbc40SYue Hin Lau 	cntl.connector_obj_id = link->link_enc->connector;
9705eefbc40SYue Hin Lau 	/*todo: unhardcode*/
9715eefbc40SYue Hin Lau 	cntl.lanes_number = LANE_COUNT_FOUR;
9725eefbc40SYue Hin Lau 	cntl.hpd_sel = link->link_enc->hpd_source;
9735eefbc40SYue Hin Lau 
9745eefbc40SYue Hin Lau 	/* For eDP, the following delays might need to be considered
9755eefbc40SYue Hin Lau 	 * after link training completed:
9765eefbc40SYue Hin Lau 	 * idle period - min. accounts for required BS-Idle pattern,
9775eefbc40SYue Hin Lau 	 * max. allows for source frame synchronization);
9785eefbc40SYue Hin Lau 	 * 50 msec max. delay from valid video data from source
9795eefbc40SYue Hin Lau 	 * to video on dislpay or backlight enable.
9805eefbc40SYue Hin Lau 	 *
9815eefbc40SYue Hin Lau 	 * Disable the delay for now.
9825eefbc40SYue Hin Lau 	 * Enable it in the future if necessary.
9835eefbc40SYue Hin Lau 	 */
9845eefbc40SYue Hin Lau 	/* dc_service_sleep_in_milliseconds(50); */
985069d418fSAndrew Jiang 	link_transmitter_control(ctx->dc_bios, &cntl);
9865eefbc40SYue Hin Lau }
9875eefbc40SYue Hin Lau 
9884176664bSCharlene Liu void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
9894562236bSHarry Wentland {
9900971c40eSHarry Wentland 	struct dc_stream_state *stream = pipe_ctx->stream;
991d0778ebfSHarry Wentland 	struct dc_link *link = stream->sink->link;
9924176664bSCharlene Liu 	struct dc *dc = pipe_ctx->stream->ctx->dc;
9934562236bSHarry Wentland 
9942b7c97d6SCharlene Liu 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
9952b7c97d6SCharlene Liu 		pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
9962b7c97d6SCharlene Liu 			pipe_ctx->stream_res.stream_enc);
9972b7c97d6SCharlene Liu 
9982b7c97d6SCharlene Liu 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
9992b7c97d6SCharlene Liu 		pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
10002b7c97d6SCharlene Liu 			pipe_ctx->stream_res.stream_enc);
10012b7c97d6SCharlene Liu 
10022b7c97d6SCharlene Liu 	pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
10032b7c97d6SCharlene Liu 			pipe_ctx->stream_res.stream_enc, true);
1004afaacef4SHarry Wentland 	if (pipe_ctx->stream_res.audio) {
1005afaacef4SHarry Wentland 		pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
10064562236bSHarry Wentland 
10074562236bSHarry Wentland 		if (dc_is_dp_signal(pipe_ctx->stream->signal))
10088e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
10098e9c4c8cSHarry Wentland 					pipe_ctx->stream_res.stream_enc);
10104562236bSHarry Wentland 		else
10118e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
10128e9c4c8cSHarry Wentland 					pipe_ctx->stream_res.stream_enc);
10134176664bSCharlene Liu 		/*don't free audio if it is from retrain or internal disable stream*/
10144176664bSCharlene Liu 		if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
10154176664bSCharlene Liu 			/*we have to dynamic arbitrate the audio endpoints*/
10164176664bSCharlene Liu 			pipe_ctx->stream_res.audio = NULL;
10174176664bSCharlene Liu 			/*we free the resource, need reset is_audio_acquired*/
10184176664bSCharlene Liu 			update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
10194176664bSCharlene Liu 		}
10204562236bSHarry Wentland 
10214562236bSHarry Wentland 		/* TODO: notify audio driver for if audio modes list changed
10224562236bSHarry Wentland 		 * add audio mode list change flag */
10234562236bSHarry Wentland 		/* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
10244562236bSHarry Wentland 		 * stream->stream_engine_id);
10254562236bSHarry Wentland 		 */
10264562236bSHarry Wentland 	}
10274562236bSHarry Wentland 
10284562236bSHarry Wentland 	/* blank at encoder level */
10291e4cee77SCharlene Liu 	if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
10301e4cee77SCharlene Liu 		if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
103187401969SAndrew Jiang 			hwss_edp_backlight_control(link, false);
10328e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
10331e4cee77SCharlene Liu 	}
10344562236bSHarry Wentland 	link->link_enc->funcs->connect_dig_be_to_fe(
10354562236bSHarry Wentland 			link->link_enc,
10368e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->id,
10374562236bSHarry Wentland 			false);
10384562236bSHarry Wentland 
10394562236bSHarry Wentland }
10404562236bSHarry Wentland 
10414562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
10424562236bSHarry Wentland 		struct dc_link_settings *link_settings)
10434562236bSHarry Wentland {
10444562236bSHarry Wentland 	struct encoder_unblank_param params = { { 0 } };
10451e4cee77SCharlene Liu 	struct dc_link *link = pipe_ctx->stream->sink->link;
10464562236bSHarry Wentland 
10474562236bSHarry Wentland 	/* only 3 items below are used by unblank */
10486235b23cSTony Cheng 	params.pixel_clk_khz =
10494fa086b9SLeo (Sunpeng) Li 		pipe_ctx->stream->timing.pix_clk_khz;
10504562236bSHarry Wentland 	params.link_settings.link_rate = link_settings->link_rate;
10518e9c4c8cSHarry Wentland 	pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
10521e4cee77SCharlene Liu 	if (link->connector_signal == SIGNAL_TYPE_EDP)
105387401969SAndrew Jiang 		hwss_edp_backlight_control(link, true);
10544562236bSHarry Wentland }
10554562236bSHarry Wentland 
105615e17335SCharlene Liu 
105715e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
105815e17335SCharlene Liu {
10598e9c4c8cSHarry Wentland 	if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
10608e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
106115e17335SCharlene Liu }
106215e17335SCharlene Liu 
10634562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
10644562236bSHarry Wentland {
10654562236bSHarry Wentland 	switch (crtc_id) {
10664562236bSHarry Wentland 	case CONTROLLER_ID_D0:
10674562236bSHarry Wentland 		return DTO_SOURCE_ID0;
10684562236bSHarry Wentland 	case CONTROLLER_ID_D1:
10694562236bSHarry Wentland 		return DTO_SOURCE_ID1;
10704562236bSHarry Wentland 	case CONTROLLER_ID_D2:
10714562236bSHarry Wentland 		return DTO_SOURCE_ID2;
10724562236bSHarry Wentland 	case CONTROLLER_ID_D3:
10734562236bSHarry Wentland 		return DTO_SOURCE_ID3;
10744562236bSHarry Wentland 	case CONTROLLER_ID_D4:
10754562236bSHarry Wentland 		return DTO_SOURCE_ID4;
10764562236bSHarry Wentland 	case CONTROLLER_ID_D5:
10774562236bSHarry Wentland 		return DTO_SOURCE_ID5;
10784562236bSHarry Wentland 	default:
10794562236bSHarry Wentland 		return DTO_SOURCE_UNKNOWN;
10804562236bSHarry Wentland 	}
10814562236bSHarry Wentland }
10824562236bSHarry Wentland 
10834562236bSHarry Wentland static void build_audio_output(
1084ab8db3e1SAndrey Grodzovsky 	struct dc_state *state,
10854562236bSHarry Wentland 	const struct pipe_ctx *pipe_ctx,
10864562236bSHarry Wentland 	struct audio_output *audio_output)
10874562236bSHarry Wentland {
10880971c40eSHarry Wentland 	const struct dc_stream_state *stream = pipe_ctx->stream;
10898e9c4c8cSHarry Wentland 	audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id;
10904562236bSHarry Wentland 
10914562236bSHarry Wentland 	audio_output->signal = pipe_ctx->stream->signal;
10924562236bSHarry Wentland 
10934562236bSHarry Wentland 	/* audio_crtc_info  */
10944562236bSHarry Wentland 
10954562236bSHarry Wentland 	audio_output->crtc_info.h_total =
10964fa086b9SLeo (Sunpeng) Li 		stream->timing.h_total;
10974562236bSHarry Wentland 
10984562236bSHarry Wentland 	/*
10994562236bSHarry Wentland 	 * Audio packets are sent during actual CRTC blank physical signal, we
11004562236bSHarry Wentland 	 * need to specify actual active signal portion
11014562236bSHarry Wentland 	 */
11024562236bSHarry Wentland 	audio_output->crtc_info.h_active =
11034fa086b9SLeo (Sunpeng) Li 			stream->timing.h_addressable
11044fa086b9SLeo (Sunpeng) Li 			+ stream->timing.h_border_left
11054fa086b9SLeo (Sunpeng) Li 			+ stream->timing.h_border_right;
11064562236bSHarry Wentland 
11074562236bSHarry Wentland 	audio_output->crtc_info.v_active =
11084fa086b9SLeo (Sunpeng) Li 			stream->timing.v_addressable
11094fa086b9SLeo (Sunpeng) Li 			+ stream->timing.v_border_top
11104fa086b9SLeo (Sunpeng) Li 			+ stream->timing.v_border_bottom;
11114562236bSHarry Wentland 
11124562236bSHarry Wentland 	audio_output->crtc_info.pixel_repetition = 1;
11134562236bSHarry Wentland 
11144562236bSHarry Wentland 	audio_output->crtc_info.interlaced =
11154fa086b9SLeo (Sunpeng) Li 			stream->timing.flags.INTERLACE;
11164562236bSHarry Wentland 
11174562236bSHarry Wentland 	audio_output->crtc_info.refresh_rate =
11184fa086b9SLeo (Sunpeng) Li 		(stream->timing.pix_clk_khz*1000)/
11194fa086b9SLeo (Sunpeng) Li 		(stream->timing.h_total*stream->timing.v_total);
11204562236bSHarry Wentland 
11214562236bSHarry Wentland 	audio_output->crtc_info.color_depth =
11224fa086b9SLeo (Sunpeng) Li 		stream->timing.display_color_depth;
11234562236bSHarry Wentland 
11244562236bSHarry Wentland 	audio_output->crtc_info.requested_pixel_clock =
112510688217SHarry Wentland 			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk;
11264562236bSHarry Wentland 
11274562236bSHarry Wentland 	audio_output->crtc_info.calculated_pixel_clock =
112810688217SHarry Wentland 			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk;
11294562236bSHarry Wentland 
113087b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/
113187b58768SCharlene Liu 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal) &&
113287b58768SCharlene Liu 		audio_output->crtc_info.requested_pixel_clock ==
11334fa086b9SLeo (Sunpeng) Li 				stream->timing.pix_clk_khz) {
113410688217SHarry Wentland 		if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
113587b58768SCharlene Liu 			audio_output->crtc_info.requested_pixel_clock =
113687b58768SCharlene Liu 					audio_output->crtc_info.requested_pixel_clock/2;
113787b58768SCharlene Liu 			audio_output->crtc_info.calculated_pixel_clock =
113810688217SHarry Wentland 					pipe_ctx->stream_res.pix_clk_params.requested_pix_clk/2;
113987b58768SCharlene Liu 
114087b58768SCharlene Liu 		}
114187b58768SCharlene Liu 	}
114287b58768SCharlene Liu 
11434562236bSHarry Wentland 	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
11444562236bSHarry Wentland 			pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
11454562236bSHarry Wentland 		audio_output->pll_info.dp_dto_source_clock_in_khz =
1146ab8db3e1SAndrey Grodzovsky 				state->dis_clk->funcs->get_dp_ref_clk_frequency(
1147ab8db3e1SAndrey Grodzovsky 						state->dis_clk);
11484562236bSHarry Wentland 	}
11494562236bSHarry Wentland 
11504562236bSHarry Wentland 	audio_output->pll_info.feed_back_divider =
11514562236bSHarry Wentland 			pipe_ctx->pll_settings.feedback_divider;
11524562236bSHarry Wentland 
11534562236bSHarry Wentland 	audio_output->pll_info.dto_source =
11544562236bSHarry Wentland 		translate_to_dto_source(
11554562236bSHarry Wentland 			pipe_ctx->pipe_idx + 1);
11564562236bSHarry Wentland 
11574562236bSHarry Wentland 	/* TODO hard code to enable for now. Need get from stream */
11584562236bSHarry Wentland 	audio_output->pll_info.ss_enabled = true;
11594562236bSHarry Wentland 
11604562236bSHarry Wentland 	audio_output->pll_info.ss_percentage =
11614562236bSHarry Wentland 			pipe_ctx->pll_settings.ss_percentage;
11624562236bSHarry Wentland }
11634562236bSHarry Wentland 
11644562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx,
11654562236bSHarry Wentland 		struct tg_color *color)
11664562236bSHarry Wentland {
11674562236bSHarry Wentland 	uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->pipe_idx) / 4;
11684562236bSHarry Wentland 
11696702a9acSHarry Wentland 	switch (pipe_ctx->plane_res.scl_data.format) {
11704562236bSHarry Wentland 	case PIXEL_FORMAT_ARGB8888:
11714562236bSHarry Wentland 		/* set boarder color to red */
11724562236bSHarry Wentland 		color->color_r_cr = color_value;
11734562236bSHarry Wentland 		break;
11744562236bSHarry Wentland 
11754562236bSHarry Wentland 	case PIXEL_FORMAT_ARGB2101010:
11764562236bSHarry Wentland 		/* set boarder color to blue */
11774562236bSHarry Wentland 		color->color_b_cb = color_value;
11784562236bSHarry Wentland 		break;
117987449a90SAnthony Koo 	case PIXEL_FORMAT_420BPP8:
11804562236bSHarry Wentland 		/* set boarder color to green */
11814562236bSHarry Wentland 		color->color_g_y = color_value;
11824562236bSHarry Wentland 		break;
118387449a90SAnthony Koo 	case PIXEL_FORMAT_420BPP10:
118487449a90SAnthony Koo 		/* set boarder color to yellow */
118587449a90SAnthony Koo 		color->color_g_y = color_value;
118687449a90SAnthony Koo 		color->color_r_cr = color_value;
118787449a90SAnthony Koo 		break;
11884562236bSHarry Wentland 	case PIXEL_FORMAT_FP16:
11894562236bSHarry Wentland 		/* set boarder color to white */
11904562236bSHarry Wentland 		color->color_r_cr = color_value;
11914562236bSHarry Wentland 		color->color_b_cb = color_value;
11924562236bSHarry Wentland 		color->color_g_y = color_value;
11934562236bSHarry Wentland 		break;
11944562236bSHarry Wentland 	default:
11954562236bSHarry Wentland 		break;
11964562236bSHarry Wentland 	}
11974562236bSHarry Wentland }
11984562236bSHarry Wentland 
1199fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc,
12004562236bSHarry Wentland 		const struct pipe_ctx *pipe_ctx)
12014562236bSHarry Wentland {
12024562236bSHarry Wentland 	struct tg_color color = {0};
12034562236bSHarry Wentland 
1204ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1205ff5ef992SAlex Deucher 	/* TOFPGA */
120686a66c4eSHarry Wentland 	if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
1207ff5ef992SAlex Deucher 		return;
1208ff5ef992SAlex Deucher #endif
1209ff5ef992SAlex Deucher 
1210fb3466a4SBhawanpreet Lakha 	if (dc->debug.surface_visual_confirm)
12114562236bSHarry Wentland 		get_surface_visual_confirm_color(pipe_ctx, &color);
12124562236bSHarry Wentland 	else
12134562236bSHarry Wentland 		color_space_to_black_color(dc,
12144fa086b9SLeo (Sunpeng) Li 				pipe_ctx->stream->output_color_space,
12154562236bSHarry Wentland 				&color);
12164562236bSHarry Wentland 
121786a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
121886a66c4eSHarry Wentland 		pipe_ctx->plane_res.xfm,
12196702a9acSHarry Wentland 		pipe_ctx->plane_res.scl_data.lb_params.depth,
12204562236bSHarry Wentland 		&pipe_ctx->stream->bit_depth_params);
12214562236bSHarry Wentland 
12226b670fa9SHarry Wentland 	if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color)
12236b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
12246b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
12254562236bSHarry Wentland 				&color);
12264562236bSHarry Wentland 
122786a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
12286702a9acSHarry Wentland 		&pipe_ctx->plane_res.scl_data);
12294562236bSHarry Wentland }
12304562236bSHarry Wentland 
12314b5e7d62SHersen Wu static enum dc_status dce110_prog_pixclk_crtc_otg(
12324562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx,
1233608ac7bbSJerry Zuo 		struct dc_state *context,
1234fb3466a4SBhawanpreet Lakha 		struct dc *dc)
12354562236bSHarry Wentland {
12360971c40eSHarry Wentland 	struct dc_stream_state *stream = pipe_ctx->stream;
1237608ac7bbSJerry Zuo 	struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
12384562236bSHarry Wentland 			pipe_ctx[pipe_ctx->pipe_idx];
12394562236bSHarry Wentland 	struct tg_color black_color = {0};
12404562236bSHarry Wentland 
12414562236bSHarry Wentland 	if (!pipe_ctx_old->stream) {
12424562236bSHarry Wentland 
12434562236bSHarry Wentland 		/* program blank color */
12444562236bSHarry Wentland 		color_space_to_black_color(dc,
12454fa086b9SLeo (Sunpeng) Li 				stream->output_color_space, &black_color);
12466b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_blank_color(
12476b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
12484562236bSHarry Wentland 				&black_color);
12494b5e7d62SHersen Wu 
12504562236bSHarry Wentland 		/*
12514562236bSHarry Wentland 		 * Must blank CRTC after disabling power gating and before any
12524562236bSHarry Wentland 		 * programming, otherwise CRTC will be hung in bad state
12534562236bSHarry Wentland 		 */
12546b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
12554562236bSHarry Wentland 
12564562236bSHarry Wentland 		if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
12574562236bSHarry Wentland 				pipe_ctx->clock_source,
125810688217SHarry Wentland 				&pipe_ctx->stream_res.pix_clk_params,
12594562236bSHarry Wentland 				&pipe_ctx->pll_settings)) {
12604562236bSHarry Wentland 			BREAK_TO_DEBUGGER();
12614562236bSHarry Wentland 			return DC_ERROR_UNEXPECTED;
12624562236bSHarry Wentland 		}
12634562236bSHarry Wentland 
12646b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->program_timing(
12656b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
12664fa086b9SLeo (Sunpeng) Li 				&stream->timing,
12674562236bSHarry Wentland 				true);
126894267b3dSSylvia Tsai 
12696b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
12706b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
127194267b3dSSylvia Tsai 				0x182);
12724562236bSHarry Wentland 	}
12734562236bSHarry Wentland 
12744562236bSHarry Wentland 	if (!pipe_ctx_old->stream) {
12756b670fa9SHarry Wentland 		if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(
12766b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg)) {
12774562236bSHarry Wentland 			BREAK_TO_DEBUGGER();
12784562236bSHarry Wentland 			return DC_ERROR_UNEXPECTED;
12794562236bSHarry Wentland 		}
12804562236bSHarry Wentland 	}
12814562236bSHarry Wentland 
128294267b3dSSylvia Tsai 
128394267b3dSSylvia Tsai 
12844562236bSHarry Wentland 	return DC_OK;
12854562236bSHarry Wentland }
12864562236bSHarry Wentland 
12874562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw(
12884562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx,
1289608ac7bbSJerry Zuo 		struct dc_state *context,
1290fb3466a4SBhawanpreet Lakha 		struct dc *dc)
12914562236bSHarry Wentland {
12920971c40eSHarry Wentland 	struct dc_stream_state *stream = pipe_ctx->stream;
1293608ac7bbSJerry Zuo 	struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
12944562236bSHarry Wentland 			pipe_ctx[pipe_ctx->pipe_idx];
12954562236bSHarry Wentland 
12964562236bSHarry Wentland 	/*  */
12974562236bSHarry Wentland 	dc->hwss.prog_pixclk_crtc_otg(pipe_ctx, context, dc);
12984562236bSHarry Wentland 
1299f0c4d997SCorbin McElhanney 	/* FPGA does not program backend */
1300f0c4d997SCorbin McElhanney 	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
1301a6a6cb34SHarry Wentland 		pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
1302a6a6cb34SHarry Wentland 		pipe_ctx->stream_res.opp,
13034562236bSHarry Wentland 		COLOR_SPACE_YCBCR601,
13044fa086b9SLeo (Sunpeng) Li 		stream->timing.display_color_depth,
13054562236bSHarry Wentland 		pipe_ctx->stream->signal);
13064562236bSHarry Wentland 
1307a6a6cb34SHarry Wentland 		pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
1308a6a6cb34SHarry Wentland 			pipe_ctx->stream_res.opp,
13094562236bSHarry Wentland 			&stream->bit_depth_params,
13104562236bSHarry Wentland 			&stream->clamping);
13114562236bSHarry Wentland 		return DC_OK;
1312181a888fSCharlene Liu 	}
13134562236bSHarry Wentland 	/* TODO: move to stream encoder */
13144562236bSHarry Wentland 	if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
13154562236bSHarry Wentland 		if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) {
13164562236bSHarry Wentland 			BREAK_TO_DEBUGGER();
13174562236bSHarry Wentland 			return DC_ERROR_UNEXPECTED;
13184562236bSHarry Wentland 		}
1319f0c4d997SCorbin McElhanney 	pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
1320f0c4d997SCorbin McElhanney 			pipe_ctx->stream_res.opp,
1321f0c4d997SCorbin McElhanney 			COLOR_SPACE_YCBCR601,
1322f0c4d997SCorbin McElhanney 			stream->timing.display_color_depth,
1323f0c4d997SCorbin McElhanney 			pipe_ctx->stream->signal);
13244562236bSHarry Wentland 
13254562236bSHarry Wentland 	if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
13264562236bSHarry Wentland 		stream->sink->link->link_enc->funcs->setup(
13274562236bSHarry Wentland 			stream->sink->link->link_enc,
13284562236bSHarry Wentland 			pipe_ctx->stream->signal);
13294562236bSHarry Wentland 
1330ab3c1798SVitaly Prosyak 	if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
13318e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync(
13328e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc,
13336b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->inst,
13344fa086b9SLeo (Sunpeng) Li 		stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
1335ab3c1798SVitaly Prosyak 
1336ab3c1798SVitaly Prosyak 
1337a6a6cb34SHarry Wentland 	pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
1338a6a6cb34SHarry Wentland 		pipe_ctx->stream_res.opp,
1339181a888fSCharlene Liu 		&stream->bit_depth_params,
1340181a888fSCharlene Liu 		&stream->clamping);
1341603767f9STony Cheng 
13424562236bSHarry Wentland 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
13438e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
13448e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
13454fa086b9SLeo (Sunpeng) Li 			&stream->timing,
13464fa086b9SLeo (Sunpeng) Li 			stream->output_color_space);
13474562236bSHarry Wentland 
13484562236bSHarry Wentland 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
13498e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute(
13508e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
13514fa086b9SLeo (Sunpeng) Li 			&stream->timing,
13524562236bSHarry Wentland 			stream->phy_pix_clk,
1353afaacef4SHarry Wentland 			pipe_ctx->stream_res.audio != NULL);
13544562236bSHarry Wentland 
13554562236bSHarry Wentland 	if (dc_is_dvi_signal(pipe_ctx->stream->signal))
13568e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
13578e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
13584fa086b9SLeo (Sunpeng) Li 			&stream->timing,
13594562236bSHarry Wentland 			(pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
13604562236bSHarry Wentland 			true : false);
13614562236bSHarry Wentland 
136215e17335SCharlene Liu 	resource_build_info_frame(pipe_ctx);
13633639fa68SZeyu Fan 	dce110_update_info_frame(pipe_ctx);
13644562236bSHarry Wentland 	if (!pipe_ctx_old->stream) {
1365d050f8edSHersen Wu 		if (!pipe_ctx->stream->dpms_off)
1366ab8db3e1SAndrey Grodzovsky 			core_link_enable_stream(context, pipe_ctx);
13674562236bSHarry Wentland 	}
13684562236bSHarry Wentland 
13696702a9acSHarry Wentland 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
13704562236bSHarry Wentland 
137194267b3dSSylvia Tsai 	pipe_ctx->stream->sink->link->psr_enabled = false;
137294267b3dSSylvia Tsai 
13734562236bSHarry Wentland 	return DC_OK;
13744562236bSHarry Wentland }
13754562236bSHarry Wentland 
13764562236bSHarry Wentland /******************************************************************************/
13774562236bSHarry Wentland 
1378fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc)
13794562236bSHarry Wentland {
13804562236bSHarry Wentland 	int i;
1381a0c38ebaSCharlene Liu 	enum connector_id connector_id;
138268d77dd8SAndrew Jiang 	enum signal_type signal = SIGNAL_TYPE_NONE;
1383b9b171ffSHersen Wu 
1384b9b171ffSHersen Wu 	/* do not know BIOS back-front mapping, simply blank all. It will not
1385b9b171ffSHersen Wu 	 * hurt for non-DP
1386b9b171ffSHersen Wu 	 */
1387b9b171ffSHersen Wu 	for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
1388b9b171ffSHersen Wu 		dc->res_pool->stream_enc[i]->funcs->dp_blank(
1389b9b171ffSHersen Wu 					dc->res_pool->stream_enc[i]);
1390b9b171ffSHersen Wu 	}
1391b9b171ffSHersen Wu 
13924562236bSHarry Wentland 	for (i = 0; i < dc->link_count; i++) {
1393a0c38ebaSCharlene Liu 		connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
1394a0c38ebaSCharlene Liu 		if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
1395a0c38ebaSCharlene Liu 			(connector_id == CONNECTOR_ID_EDP)) {
1396a0c38ebaSCharlene Liu 
1397a0c38ebaSCharlene Liu 			if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
1398a0c38ebaSCharlene Liu 				dp_receiver_power_ctrl(dc->links[i], false);
1399069d418fSAndrew Jiang 			if (connector_id == CONNECTOR_ID_EDP) {
140068d77dd8SAndrew Jiang 				signal = SIGNAL_TYPE_EDP;
1401069d418fSAndrew Jiang 				hwss_edp_backlight_control(dc->links[i], false);
1402069d418fSAndrew Jiang 			}
1403a0c38ebaSCharlene Liu 		}
1404a0c38ebaSCharlene Liu 
14054562236bSHarry Wentland 		dc->links[i]->link_enc->funcs->disable_output(
1406069d418fSAndrew Jiang 				dc->links[i]->link_enc, signal);
14074562236bSHarry Wentland 	}
14084562236bSHarry Wentland }
14094562236bSHarry Wentland 
1410fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc)
14114562236bSHarry Wentland {
14124562236bSHarry Wentland 	int i;
14134562236bSHarry Wentland 
14144562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
14154562236bSHarry Wentland 		dc->res_pool->timing_generators[i]->funcs->disable_crtc(
14164562236bSHarry Wentland 				dc->res_pool->timing_generators[i]);
14174562236bSHarry Wentland 	}
14184562236bSHarry Wentland }
14194562236bSHarry Wentland 
1420fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc)
14214562236bSHarry Wentland {
14224562236bSHarry Wentland 	int i;
14234562236bSHarry Wentland 
14244562236bSHarry Wentland 	if (dc->res_pool->dp_clock_source->funcs->cs_power_down(
14254562236bSHarry Wentland 		dc->res_pool->dp_clock_source) == false)
14264562236bSHarry Wentland 		dm_error("Failed to power down pll! (dp clk src)\n");
14274562236bSHarry Wentland 
14284562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->clk_src_count; i++) {
14294562236bSHarry Wentland 		if (dc->res_pool->clock_sources[i]->funcs->cs_power_down(
14304562236bSHarry Wentland 				dc->res_pool->clock_sources[i]) == false)
14314562236bSHarry Wentland 			dm_error("Failed to power down pll! (clk src index=%d)\n", i);
14324562236bSHarry Wentland 	}
14334562236bSHarry Wentland }
14344562236bSHarry Wentland 
1435fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc)
14364562236bSHarry Wentland {
14374562236bSHarry Wentland 	power_down_encoders(dc);
14384562236bSHarry Wentland 
14394562236bSHarry Wentland 	power_down_controllers(dc);
14404562236bSHarry Wentland 
14414562236bSHarry Wentland 	power_down_clock_sources(dc);
14421663ae1cSBhawanpreet Lakha 
14433eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
14442f3bfb27SRoman Li 	if (dc->fbc_compressor)
14451663ae1cSBhawanpreet Lakha 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
14461663ae1cSBhawanpreet Lakha #endif
14474562236bSHarry Wentland }
14484562236bSHarry Wentland 
14494562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers(
1450fb3466a4SBhawanpreet Lakha 		struct dc *dc)
14514562236bSHarry Wentland {
14524562236bSHarry Wentland 	int i;
14534562236bSHarry Wentland 	struct timing_generator *tg;
14544562236bSHarry Wentland 	struct dc_context *ctx = dc->ctx;
14554562236bSHarry Wentland 
14564562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
14574562236bSHarry Wentland 		tg = dc->res_pool->timing_generators[i];
14584562236bSHarry Wentland 
14590a87425aSTony Cheng 		if (tg->funcs->disable_vga)
14604562236bSHarry Wentland 			tg->funcs->disable_vga(tg);
14614562236bSHarry Wentland 
14624562236bSHarry Wentland 		/* Enable CLOCK gating for each pipe BEFORE controller
14634562236bSHarry Wentland 		 * powergating. */
14644562236bSHarry Wentland 		enable_display_pipe_clock_gating(ctx,
14654562236bSHarry Wentland 				true);
14664562236bSHarry Wentland 
1467e6c258cbSYongqiang Sun 		dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i;
1468e6c258cbSYongqiang Sun 		dc->hwss.power_down_front_end(dc,
1469e6c258cbSYongqiang Sun 			&dc->current_state->res_ctx.pipe_ctx[i]);
14704562236bSHarry Wentland 	}
14714562236bSHarry Wentland }
14724562236bSHarry Wentland 
14734562236bSHarry Wentland /**
14744562236bSHarry Wentland  * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
14754562236bSHarry Wentland  *  1. Power down all DC HW blocks
14764562236bSHarry Wentland  *  2. Disable VGA engine on all controllers
14774562236bSHarry Wentland  *  3. Enable power gating for controller
14784562236bSHarry Wentland  *  4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
14794562236bSHarry Wentland  */
1480fb3466a4SBhawanpreet Lakha void dce110_enable_accelerated_mode(struct dc *dc)
14814562236bSHarry Wentland {
14824562236bSHarry Wentland 	power_down_all_hw_blocks(dc);
14834562236bSHarry Wentland 
14844562236bSHarry Wentland 	disable_vga_and_power_gate_all_controllers(dc);
14854562236bSHarry Wentland 	bios_set_scratch_acc_mode_change(dc->ctx->dc_bios);
14864562236bSHarry Wentland }
14874562236bSHarry Wentland 
14884562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration(
14894562236bSHarry Wentland 	struct bw_fixed blackout_duration,
14900971c40eSHarry Wentland 	const struct dc_stream_state *stream)
14914562236bSHarry Wentland {
14924562236bSHarry Wentland 	uint32_t total_dest_line_time_ns;
14934562236bSHarry Wentland 	uint32_t pstate_blackout_duration_ns;
14944562236bSHarry Wentland 
14954562236bSHarry Wentland 	pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
14964562236bSHarry Wentland 
14974562236bSHarry Wentland 	total_dest_line_time_ns = 1000000UL *
14984fa086b9SLeo (Sunpeng) Li 		stream->timing.h_total /
14994fa086b9SLeo (Sunpeng) Li 		stream->timing.pix_clk_khz +
15004562236bSHarry Wentland 		pstate_blackout_duration_ns;
15014562236bSHarry Wentland 
15024562236bSHarry Wentland 	return total_dest_line_time_ns;
15034562236bSHarry Wentland }
15044562236bSHarry Wentland 
15054562236bSHarry Wentland void dce110_set_displaymarks(
1506fb3466a4SBhawanpreet Lakha 	const struct dc *dc,
1507608ac7bbSJerry Zuo 	struct dc_state *context)
15084562236bSHarry Wentland {
15094562236bSHarry Wentland 	uint8_t i, num_pipes;
15104562236bSHarry Wentland 	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
15114562236bSHarry Wentland 
15124562236bSHarry Wentland 	for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) {
15134562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
15144562236bSHarry Wentland 		uint32_t total_dest_line_time_ns;
15154562236bSHarry Wentland 
15164562236bSHarry Wentland 		if (pipe_ctx->stream == NULL)
15174562236bSHarry Wentland 			continue;
15184562236bSHarry Wentland 
15194562236bSHarry Wentland 		total_dest_line_time_ns = compute_pstate_blackout_duration(
152077a4ea53SBhawanpreet Lakha 			dc->bw_vbios->blackout_duration, pipe_ctx->stream);
152186a66c4eSHarry Wentland 		pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
152286a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi,
15239037d802SDmytro Laktyushkin 			context->bw.dce.nbp_state_change_wm_ns[num_pipes],
15249037d802SDmytro Laktyushkin 			context->bw.dce.stutter_exit_wm_ns[num_pipes],
15259037d802SDmytro Laktyushkin 			context->bw.dce.urgent_wm_ns[num_pipes],
15264562236bSHarry Wentland 			total_dest_line_time_ns);
15274562236bSHarry Wentland 		if (i == underlay_idx) {
15284562236bSHarry Wentland 			num_pipes++;
152986a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
153086a66c4eSHarry Wentland 				pipe_ctx->plane_res.mi,
15319037d802SDmytro Laktyushkin 				context->bw.dce.nbp_state_change_wm_ns[num_pipes],
15329037d802SDmytro Laktyushkin 				context->bw.dce.stutter_exit_wm_ns[num_pipes],
15339037d802SDmytro Laktyushkin 				context->bw.dce.urgent_wm_ns[num_pipes],
15344562236bSHarry Wentland 				total_dest_line_time_ns);
15354562236bSHarry Wentland 		}
15364562236bSHarry Wentland 		num_pipes++;
15374562236bSHarry Wentland 	}
15384562236bSHarry Wentland }
15394562236bSHarry Wentland 
1540a2b8659dSTony Cheng static void set_safe_displaymarks(
1541a2b8659dSTony Cheng 		struct resource_context *res_ctx,
1542a2b8659dSTony Cheng 		const struct resource_pool *pool)
15434562236bSHarry Wentland {
15444562236bSHarry Wentland 	int i;
1545a2b8659dSTony Cheng 	int underlay_idx = pool->underlay_pipe_index;
15469037d802SDmytro Laktyushkin 	struct dce_watermarks max_marks = {
15474562236bSHarry Wentland 		MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK };
15489037d802SDmytro Laktyushkin 	struct dce_watermarks nbp_marks = {
15494562236bSHarry Wentland 		SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
15504562236bSHarry Wentland 
15514562236bSHarry Wentland 	for (i = 0; i < MAX_PIPES; i++) {
15528feabd03SYue Hin Lau 		if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
15534562236bSHarry Wentland 			continue;
15544562236bSHarry Wentland 
155586a66c4eSHarry Wentland 		res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
155686a66c4eSHarry Wentland 				res_ctx->pipe_ctx[i].plane_res.mi,
15574562236bSHarry Wentland 				nbp_marks,
15584562236bSHarry Wentland 				max_marks,
15594562236bSHarry Wentland 				max_marks,
15604562236bSHarry Wentland 				MAX_WATERMARK);
15618feabd03SYue Hin Lau 
15624562236bSHarry Wentland 		if (i == underlay_idx)
156386a66c4eSHarry Wentland 			res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
156486a66c4eSHarry Wentland 				res_ctx->pipe_ctx[i].plane_res.mi,
15654562236bSHarry Wentland 				nbp_marks,
15664562236bSHarry Wentland 				max_marks,
15674562236bSHarry Wentland 				max_marks,
15684562236bSHarry Wentland 				MAX_WATERMARK);
15698feabd03SYue Hin Lau 
15704562236bSHarry Wentland 	}
15714562236bSHarry Wentland }
15724562236bSHarry Wentland 
15734562236bSHarry Wentland /*******************************************************************************
15744562236bSHarry Wentland  * Public functions
15754562236bSHarry Wentland  ******************************************************************************/
15764562236bSHarry Wentland 
15774562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx,
15784562236bSHarry Wentland 		int num_pipes, int vmin, int vmax)
15794562236bSHarry Wentland {
15804562236bSHarry Wentland 	int i = 0;
15814562236bSHarry Wentland 	struct drr_params params = {0};
15824562236bSHarry Wentland 
15834562236bSHarry Wentland 	params.vertical_total_max = vmax;
15844562236bSHarry Wentland 	params.vertical_total_min = vmin;
15854562236bSHarry Wentland 
15864562236bSHarry Wentland 	/* TODO: If multiple pipes are to be supported, you need
15874562236bSHarry Wentland 	 * some GSL stuff
15884562236bSHarry Wentland 	 */
15894562236bSHarry Wentland 
15904562236bSHarry Wentland 	for (i = 0; i < num_pipes; i++) {
15916b670fa9SHarry Wentland 		pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, &params);
15924562236bSHarry Wentland 	}
15934562236bSHarry Wentland }
15944562236bSHarry Wentland 
159572ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx,
159672ada5f7SEric Cook 		int num_pipes,
159772ada5f7SEric Cook 		struct crtc_position *position)
159872ada5f7SEric Cook {
159972ada5f7SEric Cook 	int i = 0;
160072ada5f7SEric Cook 
160172ada5f7SEric Cook 	/* TODO: handle pipes > 1
160272ada5f7SEric Cook 	 */
160372ada5f7SEric Cook 	for (i = 0; i < num_pipes; i++)
16046b670fa9SHarry Wentland 		pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
160572ada5f7SEric Cook }
160672ada5f7SEric Cook 
16074562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
160894267b3dSSylvia Tsai 		int num_pipes, const struct dc_static_screen_events *events)
16094562236bSHarry Wentland {
16104562236bSHarry Wentland 	unsigned int i;
161194267b3dSSylvia Tsai 	unsigned int value = 0;
161294267b3dSSylvia Tsai 
161394267b3dSSylvia Tsai 	if (events->overlay_update)
161494267b3dSSylvia Tsai 		value |= 0x100;
161594267b3dSSylvia Tsai 	if (events->surface_update)
161694267b3dSSylvia Tsai 		value |= 0x80;
161794267b3dSSylvia Tsai 	if (events->cursor_update)
161894267b3dSSylvia Tsai 		value |= 0x2;
16194562236bSHarry Wentland 
16203eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
1621c3aa1d67SBhawanpreet Lakha 	value |= 0x84;
1622c3aa1d67SBhawanpreet Lakha #endif
1623c3aa1d67SBhawanpreet Lakha 
16244562236bSHarry Wentland 	for (i = 0; i < num_pipes; i++)
16256b670fa9SHarry Wentland 		pipe_ctx[i]->stream_res.tg->funcs->
16266b670fa9SHarry Wentland 			set_static_screen_control(pipe_ctx[i]->stream_res.tg, value);
16274562236bSHarry Wentland }
16284562236bSHarry Wentland 
16294562236bSHarry Wentland /* unit: in_khz before mode set, get pixel clock from context. ASIC register
16304562236bSHarry Wentland  * may not be programmed yet.
16314562236bSHarry Wentland  * TODO: after mode set, pre_mode_set = false,
16324562236bSHarry Wentland  * may read PLL register to get pixel clock
16334562236bSHarry Wentland  */
16344562236bSHarry Wentland static uint32_t get_max_pixel_clock_for_all_paths(
1635fb3466a4SBhawanpreet Lakha 	struct dc *dc,
1636608ac7bbSJerry Zuo 	struct dc_state *context,
16374562236bSHarry Wentland 	bool pre_mode_set)
16384562236bSHarry Wentland {
16394562236bSHarry Wentland 	uint32_t max_pix_clk = 0;
16404562236bSHarry Wentland 	int i;
16414562236bSHarry Wentland 
16424562236bSHarry Wentland 	if (!pre_mode_set) {
16434562236bSHarry Wentland 		/* TODO: read ASIC register to get pixel clock */
16444562236bSHarry Wentland 		ASSERT(0);
16454562236bSHarry Wentland 	}
16464562236bSHarry Wentland 
16474562236bSHarry Wentland 	for (i = 0; i < MAX_PIPES; i++) {
16484562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
16494562236bSHarry Wentland 
16504562236bSHarry Wentland 		if (pipe_ctx->stream == NULL)
16514562236bSHarry Wentland 			continue;
16524562236bSHarry Wentland 
16534562236bSHarry Wentland 		/* do not check under lay */
16544562236bSHarry Wentland 		if (pipe_ctx->top_pipe)
16554562236bSHarry Wentland 			continue;
16564562236bSHarry Wentland 
165710688217SHarry Wentland 		if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk)
16584562236bSHarry Wentland 			max_pix_clk =
165910688217SHarry Wentland 				pipe_ctx->stream_res.pix_clk_params.requested_pix_clk;
16604562236bSHarry Wentland 	}
16614562236bSHarry Wentland 
16624562236bSHarry Wentland 	if (max_pix_clk == 0)
16634562236bSHarry Wentland 		ASSERT(0);
16644562236bSHarry Wentland 
16654562236bSHarry Wentland 	return max_pix_clk;
16664562236bSHarry Wentland }
16674562236bSHarry Wentland 
1668f6baff4dSHarry Wentland /*
1669f6baff4dSHarry Wentland  * Find clock state based on clock requested. if clock value is 0, simply
16704562236bSHarry Wentland  * set clock state as requested without finding clock state by clock value
16714562236bSHarry Wentland  */
1672f6baff4dSHarry Wentland 
16734562236bSHarry Wentland static void apply_min_clocks(
1674fb3466a4SBhawanpreet Lakha 	struct dc *dc,
1675608ac7bbSJerry Zuo 	struct dc_state *context,
1676e9c58bb4SDmytro Laktyushkin 	enum dm_pp_clocks_state *clocks_state,
16774562236bSHarry Wentland 	bool pre_mode_set)
16784562236bSHarry Wentland {
16794562236bSHarry Wentland 	struct state_dependent_clocks req_clocks = {0};
16804562236bSHarry Wentland 
16814562236bSHarry Wentland 	if (!pre_mode_set) {
16824562236bSHarry Wentland 		/* set clock_state without verification */
1683ab8db3e1SAndrey Grodzovsky 		if (context->dis_clk->funcs->set_min_clocks_state) {
1684ab8db3e1SAndrey Grodzovsky 			context->dis_clk->funcs->set_min_clocks_state(
1685ab8db3e1SAndrey Grodzovsky 						context->dis_clk, *clocks_state);
16864562236bSHarry Wentland 			return;
16875d6d185fSDmytro Laktyushkin 		}
16884562236bSHarry Wentland 
16892c8ad2d5SAlex Deucher 		/* TODO: This is incorrect. Figure out how to fix. */
1690ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->apply_clock_voltage_request(
1691ab8db3e1SAndrey Grodzovsky 				context->dis_clk,
16922c8ad2d5SAlex Deucher 				DM_PP_CLOCK_TYPE_DISPLAY_CLK,
1693ab8db3e1SAndrey Grodzovsky 				context->dis_clk->cur_clocks_value.dispclk_in_khz,
16942c8ad2d5SAlex Deucher 				pre_mode_set,
16952c8ad2d5SAlex Deucher 				false);
16962c8ad2d5SAlex Deucher 
1697ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->apply_clock_voltage_request(
1698ab8db3e1SAndrey Grodzovsky 				context->dis_clk,
16992c8ad2d5SAlex Deucher 				DM_PP_CLOCK_TYPE_PIXELCLK,
1700ab8db3e1SAndrey Grodzovsky 				context->dis_clk->cur_clocks_value.max_pixelclk_in_khz,
17012c8ad2d5SAlex Deucher 				pre_mode_set,
17022c8ad2d5SAlex Deucher 				false);
17032c8ad2d5SAlex Deucher 
1704ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->apply_clock_voltage_request(
1705ab8db3e1SAndrey Grodzovsky 				context->dis_clk,
17062c8ad2d5SAlex Deucher 				DM_PP_CLOCK_TYPE_DISPLAYPHYCLK,
1707ab8db3e1SAndrey Grodzovsky 				context->dis_clk->cur_clocks_value.max_non_dp_phyclk_in_khz,
17082c8ad2d5SAlex Deucher 				pre_mode_set,
17092c8ad2d5SAlex Deucher 				false);
17102c8ad2d5SAlex Deucher 		return;
17114562236bSHarry Wentland 	}
17124562236bSHarry Wentland 
17134562236bSHarry Wentland 	/* get the required state based on state dependent clocks:
17144562236bSHarry Wentland 	 * display clock and pixel clock
17154562236bSHarry Wentland 	 */
17169037d802SDmytro Laktyushkin 	req_clocks.display_clk_khz = context->bw.dce.dispclk_khz;
17174562236bSHarry Wentland 
17184562236bSHarry Wentland 	req_clocks.pixel_clk_khz = get_max_pixel_clock_for_all_paths(
17194562236bSHarry Wentland 			dc, context, true);
17204562236bSHarry Wentland 
1721ab8db3e1SAndrey Grodzovsky 	if (context->dis_clk->funcs->get_required_clocks_state) {
1722ab8db3e1SAndrey Grodzovsky 		*clocks_state = context->dis_clk->funcs->get_required_clocks_state(
1723ab8db3e1SAndrey Grodzovsky 				context->dis_clk, &req_clocks);
1724ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->set_min_clocks_state(
1725ab8db3e1SAndrey Grodzovsky 			context->dis_clk, *clocks_state);
17264562236bSHarry Wentland 	} else {
1727ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->apply_clock_voltage_request(
1728ab8db3e1SAndrey Grodzovsky 				context->dis_clk,
17292c8ad2d5SAlex Deucher 				DM_PP_CLOCK_TYPE_DISPLAY_CLK,
17302c8ad2d5SAlex Deucher 				req_clocks.display_clk_khz,
17312c8ad2d5SAlex Deucher 				pre_mode_set,
17322c8ad2d5SAlex Deucher 				false);
17332c8ad2d5SAlex Deucher 
1734ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->apply_clock_voltage_request(
1735ab8db3e1SAndrey Grodzovsky 				context->dis_clk,
17362c8ad2d5SAlex Deucher 				DM_PP_CLOCK_TYPE_PIXELCLK,
17372c8ad2d5SAlex Deucher 				req_clocks.pixel_clk_khz,
17382c8ad2d5SAlex Deucher 				pre_mode_set,
17392c8ad2d5SAlex Deucher 				false);
17402c8ad2d5SAlex Deucher 
1741ab8db3e1SAndrey Grodzovsky 		context->dis_clk->funcs->apply_clock_voltage_request(
1742ab8db3e1SAndrey Grodzovsky 				context->dis_clk,
17432c8ad2d5SAlex Deucher 				DM_PP_CLOCK_TYPE_DISPLAYPHYCLK,
17442c8ad2d5SAlex Deucher 				req_clocks.pixel_clk_khz,
17452c8ad2d5SAlex Deucher 				pre_mode_set,
17462c8ad2d5SAlex Deucher 				false);
17474562236bSHarry Wentland 	}
17484562236bSHarry Wentland }
17494562236bSHarry Wentland 
17503eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
1751690b5e39SRoman Li 
1752690b5e39SRoman Li /*
1753690b5e39SRoman Li  *  Check if FBC can be enabled
1754690b5e39SRoman Li  */
1755fb3466a4SBhawanpreet Lakha static enum dc_status validate_fbc(struct dc *dc,
1756608ac7bbSJerry Zuo 		struct dc_state *context)
1757690b5e39SRoman Li {
1758690b5e39SRoman Li 	struct pipe_ctx *pipe_ctx =
1759690b5e39SRoman Li 			      &context->res_ctx.pipe_ctx[0];
1760690b5e39SRoman Li 
1761690b5e39SRoman Li 	ASSERT(dc->fbc_compressor);
1762690b5e39SRoman Li 
1763690b5e39SRoman Li 	/* FBC memory should be allocated */
1764690b5e39SRoman Li 	if (!dc->ctx->fbc_gpu_addr)
1765690b5e39SRoman Li 		return DC_ERROR_UNEXPECTED;
1766690b5e39SRoman Li 
1767690b5e39SRoman Li 	/* Only supports single display */
1768690b5e39SRoman Li 	if (context->stream_count != 1)
1769690b5e39SRoman Li 		return DC_ERROR_UNEXPECTED;
1770690b5e39SRoman Li 
1771690b5e39SRoman Li 	/* Only supports eDP */
1772690b5e39SRoman Li 	if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
1773690b5e39SRoman Li 		return DC_ERROR_UNEXPECTED;
1774690b5e39SRoman Li 
1775690b5e39SRoman Li 	/* PSR should not be enabled */
1776690b5e39SRoman Li 	if (pipe_ctx->stream->sink->link->psr_enabled)
1777690b5e39SRoman Li 		return DC_ERROR_UNEXPECTED;
1778690b5e39SRoman Li 
177993984bbcSShirish S 	/* Nothing to compress */
178093984bbcSShirish S 	if (!pipe_ctx->plane_state)
178193984bbcSShirish S 		return DC_ERROR_UNEXPECTED;
178293984bbcSShirish S 
178305230fa9SRoman Li 	/* Only for non-linear tiling */
178405230fa9SRoman Li 	if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
178505230fa9SRoman Li 		return DC_ERROR_UNEXPECTED;
178605230fa9SRoman Li 
1787690b5e39SRoman Li 	return DC_OK;
1788690b5e39SRoman Li }
1789690b5e39SRoman Li 
1790690b5e39SRoman Li /*
1791690b5e39SRoman Li  *  Enable FBC
1792690b5e39SRoman Li  */
1793fb3466a4SBhawanpreet Lakha static enum dc_status enable_fbc(struct dc *dc,
1794608ac7bbSJerry Zuo 		struct dc_state *context)
1795690b5e39SRoman Li {
1796690b5e39SRoman Li 	enum dc_status status = validate_fbc(dc, context);
1797690b5e39SRoman Li 
1798690b5e39SRoman Li 	if (status == DC_OK) {
1799690b5e39SRoman Li 		/* Program GRPH COMPRESSED ADDRESS and PITCH */
1800690b5e39SRoman Li 		struct compr_addr_and_pitch_params params = {0, 0, 0};
1801690b5e39SRoman Li 		struct compressor *compr = dc->fbc_compressor;
1802690b5e39SRoman Li 		struct pipe_ctx *pipe_ctx =
1803690b5e39SRoman Li 				      &context->res_ctx.pipe_ctx[0];
1804690b5e39SRoman Li 
1805690b5e39SRoman Li 		params.source_view_width =
1806690b5e39SRoman Li 				pipe_ctx->stream->timing.h_addressable;
1807690b5e39SRoman Li 		params.source_view_height =
1808690b5e39SRoman Li 				pipe_ctx->stream->timing.v_addressable;
1809690b5e39SRoman Li 
1810690b5e39SRoman Li 		compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
1811690b5e39SRoman Li 
1812690b5e39SRoman Li 		compr->funcs->surface_address_and_pitch(compr, &params);
1813690b5e39SRoman Li 		compr->funcs->set_fbc_invalidation_triggers(compr, 1);
1814690b5e39SRoman Li 
1815690b5e39SRoman Li 		compr->funcs->enable_fbc(compr, &params);
1816690b5e39SRoman Li 	}
1817690b5e39SRoman Li 	return status;
1818690b5e39SRoman Li }
1819690b5e39SRoman Li #endif
1820690b5e39SRoman Li 
18214562236bSHarry Wentland static enum dc_status apply_ctx_to_hw_fpga(
1822fb3466a4SBhawanpreet Lakha 		struct dc *dc,
1823608ac7bbSJerry Zuo 		struct dc_state *context)
18244562236bSHarry Wentland {
18254562236bSHarry Wentland 	enum dc_status status = DC_ERROR_UNEXPECTED;
18264562236bSHarry Wentland 	int i;
18274562236bSHarry Wentland 
1828a2b8659dSTony Cheng 	for (i = 0; i < MAX_PIPES; i++) {
18294562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx_old =
1830608ac7bbSJerry Zuo 				&dc->current_state->res_ctx.pipe_ctx[i];
18314562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
18324562236bSHarry Wentland 
18334562236bSHarry Wentland 		if (pipe_ctx->stream == NULL)
18344562236bSHarry Wentland 			continue;
18354562236bSHarry Wentland 
18364562236bSHarry Wentland 		if (pipe_ctx->stream == pipe_ctx_old->stream)
18374562236bSHarry Wentland 			continue;
18384562236bSHarry Wentland 
18394562236bSHarry Wentland 		status = apply_single_controller_ctx_to_hw(
18404562236bSHarry Wentland 				pipe_ctx,
18414562236bSHarry Wentland 				context,
18424562236bSHarry Wentland 				dc);
18434562236bSHarry Wentland 
18444562236bSHarry Wentland 		if (status != DC_OK)
18454562236bSHarry Wentland 			return status;
18464562236bSHarry Wentland 	}
18474562236bSHarry Wentland 
18484562236bSHarry Wentland 	return DC_OK;
18494562236bSHarry Wentland }
18504562236bSHarry Wentland 
185154e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap(
1852fb3466a4SBhawanpreet Lakha 		struct dc *dc,
1853608ac7bbSJerry Zuo 		struct dc_state *context)
18544562236bSHarry Wentland {
18554562236bSHarry Wentland 	int i;
18564562236bSHarry Wentland 
18574562236bSHarry Wentland 	/* Reset old context */
18584562236bSHarry Wentland 	/* look up the targets that have been removed since last commit */
1859a2b8659dSTony Cheng 	for (i = 0; i < MAX_PIPES; i++) {
18604562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx_old =
1861608ac7bbSJerry Zuo 			&dc->current_state->res_ctx.pipe_ctx[i];
18624562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
18634562236bSHarry Wentland 
18644562236bSHarry Wentland 		/* Note: We need to disable output if clock sources change,
18654562236bSHarry Wentland 		 * since bios does optimization and doesn't apply if changing
18664562236bSHarry Wentland 		 * PHY when not already disabled.
18674562236bSHarry Wentland 		 */
18684562236bSHarry Wentland 
18694562236bSHarry Wentland 		/* Skip underlay pipe since it will be handled in commit surface*/
18704562236bSHarry Wentland 		if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe)
18714562236bSHarry Wentland 			continue;
18724562236bSHarry Wentland 
18734562236bSHarry Wentland 		if (!pipe_ctx->stream ||
187454e8695eSDmytro Laktyushkin 				pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
187521e67d4dSHarry Wentland 			struct clock_source *old_clk = pipe_ctx_old->clock_source;
187621e67d4dSHarry Wentland 
1877827f11e9SLeo (Sunpeng) Li 			/* Disable if new stream is null. O/w, if stream is
1878827f11e9SLeo (Sunpeng) Li 			 * disabled already, no need to disable again.
1879827f11e9SLeo (Sunpeng) Li 			 */
1880827f11e9SLeo (Sunpeng) Li 			if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off)
18814176664bSCharlene Liu 				core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
1882d050f8edSHersen Wu 
18836b670fa9SHarry Wentland 			pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
18846b670fa9SHarry Wentland 			if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
188554e8695eSDmytro Laktyushkin 				dm_error("DC: failed to blank crtc!\n");
188654e8695eSDmytro Laktyushkin 				BREAK_TO_DEBUGGER();
188754e8695eSDmytro Laktyushkin 			}
18886b670fa9SHarry Wentland 			pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg);
188986a66c4eSHarry Wentland 			pipe_ctx_old->plane_res.mi->funcs->free_mem_input(
1890608ac7bbSJerry Zuo 					pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
189154e8695eSDmytro Laktyushkin 
189221e67d4dSHarry Wentland 			if (old_clk)
189321e67d4dSHarry Wentland 				old_clk->funcs->cs_power_down(old_clk);
189421e67d4dSHarry Wentland 
1895e6c258cbSYongqiang Sun 			dc->hwss.power_down_front_end(dc, pipe_ctx_old);
189654e8695eSDmytro Laktyushkin 
189754e8695eSDmytro Laktyushkin 			pipe_ctx_old->stream = NULL;
189854e8695eSDmytro Laktyushkin 		}
18994562236bSHarry Wentland 	}
19004562236bSHarry Wentland }
19014562236bSHarry Wentland 
1902cf437593SDmytro Laktyushkin 
19034562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw(
1904fb3466a4SBhawanpreet Lakha 		struct dc *dc,
1905608ac7bbSJerry Zuo 		struct dc_state *context)
19064562236bSHarry Wentland {
19074562236bSHarry Wentland 	struct dc_bios *dcb = dc->ctx->dc_bios;
19084562236bSHarry Wentland 	enum dc_status status;
19094562236bSHarry Wentland 	int i;
1910e9c58bb4SDmytro Laktyushkin 	enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID;
19114562236bSHarry Wentland 
19124562236bSHarry Wentland 	/* Reset old context */
19134562236bSHarry Wentland 	/* look up the targets that have been removed since last commit */
19144562236bSHarry Wentland 	dc->hwss.reset_hw_ctx_wrap(dc, context);
19154562236bSHarry Wentland 
19164562236bSHarry Wentland 	/* Skip applying if no targets */
1917ab2541b6SAric Cyr 	if (context->stream_count <= 0)
19184562236bSHarry Wentland 		return DC_OK;
19194562236bSHarry Wentland 
19204562236bSHarry Wentland 	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
19214562236bSHarry Wentland 		apply_ctx_to_hw_fpga(dc, context);
19224562236bSHarry Wentland 		return DC_OK;
19234562236bSHarry Wentland 	}
19244562236bSHarry Wentland 
19254562236bSHarry Wentland 	/* Apply new context */
19264562236bSHarry Wentland 	dcb->funcs->set_scratch_critical_state(dcb, true);
19274562236bSHarry Wentland 
19284562236bSHarry Wentland 	/* below is for real asic only */
1929a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
19304562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx_old =
1931608ac7bbSJerry Zuo 					&dc->current_state->res_ctx.pipe_ctx[i];
19324562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
19334562236bSHarry Wentland 
19344562236bSHarry Wentland 		if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe)
19354562236bSHarry Wentland 			continue;
19364562236bSHarry Wentland 
19374562236bSHarry Wentland 		if (pipe_ctx->stream == pipe_ctx_old->stream) {
19384562236bSHarry Wentland 			if (pipe_ctx_old->clock_source != pipe_ctx->clock_source)
19394562236bSHarry Wentland 				dce_crtc_switch_to_clk_src(dc->hwseq,
19404562236bSHarry Wentland 						pipe_ctx->clock_source, i);
19414562236bSHarry Wentland 			continue;
19424562236bSHarry Wentland 		}
19434562236bSHarry Wentland 
19444562236bSHarry Wentland 		dc->hwss.enable_display_power_gating(
19454562236bSHarry Wentland 				dc, i, dc->ctx->dc_bios,
19464562236bSHarry Wentland 				PIPE_GATING_CONTROL_DISABLE);
19474562236bSHarry Wentland 	}
19484562236bSHarry Wentland 
1949a2b8659dSTony Cheng 	set_safe_displaymarks(&context->res_ctx, dc->res_pool);
19501663ae1cSBhawanpreet Lakha 
19513eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
19522f3bfb27SRoman Li 	if (dc->fbc_compressor)
19531663ae1cSBhawanpreet Lakha 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
19541663ae1cSBhawanpreet Lakha #endif
19554562236bSHarry Wentland 	/*TODO: when pplib works*/
19564562236bSHarry Wentland 	apply_min_clocks(dc, context, &clocks_state, true);
19574562236bSHarry Wentland 
1958ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
19593639fa68SZeyu Fan 	if (dc->ctx->dce_version >= DCN_VERSION_1_0) {
19609037d802SDmytro Laktyushkin 		if (context->bw.dcn.calc_clk.fclk_khz
1961608ac7bbSJerry Zuo 				> dc->current_state->bw.dcn.cur_clk.fclk_khz) {
1962ff5ef992SAlex Deucher 			struct dm_pp_clock_for_voltage_req clock;
1963ff5ef992SAlex Deucher 
1964ff5ef992SAlex Deucher 			clock.clk_type = DM_PP_CLOCK_TYPE_FCLK;
19659037d802SDmytro Laktyushkin 			clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz;
1966ff5ef992SAlex Deucher 			dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock);
1967608ac7bbSJerry Zuo 			dc->current_state->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz;
1968c66a54dcSDmytro Laktyushkin 			context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz;
1969ff5ef992SAlex Deucher 		}
19709037d802SDmytro Laktyushkin 		if (context->bw.dcn.calc_clk.dcfclk_khz
1971608ac7bbSJerry Zuo 				> dc->current_state->bw.dcn.cur_clk.dcfclk_khz) {
1972ff5ef992SAlex Deucher 			struct dm_pp_clock_for_voltage_req clock;
1973ff5ef992SAlex Deucher 
1974ff5ef992SAlex Deucher 			clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK;
19759037d802SDmytro Laktyushkin 			clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz;
1976ff5ef992SAlex Deucher 			dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock);
1977608ac7bbSJerry Zuo 			dc->current_state->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz;
1978c66a54dcSDmytro Laktyushkin 			context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz;
1979ff5ef992SAlex Deucher 		}
1980c66a54dcSDmytro Laktyushkin 		if (context->bw.dcn.calc_clk.dispclk_khz
1981608ac7bbSJerry Zuo 				> dc->current_state->bw.dcn.cur_clk.dispclk_khz) {
1982c66a54dcSDmytro Laktyushkin 			dc->res_pool->display_clock->funcs->set_clock(
1983c66a54dcSDmytro Laktyushkin 					dc->res_pool->display_clock,
1984c66a54dcSDmytro Laktyushkin 					context->bw.dcn.calc_clk.dispclk_khz);
1985608ac7bbSJerry Zuo 			dc->current_state->bw.dcn.cur_clk.dispclk_khz =
1986c66a54dcSDmytro Laktyushkin 					context->bw.dcn.calc_clk.dispclk_khz;
1987c66a54dcSDmytro Laktyushkin 			context->bw.dcn.cur_clk.dispclk_khz =
1988c66a54dcSDmytro Laktyushkin 					context->bw.dcn.calc_clk.dispclk_khz;
1989c66a54dcSDmytro Laktyushkin 		}
1990c66a54dcSDmytro Laktyushkin 	} else
1991ff5ef992SAlex Deucher #endif
19929037d802SDmytro Laktyushkin 	if (context->bw.dce.dispclk_khz
1993608ac7bbSJerry Zuo 			> dc->current_state->bw.dce.dispclk_khz) {
1994a2b8659dSTony Cheng 		dc->res_pool->display_clock->funcs->set_clock(
1995a2b8659dSTony Cheng 				dc->res_pool->display_clock,
19969037d802SDmytro Laktyushkin 				context->bw.dce.dispclk_khz * 115 / 100);
19971ce71fcdSCharlene Liu 	}
1998ab8812a3SHersen Wu 	/* program audio wall clock. use HDMI as clock source if HDMI
1999ab8812a3SHersen Wu 	 * audio active. Otherwise, use DP as clock source
2000ab8812a3SHersen Wu 	 * first, loop to find any HDMI audio, if not, loop find DP audio
2001ab8812a3SHersen Wu 	 */
20024562236bSHarry Wentland 	/* Setup audio rate clock source */
20034562236bSHarry Wentland 	/* Issue:
20044562236bSHarry Wentland 	* Audio lag happened on DP monitor when unplug a HDMI monitor
20054562236bSHarry Wentland 	*
20064562236bSHarry Wentland 	* Cause:
20074562236bSHarry Wentland 	* In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL
20084562236bSHarry Wentland 	* is set to either dto0 or dto1, audio should work fine.
20094562236bSHarry Wentland 	* In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1,
20104562236bSHarry Wentland 	* set to dto0 will cause audio lag.
20114562236bSHarry Wentland 	*
20124562236bSHarry Wentland 	* Solution:
20134562236bSHarry Wentland 	* Not optimized audio wall dto setup. When mode set, iterate pipe_ctx,
20144562236bSHarry Wentland 	* find first available pipe with audio, setup audio wall DTO per topology
20154562236bSHarry Wentland 	* instead of per pipe.
20164562236bSHarry Wentland 	*/
2017a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2018ab8812a3SHersen Wu 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2019ab8812a3SHersen Wu 
2020ab8812a3SHersen Wu 		if (pipe_ctx->stream == NULL)
2021ab8812a3SHersen Wu 			continue;
2022ab8812a3SHersen Wu 
2023ab8812a3SHersen Wu 		if (pipe_ctx->top_pipe)
2024ab8812a3SHersen Wu 			continue;
2025ab8812a3SHersen Wu 
2026ab8812a3SHersen Wu 		if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
2027ab8812a3SHersen Wu 			continue;
2028ab8812a3SHersen Wu 
2029afaacef4SHarry Wentland 		if (pipe_ctx->stream_res.audio != NULL) {
2030ab8812a3SHersen Wu 			struct audio_output audio_output;
2031ab8812a3SHersen Wu 
2032ab8db3e1SAndrey Grodzovsky 			build_audio_output(context, pipe_ctx, &audio_output);
2033ab8812a3SHersen Wu 
2034afaacef4SHarry Wentland 			pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
2035afaacef4SHarry Wentland 				pipe_ctx->stream_res.audio,
2036ab8812a3SHersen Wu 				pipe_ctx->stream->signal,
2037ab8812a3SHersen Wu 				&audio_output.crtc_info,
2038ab8812a3SHersen Wu 				&audio_output.pll_info);
2039ab8812a3SHersen Wu 			break;
2040ab8812a3SHersen Wu 		}
2041ab8812a3SHersen Wu 	}
2042ab8812a3SHersen Wu 
2043ab8812a3SHersen Wu 	/* no HDMI audio is found, try DP audio */
2044a2b8659dSTony Cheng 	if (i == dc->res_pool->pipe_count) {
2045a2b8659dSTony Cheng 		for (i = 0; i < dc->res_pool->pipe_count; i++) {
2046ab8812a3SHersen Wu 			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2047ab8812a3SHersen Wu 
2048ab8812a3SHersen Wu 			if (pipe_ctx->stream == NULL)
2049ab8812a3SHersen Wu 				continue;
2050ab8812a3SHersen Wu 
2051ab8812a3SHersen Wu 			if (pipe_ctx->top_pipe)
2052ab8812a3SHersen Wu 				continue;
2053ab8812a3SHersen Wu 
2054ab8812a3SHersen Wu 			if (!dc_is_dp_signal(pipe_ctx->stream->signal))
2055ab8812a3SHersen Wu 				continue;
2056ab8812a3SHersen Wu 
2057afaacef4SHarry Wentland 			if (pipe_ctx->stream_res.audio != NULL) {
2058ab8812a3SHersen Wu 				struct audio_output audio_output;
2059ab8812a3SHersen Wu 
2060ab8db3e1SAndrey Grodzovsky 				build_audio_output(context, pipe_ctx, &audio_output);
2061ab8812a3SHersen Wu 
2062afaacef4SHarry Wentland 				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
2063afaacef4SHarry Wentland 					pipe_ctx->stream_res.audio,
2064ab8812a3SHersen Wu 					pipe_ctx->stream->signal,
2065ab8812a3SHersen Wu 					&audio_output.crtc_info,
2066ab8812a3SHersen Wu 					&audio_output.pll_info);
2067ab8812a3SHersen Wu 				break;
2068ab8812a3SHersen Wu 			}
2069ab8812a3SHersen Wu 		}
2070ab8812a3SHersen Wu 	}
2071ab8812a3SHersen Wu 
2072a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2073ab8812a3SHersen Wu 		struct pipe_ctx *pipe_ctx_old =
2074608ac7bbSJerry Zuo 					&dc->current_state->res_ctx.pipe_ctx[i];
2075ab8812a3SHersen Wu 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2076ab8812a3SHersen Wu 
2077ab8812a3SHersen Wu 		if (pipe_ctx->stream == NULL)
2078ab8812a3SHersen Wu 			continue;
2079ab8812a3SHersen Wu 
2080ab8812a3SHersen Wu 		if (pipe_ctx->stream == pipe_ctx_old->stream)
2081ab8812a3SHersen Wu 			continue;
2082ab8812a3SHersen Wu 
2083313bf4ffSYongqiang Sun 		if (pipe_ctx->stream && pipe_ctx_old->stream
2084313bf4ffSYongqiang Sun 				&& !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
2085313bf4ffSYongqiang Sun 			continue;
2086313bf4ffSYongqiang Sun 
2087ab8812a3SHersen Wu 		if (pipe_ctx->top_pipe)
2088ab8812a3SHersen Wu 			continue;
2089ab8812a3SHersen Wu 
2090afaacef4SHarry Wentland 		if (context->res_ctx.pipe_ctx[i].stream_res.audio != NULL) {
2091ab8812a3SHersen Wu 
20924562236bSHarry Wentland 			struct audio_output audio_output;
20934562236bSHarry Wentland 
2094ab8db3e1SAndrey Grodzovsky 			build_audio_output(context, pipe_ctx, &audio_output);
20954562236bSHarry Wentland 
20964562236bSHarry Wentland 			if (dc_is_dp_signal(pipe_ctx->stream->signal))
20978e9c4c8cSHarry Wentland 				pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
20988e9c4c8cSHarry Wentland 						pipe_ctx->stream_res.stream_enc,
2099afaacef4SHarry Wentland 						pipe_ctx->stream_res.audio->inst,
21004fa086b9SLeo (Sunpeng) Li 						&pipe_ctx->stream->audio_info);
21014562236bSHarry Wentland 			else
21028e9c4c8cSHarry Wentland 				pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup(
21038e9c4c8cSHarry Wentland 						pipe_ctx->stream_res.stream_enc,
2104afaacef4SHarry Wentland 						pipe_ctx->stream_res.audio->inst,
21054fa086b9SLeo (Sunpeng) Li 						&pipe_ctx->stream->audio_info,
21064562236bSHarry Wentland 						&audio_output.crtc_info);
21074562236bSHarry Wentland 
2108afaacef4SHarry Wentland 			pipe_ctx->stream_res.audio->funcs->az_configure(
2109afaacef4SHarry Wentland 					pipe_ctx->stream_res.audio,
21104562236bSHarry Wentland 					pipe_ctx->stream->signal,
21114562236bSHarry Wentland 					&audio_output.crtc_info,
21124fa086b9SLeo (Sunpeng) Li 					&pipe_ctx->stream->audio_info);
21134562236bSHarry Wentland 		}
21144562236bSHarry Wentland 
21154562236bSHarry Wentland 		status = apply_single_controller_ctx_to_hw(
21164562236bSHarry Wentland 				pipe_ctx,
21174562236bSHarry Wentland 				context,
21184562236bSHarry Wentland 				dc);
21194562236bSHarry Wentland 
212018f7a1e4SYongqiang Sun 		if (dc->hwss.power_on_front_end)
212118f7a1e4SYongqiang Sun 			dc->hwss.power_on_front_end(dc, pipe_ctx, context);
212218f7a1e4SYongqiang Sun 
21234562236bSHarry Wentland 		if (DC_OK != status)
21244562236bSHarry Wentland 			return status;
21254562236bSHarry Wentland 	}
21264562236bSHarry Wentland 
21276bf52028SHersen Wu 	/* pplib is notified if disp_num changed */
2128cf437593SDmytro Laktyushkin 	dc->hwss.set_bandwidth(dc, context, true);
21294562236bSHarry Wentland 
21304562236bSHarry Wentland 	/* to save power */
21314562236bSHarry Wentland 	apply_min_clocks(dc, context, &clocks_state, false);
21324562236bSHarry Wentland 
21334562236bSHarry Wentland 	dcb->funcs->set_scratch_critical_state(dcb, false);
21344562236bSHarry Wentland 
21353eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
2136690b5e39SRoman Li 	if (dc->fbc_compressor)
2137690b5e39SRoman Li 		enable_fbc(dc, context);
2138690b5e39SRoman Li 
2139690b5e39SRoman Li #endif
2140cf437593SDmytro Laktyushkin 
21414562236bSHarry Wentland 	return DC_OK;
21424562236bSHarry Wentland }
21434562236bSHarry Wentland 
21444562236bSHarry Wentland /*******************************************************************************
21454562236bSHarry Wentland  * Front End programming
21464562236bSHarry Wentland  ******************************************************************************/
21474562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx)
21484562236bSHarry Wentland {
21494562236bSHarry Wentland 	struct default_adjustment default_adjust = { 0 };
21504562236bSHarry Wentland 
21514562236bSHarry Wentland 	default_adjust.force_hw_default = false;
21523be5262eSHarry Wentland 	if (pipe_ctx->plane_state == NULL)
21534562236bSHarry Wentland 		default_adjust.in_color_space = COLOR_SPACE_SRGB;
21544562236bSHarry Wentland 	else
21554562236bSHarry Wentland 		default_adjust.in_color_space =
21563be5262eSHarry Wentland 				pipe_ctx->plane_state->color_space;
21574562236bSHarry Wentland 	if (pipe_ctx->stream == NULL)
21584562236bSHarry Wentland 		default_adjust.out_color_space = COLOR_SPACE_SRGB;
21594562236bSHarry Wentland 	else
21604562236bSHarry Wentland 		default_adjust.out_color_space =
21614fa086b9SLeo (Sunpeng) Li 				pipe_ctx->stream->output_color_space;
21624562236bSHarry Wentland 	default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
21636702a9acSHarry Wentland 	default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
21644562236bSHarry Wentland 
21654562236bSHarry Wentland 	/* display color depth */
21664562236bSHarry Wentland 	default_adjust.color_depth =
21674fa086b9SLeo (Sunpeng) Li 		pipe_ctx->stream->timing.display_color_depth;
21684562236bSHarry Wentland 
21694562236bSHarry Wentland 	/* Lb color depth */
21706702a9acSHarry Wentland 	default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
21714562236bSHarry Wentland 
217286a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
217386a66c4eSHarry Wentland 					pipe_ctx->plane_res.xfm, &default_adjust);
21744562236bSHarry Wentland }
21754562236bSHarry Wentland 
2176b06b7680SLeon Elazar 
2177b06b7680SLeon Elazar /*******************************************************************************
2178b06b7680SLeon Elazar  * In order to turn on/off specific surface we will program
2179b06b7680SLeon Elazar  * Blender + CRTC
2180b06b7680SLeon Elazar  *
2181b06b7680SLeon Elazar  * In case that we have two surfaces and they have a different visibility
2182b06b7680SLeon Elazar  * we can't turn off the CRTC since it will turn off the entire display
2183b06b7680SLeon Elazar  *
2184b06b7680SLeon Elazar  * |----------------------------------------------- |
2185b06b7680SLeon Elazar  * |bottom pipe|curr pipe  |              |         |
2186b06b7680SLeon Elazar  * |Surface    |Surface    | Blender      |  CRCT   |
2187b06b7680SLeon Elazar  * |visibility |visibility | Configuration|         |
2188b06b7680SLeon Elazar  * |------------------------------------------------|
2189b06b7680SLeon Elazar  * |   off     |    off    | CURRENT_PIPE | blank   |
2190b06b7680SLeon Elazar  * |   off     |    on     | CURRENT_PIPE | unblank |
2191b06b7680SLeon Elazar  * |   on      |    off    | OTHER_PIPE   | unblank |
2192b06b7680SLeon Elazar  * |   on      |    on     | BLENDING     | unblank |
2193b06b7680SLeon Elazar  * -------------------------------------------------|
2194b06b7680SLeon Elazar  *
2195b06b7680SLeon Elazar  ******************************************************************************/
2196fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc,
21974562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx)
21984562236bSHarry Wentland {
21994562236bSHarry Wentland 	enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE;
2200b06b7680SLeon Elazar 	bool blank_target = false;
22014562236bSHarry Wentland 
22024562236bSHarry Wentland 	if (pipe_ctx->bottom_pipe) {
2203b06b7680SLeon Elazar 
2204b06b7680SLeon Elazar 		/* For now we are supporting only two pipes */
2205b06b7680SLeon Elazar 		ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL);
2206b06b7680SLeon Elazar 
22073be5262eSHarry Wentland 		if (pipe_ctx->bottom_pipe->plane_state->visible) {
22083be5262eSHarry Wentland 			if (pipe_ctx->plane_state->visible)
22094562236bSHarry Wentland 				blender_mode = BLND_MODE_BLENDING;
22104562236bSHarry Wentland 			else
22114562236bSHarry Wentland 				blender_mode = BLND_MODE_OTHER_PIPE;
2212b06b7680SLeon Elazar 
22133be5262eSHarry Wentland 		} else if (!pipe_ctx->plane_state->visible)
2214b06b7680SLeon Elazar 			blank_target = true;
2215b06b7680SLeon Elazar 
22163be5262eSHarry Wentland 	} else if (!pipe_ctx->plane_state->visible)
2217b06b7680SLeon Elazar 		blank_target = true;
2218b06b7680SLeon Elazar 
22194562236bSHarry Wentland 	dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode);
22206b670fa9SHarry Wentland 	pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
2221b06b7680SLeon Elazar 
22224562236bSHarry Wentland }
22234562236bSHarry Wentland 
22241bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
22251bf56e62SZeyu Fan {
22261bf56e62SZeyu Fan 	struct xfm_grph_csc_adjustment adjust;
22271bf56e62SZeyu Fan 	memset(&adjust, 0, sizeof(adjust));
22281bf56e62SZeyu Fan 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
22291bf56e62SZeyu Fan 
22301bf56e62SZeyu Fan 
22314fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
22321bf56e62SZeyu Fan 		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
22331bf56e62SZeyu Fan 		adjust.temperature_matrix[0] =
22341bf56e62SZeyu Fan 				pipe_ctx->stream->
22354fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[0];
22361bf56e62SZeyu Fan 		adjust.temperature_matrix[1] =
22371bf56e62SZeyu Fan 				pipe_ctx->stream->
22384fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[1];
22391bf56e62SZeyu Fan 		adjust.temperature_matrix[2] =
22401bf56e62SZeyu Fan 				pipe_ctx->stream->
22414fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[2];
22421bf56e62SZeyu Fan 		adjust.temperature_matrix[3] =
22431bf56e62SZeyu Fan 				pipe_ctx->stream->
22444fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[4];
22451bf56e62SZeyu Fan 		adjust.temperature_matrix[4] =
22461bf56e62SZeyu Fan 				pipe_ctx->stream->
22474fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[5];
22481bf56e62SZeyu Fan 		adjust.temperature_matrix[5] =
22491bf56e62SZeyu Fan 				pipe_ctx->stream->
22504fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[6];
22511bf56e62SZeyu Fan 		adjust.temperature_matrix[6] =
22521bf56e62SZeyu Fan 				pipe_ctx->stream->
22534fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[8];
22541bf56e62SZeyu Fan 		adjust.temperature_matrix[7] =
22551bf56e62SZeyu Fan 				pipe_ctx->stream->
22564fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[9];
22571bf56e62SZeyu Fan 		adjust.temperature_matrix[8] =
22581bf56e62SZeyu Fan 				pipe_ctx->stream->
22594fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[10];
22601bf56e62SZeyu Fan 	}
22611bf56e62SZeyu Fan 
226286a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
22631bf56e62SZeyu Fan }
22641bf56e62SZeyu Fan 
22654562236bSHarry Wentland /**
22664562236bSHarry Wentland  * TODO REMOVE, USE UPDATE INSTEAD
22674562236bSHarry Wentland  */
22684562236bSHarry Wentland static void set_plane_config(
2269fb3466a4SBhawanpreet Lakha 	const struct dc *dc,
22704562236bSHarry Wentland 	struct pipe_ctx *pipe_ctx,
22714562236bSHarry Wentland 	struct resource_context *res_ctx)
22724562236bSHarry Wentland {
227386a66c4eSHarry Wentland 	struct mem_input *mi = pipe_ctx->plane_res.mi;
22743be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
22754562236bSHarry Wentland 	struct xfm_grph_csc_adjustment adjust;
22764562236bSHarry Wentland 	struct out_csc_color_matrix tbl_entry;
22774562236bSHarry Wentland 	unsigned int i;
22784562236bSHarry Wentland 
22794562236bSHarry Wentland 	memset(&adjust, 0, sizeof(adjust));
22804562236bSHarry Wentland 	memset(&tbl_entry, 0, sizeof(tbl_entry));
22814562236bSHarry Wentland 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
22824562236bSHarry Wentland 
22834562236bSHarry Wentland 	dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
22844562236bSHarry Wentland 
22854562236bSHarry Wentland 	set_default_colors(pipe_ctx);
228656ef6ed9SAnthony Koo 	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
22874562236bSHarry Wentland 		tbl_entry.color_space =
22884fa086b9SLeo (Sunpeng) Li 			pipe_ctx->stream->output_color_space;
22894562236bSHarry Wentland 
22904562236bSHarry Wentland 		for (i = 0; i < 12; i++)
22914562236bSHarry Wentland 			tbl_entry.regval[i] =
22924fa086b9SLeo (Sunpeng) Li 			pipe_ctx->stream->csc_color_matrix.matrix[i];
22934562236bSHarry Wentland 
229486a66c4eSHarry Wentland 		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
229586a66c4eSHarry Wentland 				(pipe_ctx->plane_res.xfm, &tbl_entry);
22964562236bSHarry Wentland 	}
22974562236bSHarry Wentland 
22984fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
22994562236bSHarry Wentland 		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
23004562236bSHarry Wentland 		adjust.temperature_matrix[0] =
23014562236bSHarry Wentland 				pipe_ctx->stream->
23024fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[0];
23034562236bSHarry Wentland 		adjust.temperature_matrix[1] =
23044562236bSHarry Wentland 				pipe_ctx->stream->
23054fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[1];
23064562236bSHarry Wentland 		adjust.temperature_matrix[2] =
23074562236bSHarry Wentland 				pipe_ctx->stream->
23084fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[2];
23094562236bSHarry Wentland 		adjust.temperature_matrix[3] =
23104562236bSHarry Wentland 				pipe_ctx->stream->
23114fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[4];
23124562236bSHarry Wentland 		adjust.temperature_matrix[4] =
23134562236bSHarry Wentland 				pipe_ctx->stream->
23144fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[5];
23154562236bSHarry Wentland 		adjust.temperature_matrix[5] =
23164562236bSHarry Wentland 				pipe_ctx->stream->
23174fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[6];
23184562236bSHarry Wentland 		adjust.temperature_matrix[6] =
23194562236bSHarry Wentland 				pipe_ctx->stream->
23204fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[8];
23214562236bSHarry Wentland 		adjust.temperature_matrix[7] =
23224562236bSHarry Wentland 				pipe_ctx->stream->
23234fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[9];
23244562236bSHarry Wentland 		adjust.temperature_matrix[8] =
23254562236bSHarry Wentland 				pipe_ctx->stream->
23264fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[10];
23274562236bSHarry Wentland 	}
23284562236bSHarry Wentland 
232986a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
23304562236bSHarry Wentland 
23316702a9acSHarry Wentland 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
23324562236bSHarry Wentland 	program_scaler(dc, pipe_ctx);
23334562236bSHarry Wentland 
2334b06b7680SLeon Elazar 	program_surface_visibility(dc, pipe_ctx);
23354562236bSHarry Wentland 
23364562236bSHarry Wentland 	mi->funcs->mem_input_program_surface_config(
23374562236bSHarry Wentland 			mi,
23383be5262eSHarry Wentland 			plane_state->format,
23393be5262eSHarry Wentland 			&plane_state->tiling_info,
23403be5262eSHarry Wentland 			&plane_state->plane_size,
23413be5262eSHarry Wentland 			plane_state->rotation,
23424562236bSHarry Wentland 			NULL,
23434b28b76bSDmytro Laktyushkin 			false);
23444b28b76bSDmytro Laktyushkin 	if (mi->funcs->set_blank)
23453be5262eSHarry Wentland 		mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
23464562236bSHarry Wentland 
2347fb3466a4SBhawanpreet Lakha 	if (dc->config.gpu_vm_support)
23484562236bSHarry Wentland 		mi->funcs->mem_input_program_pte_vm(
234986a66c4eSHarry Wentland 				pipe_ctx->plane_res.mi,
23503be5262eSHarry Wentland 				plane_state->format,
23513be5262eSHarry Wentland 				&plane_state->tiling_info,
23523be5262eSHarry Wentland 				plane_state->rotation);
23534562236bSHarry Wentland }
23544562236bSHarry Wentland 
2355fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc,
23564562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx)
23574562236bSHarry Wentland {
23583be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
23594562236bSHarry Wentland 
23603be5262eSHarry Wentland 	if (plane_state == NULL)
23614562236bSHarry Wentland 		return;
23624562236bSHarry Wentland 
236386a66c4eSHarry Wentland 	pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
236486a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi,
23653be5262eSHarry Wentland 			&plane_state->address,
23663be5262eSHarry Wentland 			plane_state->flip_immediate);
23674562236bSHarry Wentland 
23683be5262eSHarry Wentland 	plane_state->status.requested_address = plane_state->address;
23694562236bSHarry Wentland }
23704562236bSHarry Wentland 
23714562236bSHarry Wentland void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
23724562236bSHarry Wentland {
23733be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
23744562236bSHarry Wentland 
23753be5262eSHarry Wentland 	if (plane_state == NULL)
23764562236bSHarry Wentland 		return;
23774562236bSHarry Wentland 
23783be5262eSHarry Wentland 	plane_state->status.is_flip_pending =
237986a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
238086a66c4eSHarry Wentland 					pipe_ctx->plane_res.mi);
23814562236bSHarry Wentland 
23823be5262eSHarry Wentland 	if (plane_state->status.is_flip_pending && !plane_state->visible)
238386a66c4eSHarry Wentland 		pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address;
23844562236bSHarry Wentland 
238586a66c4eSHarry Wentland 	plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
238686a66c4eSHarry Wentland 	if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
23876b670fa9SHarry Wentland 			pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) {
23883be5262eSHarry Wentland 		plane_state->status.is_right_eye =\
23896b670fa9SHarry Wentland 				!pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
23907f5c22d1SVitaly Prosyak 	}
23914562236bSHarry Wentland }
23924562236bSHarry Wentland 
2393fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc)
23944562236bSHarry Wentland {
23954562236bSHarry Wentland 	power_down_all_hw_blocks(dc);
23964562236bSHarry Wentland 	disable_vga_and_power_gate_all_controllers(dc);
23974562236bSHarry Wentland }
23984562236bSHarry Wentland 
23994562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur(
24004562236bSHarry Wentland 	struct dc_context *dc_ctx,
24014562236bSHarry Wentland 	struct timing_generator *tg)
24024562236bSHarry Wentland {
24034562236bSHarry Wentland 	bool rc = false;
24044562236bSHarry Wentland 
24054562236bSHarry Wentland 	/* To avoid endless loop we wait at most
24064562236bSHarry Wentland 	 * frames_to_wait_on_triggered_reset frames for the reset to occur. */
24074562236bSHarry Wentland 	const uint32_t frames_to_wait_on_triggered_reset = 10;
24084562236bSHarry Wentland 	uint32_t i;
24094562236bSHarry Wentland 
24104562236bSHarry Wentland 	for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
24114562236bSHarry Wentland 
24124562236bSHarry Wentland 		if (!tg->funcs->is_counter_moving(tg)) {
24134562236bSHarry Wentland 			DC_ERROR("TG counter is not moving!\n");
24144562236bSHarry Wentland 			break;
24154562236bSHarry Wentland 		}
24164562236bSHarry Wentland 
24174562236bSHarry Wentland 		if (tg->funcs->did_triggered_reset_occur(tg)) {
24184562236bSHarry Wentland 			rc = true;
24194562236bSHarry Wentland 			/* usually occurs at i=1 */
24204562236bSHarry Wentland 			DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
24214562236bSHarry Wentland 					i);
24224562236bSHarry Wentland 			break;
24234562236bSHarry Wentland 		}
24244562236bSHarry Wentland 
24254562236bSHarry Wentland 		/* Wait for one frame. */
24264562236bSHarry Wentland 		tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
24274562236bSHarry Wentland 		tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
24284562236bSHarry Wentland 	}
24294562236bSHarry Wentland 
24304562236bSHarry Wentland 	if (false == rc)
24314562236bSHarry Wentland 		DC_ERROR("GSL: Timeout on reset trigger!\n");
24324562236bSHarry Wentland 
24334562236bSHarry Wentland 	return rc;
24344562236bSHarry Wentland }
24354562236bSHarry Wentland 
24364562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */
24374562236bSHarry Wentland static void dce110_enable_timing_synchronization(
2438fb3466a4SBhawanpreet Lakha 		struct dc *dc,
24394562236bSHarry Wentland 		int group_index,
24404562236bSHarry Wentland 		int group_size,
24414562236bSHarry Wentland 		struct pipe_ctx *grouped_pipes[])
24424562236bSHarry Wentland {
24434562236bSHarry Wentland 	struct dc_context *dc_ctx = dc->ctx;
24444562236bSHarry Wentland 	struct dcp_gsl_params gsl_params = { 0 };
24454562236bSHarry Wentland 	int i;
24464562236bSHarry Wentland 
24474562236bSHarry Wentland 	DC_SYNC_INFO("GSL: Setting-up...\n");
24484562236bSHarry Wentland 
24494562236bSHarry Wentland 	/* Designate a single TG in the group as a master.
24504562236bSHarry Wentland 	 * Since HW doesn't care which one, we always assign
24514562236bSHarry Wentland 	 * the 1st one in the group. */
24524562236bSHarry Wentland 	gsl_params.gsl_group = 0;
24536b670fa9SHarry Wentland 	gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst;
24544562236bSHarry Wentland 
24554562236bSHarry Wentland 	for (i = 0; i < group_size; i++)
24566b670fa9SHarry Wentland 		grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
24576b670fa9SHarry Wentland 					grouped_pipes[i]->stream_res.tg, &gsl_params);
24584562236bSHarry Wentland 
24594562236bSHarry Wentland 	/* Reset slave controllers on master VSync */
24604562236bSHarry Wentland 	DC_SYNC_INFO("GSL: enabling trigger-reset\n");
24614562236bSHarry Wentland 
24624562236bSHarry Wentland 	for (i = 1 /* skip the master */; i < group_size; i++)
24636b670fa9SHarry Wentland 		grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
2464fa2123dbSMikita Lipski 				grouped_pipes[i]->stream_res.tg,
2465fa2123dbSMikita Lipski 				gsl_params.gsl_group);
24664562236bSHarry Wentland 
24674562236bSHarry Wentland 	for (i = 1 /* skip the master */; i < group_size; i++) {
24684562236bSHarry Wentland 		DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
24696b670fa9SHarry Wentland 		wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
2470fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
2471fa2123dbSMikita Lipski 				grouped_pipes[i]->stream_res.tg);
24724562236bSHarry Wentland 	}
24734562236bSHarry Wentland 
24744562236bSHarry Wentland 	/* GSL Vblank synchronization is a one time sync mechanism, assumption
24754562236bSHarry Wentland 	 * is that the sync'ed displays will not drift out of sync over time*/
24764562236bSHarry Wentland 	DC_SYNC_INFO("GSL: Restoring register states.\n");
24774562236bSHarry Wentland 	for (i = 0; i < group_size; i++)
24786b670fa9SHarry Wentland 		grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
24794562236bSHarry Wentland 
24804562236bSHarry Wentland 	DC_SYNC_INFO("GSL: Set-up complete.\n");
24814562236bSHarry Wentland }
24824562236bSHarry Wentland 
2483fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset(
2484fa2123dbSMikita Lipski 		struct dc *dc,
2485fa2123dbSMikita Lipski 		int group_size,
2486fa2123dbSMikita Lipski 		struct pipe_ctx *grouped_pipes[])
2487fa2123dbSMikita Lipski {
2488fa2123dbSMikita Lipski 	struct dc_context *dc_ctx = dc->ctx;
2489fa2123dbSMikita Lipski 	struct dcp_gsl_params gsl_params = { 0 };
2490fa2123dbSMikita Lipski 	int i;
2491fa2123dbSMikita Lipski 
2492fa2123dbSMikita Lipski 	gsl_params.gsl_group = 0;
2493fa2123dbSMikita Lipski 	gsl_params.gsl_master = grouped_pipes[0]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst;
2494fa2123dbSMikita Lipski 
2495fa2123dbSMikita Lipski 	for (i = 0; i < group_size; i++)
2496fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
2497fa2123dbSMikita Lipski 					grouped_pipes[i]->stream_res.tg, &gsl_params);
2498fa2123dbSMikita Lipski 
2499fa2123dbSMikita Lipski 	DC_SYNC_INFO("GSL: enabling trigger-reset\n");
2500fa2123dbSMikita Lipski 
2501fa2123dbSMikita Lipski 	for (i = 1; i < group_size; i++)
2502fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
2503fa2123dbSMikita Lipski 				grouped_pipes[i]->stream_res.tg,
2504fa2123dbSMikita Lipski 				gsl_params.gsl_master,
2505fa2123dbSMikita Lipski 				&grouped_pipes[i]->stream->triggered_crtc_reset);
2506fa2123dbSMikita Lipski 
2507fa2123dbSMikita Lipski 	DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
2508fa2123dbSMikita Lipski 	for (i = 1; i < group_size; i++)
2509fa2123dbSMikita Lipski 		wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
2510fa2123dbSMikita Lipski 
2511fa2123dbSMikita Lipski 	for (i = 0; i < group_size; i++)
2512fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
2513fa2123dbSMikita Lipski 
2514fa2123dbSMikita Lipski }
2515fa2123dbSMikita Lipski 
2516fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc)
25174562236bSHarry Wentland {
25184562236bSHarry Wentland 	int i;
25194562236bSHarry Wentland 	struct dc_bios *bp;
25204562236bSHarry Wentland 	struct transform *xfm;
25215e7773a2SAnthony Koo 	struct abm *abm;
25224562236bSHarry Wentland 
25234562236bSHarry Wentland 	bp = dc->ctx->dc_bios;
25244562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
25254562236bSHarry Wentland 		xfm = dc->res_pool->transforms[i];
25264562236bSHarry Wentland 		xfm->funcs->transform_reset(xfm);
25274562236bSHarry Wentland 
25284562236bSHarry Wentland 		dc->hwss.enable_display_power_gating(
25294562236bSHarry Wentland 				dc, i, bp,
25304562236bSHarry Wentland 				PIPE_GATING_CONTROL_INIT);
25314562236bSHarry Wentland 		dc->hwss.enable_display_power_gating(
25324562236bSHarry Wentland 				dc, i, bp,
25334562236bSHarry Wentland 				PIPE_GATING_CONTROL_DISABLE);
25344562236bSHarry Wentland 		dc->hwss.enable_display_pipe_clock_gating(
25354562236bSHarry Wentland 			dc->ctx,
25364562236bSHarry Wentland 			true);
25374562236bSHarry Wentland 	}
25384562236bSHarry Wentland 
2539e166ad43SJulia Lawall 	dce_clock_gating_power_up(dc->hwseq, false);
25404562236bSHarry Wentland 	/***************************************/
25414562236bSHarry Wentland 
25424562236bSHarry Wentland 	for (i = 0; i < dc->link_count; i++) {
25434562236bSHarry Wentland 		/****************************************/
25444562236bSHarry Wentland 		/* Power up AND update implementation according to the
25454562236bSHarry Wentland 		 * required signal (which may be different from the
25464562236bSHarry Wentland 		 * default signal on connector). */
2547d0778ebfSHarry Wentland 		struct dc_link *link = dc->links[i];
2548069d418fSAndrew Jiang 
2549069d418fSAndrew Jiang 		if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
2550069d418fSAndrew Jiang 			dc->hwss.edp_power_control(link, true);
2551069d418fSAndrew Jiang 
25524562236bSHarry Wentland 		link->link_enc->funcs->hw_init(link->link_enc);
25534562236bSHarry Wentland 	}
25544562236bSHarry Wentland 
25554562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
25564562236bSHarry Wentland 		struct timing_generator *tg = dc->res_pool->timing_generators[i];
25574562236bSHarry Wentland 
25584562236bSHarry Wentland 		tg->funcs->disable_vga(tg);
25594562236bSHarry Wentland 
25604562236bSHarry Wentland 		/* Blank controller using driver code instead of
25614562236bSHarry Wentland 		 * command table. */
25624562236bSHarry Wentland 		tg->funcs->set_blank(tg, true);
25634b5e7d62SHersen Wu 		hwss_wait_for_blank_complete(tg);
25644562236bSHarry Wentland 	}
25654562236bSHarry Wentland 
25664562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->audio_count; i++) {
25674562236bSHarry Wentland 		struct audio *audio = dc->res_pool->audios[i];
25684562236bSHarry Wentland 		audio->funcs->hw_init(audio);
25694562236bSHarry Wentland 	}
25705e7773a2SAnthony Koo 
25715e7773a2SAnthony Koo 	abm = dc->res_pool->abm;
25726728b30cSAnthony Koo 	if (abm != NULL) {
25736728b30cSAnthony Koo 		abm->funcs->init_backlight(abm);
25745e7773a2SAnthony Koo 		abm->funcs->abm_init(abm);
25754562236bSHarry Wentland 	}
25763eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
25772f3bfb27SRoman Li 	if (dc->fbc_compressor)
25781663ae1cSBhawanpreet Lakha 		dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
25791663ae1cSBhawanpreet Lakha #endif
2580690b5e39SRoman Li 
25816728b30cSAnthony Koo }
25824562236bSHarry Wentland 
258328f72454SJordan Lazare void dce110_fill_display_configs(
2584608ac7bbSJerry Zuo 	const struct dc_state *context,
2585cf437593SDmytro Laktyushkin 	struct dm_pp_display_configuration *pp_display_cfg)
25864562236bSHarry Wentland {
2587cf437593SDmytro Laktyushkin 	int j;
2588cf437593SDmytro Laktyushkin 	int num_cfgs = 0;
2589cf437593SDmytro Laktyushkin 
2590cf437593SDmytro Laktyushkin 	for (j = 0; j < context->stream_count; j++) {
2591cf437593SDmytro Laktyushkin 		int k;
2592cf437593SDmytro Laktyushkin 
25930971c40eSHarry Wentland 		const struct dc_stream_state *stream = context->streams[j];
2594cf437593SDmytro Laktyushkin 		struct dm_pp_single_disp_config *cfg =
2595cf437593SDmytro Laktyushkin 			&pp_display_cfg->disp_configs[num_cfgs];
2596cf437593SDmytro Laktyushkin 		const struct pipe_ctx *pipe_ctx = NULL;
2597cf437593SDmytro Laktyushkin 
2598cf437593SDmytro Laktyushkin 		for (k = 0; k < MAX_PIPES; k++)
2599cf437593SDmytro Laktyushkin 			if (stream == context->res_ctx.pipe_ctx[k].stream) {
2600cf437593SDmytro Laktyushkin 				pipe_ctx = &context->res_ctx.pipe_ctx[k];
2601cf437593SDmytro Laktyushkin 				break;
26024562236bSHarry Wentland 			}
26034562236bSHarry Wentland 
2604cf437593SDmytro Laktyushkin 		ASSERT(pipe_ctx != NULL);
2605cf437593SDmytro Laktyushkin 
2606cf437593SDmytro Laktyushkin 		num_cfgs++;
2607cf437593SDmytro Laktyushkin 		cfg->signal = pipe_ctx->stream->signal;
2608cf437593SDmytro Laktyushkin 		cfg->pipe_idx = pipe_ctx->pipe_idx;
26094fa086b9SLeo (Sunpeng) Li 		cfg->src_height = stream->src.height;
26104fa086b9SLeo (Sunpeng) Li 		cfg->src_width = stream->src.width;
2611cf437593SDmytro Laktyushkin 		cfg->ddi_channel_mapping =
2612cf437593SDmytro Laktyushkin 			stream->sink->link->ddi_channel_mapping.raw;
2613cf437593SDmytro Laktyushkin 		cfg->transmitter =
2614cf437593SDmytro Laktyushkin 			stream->sink->link->link_enc->transmitter;
2615cf437593SDmytro Laktyushkin 		cfg->link_settings.lane_count =
2616d0778ebfSHarry Wentland 			stream->sink->link->cur_link_settings.lane_count;
2617cf437593SDmytro Laktyushkin 		cfg->link_settings.link_rate =
2618d0778ebfSHarry Wentland 			stream->sink->link->cur_link_settings.link_rate;
2619cf437593SDmytro Laktyushkin 		cfg->link_settings.link_spread =
2620d0778ebfSHarry Wentland 			stream->sink->link->cur_link_settings.link_spread;
2621cf437593SDmytro Laktyushkin 		cfg->sym_clock = stream->phy_pix_clk;
2622cf437593SDmytro Laktyushkin 		/* Round v_refresh*/
26234fa086b9SLeo (Sunpeng) Li 		cfg->v_refresh = stream->timing.pix_clk_khz * 1000;
26244fa086b9SLeo (Sunpeng) Li 		cfg->v_refresh /= stream->timing.h_total;
26254fa086b9SLeo (Sunpeng) Li 		cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2)
26264fa086b9SLeo (Sunpeng) Li 							/ stream->timing.v_total;
2627cf437593SDmytro Laktyushkin 	}
2628cf437593SDmytro Laktyushkin 
2629cf437593SDmytro Laktyushkin 	pp_display_cfg->display_count = num_cfgs;
2630cf437593SDmytro Laktyushkin }
2631cf437593SDmytro Laktyushkin 
2632608ac7bbSJerry Zuo uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context)
2633cf437593SDmytro Laktyushkin {
2634cf437593SDmytro Laktyushkin 	uint8_t j;
2635cf437593SDmytro Laktyushkin 	uint32_t min_vertical_blank_time = -1;
2636cf437593SDmytro Laktyushkin 
2637cf437593SDmytro Laktyushkin 	for (j = 0; j < context->stream_count; j++) {
26380971c40eSHarry Wentland 		struct dc_stream_state *stream = context->streams[j];
2639cf437593SDmytro Laktyushkin 		uint32_t vertical_blank_in_pixels = 0;
2640cf437593SDmytro Laktyushkin 		uint32_t vertical_blank_time = 0;
2641cf437593SDmytro Laktyushkin 
2642cf437593SDmytro Laktyushkin 		vertical_blank_in_pixels = stream->timing.h_total *
2643cf437593SDmytro Laktyushkin 			(stream->timing.v_total
2644cf437593SDmytro Laktyushkin 			 - stream->timing.v_addressable);
2645cf437593SDmytro Laktyushkin 
2646cf437593SDmytro Laktyushkin 		vertical_blank_time = vertical_blank_in_pixels
2647cf437593SDmytro Laktyushkin 			* 1000 / stream->timing.pix_clk_khz;
2648cf437593SDmytro Laktyushkin 
2649cf437593SDmytro Laktyushkin 		if (min_vertical_blank_time > vertical_blank_time)
2650cf437593SDmytro Laktyushkin 			min_vertical_blank_time = vertical_blank_time;
2651cf437593SDmytro Laktyushkin 	}
2652cf437593SDmytro Laktyushkin 
2653cf437593SDmytro Laktyushkin 	return min_vertical_blank_time;
2654cf437593SDmytro Laktyushkin }
2655cf437593SDmytro Laktyushkin 
2656cf437593SDmytro Laktyushkin static int determine_sclk_from_bounding_box(
2657fb3466a4SBhawanpreet Lakha 		const struct dc *dc,
2658cf437593SDmytro Laktyushkin 		int required_sclk)
26594562236bSHarry Wentland {
26604562236bSHarry Wentland 	int i;
26614562236bSHarry Wentland 
2662cf437593SDmytro Laktyushkin 	/*
2663cf437593SDmytro Laktyushkin 	 * Some asics do not give us sclk levels, so we just report the actual
2664cf437593SDmytro Laktyushkin 	 * required sclk
2665cf437593SDmytro Laktyushkin 	 */
2666cf437593SDmytro Laktyushkin 	if (dc->sclk_lvls.num_levels == 0)
2667cf437593SDmytro Laktyushkin 		return required_sclk;
26684562236bSHarry Wentland 
2669cf437593SDmytro Laktyushkin 	for (i = 0; i < dc->sclk_lvls.num_levels; i++) {
2670cf437593SDmytro Laktyushkin 		if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk)
2671cf437593SDmytro Laktyushkin 			return dc->sclk_lvls.clocks_in_khz[i];
2672cf437593SDmytro Laktyushkin 	}
2673cf437593SDmytro Laktyushkin 	/*
2674cf437593SDmytro Laktyushkin 	 * even maximum level could not satisfy requirement, this
2675cf437593SDmytro Laktyushkin 	 * is unexpected at this stage, should have been caught at
2676cf437593SDmytro Laktyushkin 	 * validation time
2677cf437593SDmytro Laktyushkin 	 */
2678cf437593SDmytro Laktyushkin 	ASSERT(0);
2679cf437593SDmytro Laktyushkin 	return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1];
26804562236bSHarry Wentland }
26814562236bSHarry Wentland 
2682cf437593SDmytro Laktyushkin static void pplib_apply_display_requirements(
2683fb3466a4SBhawanpreet Lakha 	struct dc *dc,
2684608ac7bbSJerry Zuo 	struct dc_state *context)
2685cf437593SDmytro Laktyushkin {
2686cf437593SDmytro Laktyushkin 	struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
2687cf437593SDmytro Laktyushkin 
2688cf437593SDmytro Laktyushkin 	pp_display_cfg->all_displays_in_sync =
26899037d802SDmytro Laktyushkin 		context->bw.dce.all_displays_in_sync;
2690cf437593SDmytro Laktyushkin 	pp_display_cfg->nb_pstate_switch_disable =
26919037d802SDmytro Laktyushkin 			context->bw.dce.nbp_state_change_enable == false;
2692cf437593SDmytro Laktyushkin 	pp_display_cfg->cpu_cc6_disable =
26939037d802SDmytro Laktyushkin 			context->bw.dce.cpuc_state_change_enable == false;
2694cf437593SDmytro Laktyushkin 	pp_display_cfg->cpu_pstate_disable =
26959037d802SDmytro Laktyushkin 			context->bw.dce.cpup_state_change_enable == false;
2696cf437593SDmytro Laktyushkin 	pp_display_cfg->cpu_pstate_separation_time =
26979037d802SDmytro Laktyushkin 			context->bw.dce.blackout_recovery_time_us;
2698cf437593SDmytro Laktyushkin 
26999037d802SDmytro Laktyushkin 	pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz
2700cf437593SDmytro Laktyushkin 		/ MEMORY_TYPE_MULTIPLIER;
2701cf437593SDmytro Laktyushkin 
2702cf437593SDmytro Laktyushkin 	pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
2703cf437593SDmytro Laktyushkin 			dc,
27049037d802SDmytro Laktyushkin 			context->bw.dce.sclk_khz);
2705cf437593SDmytro Laktyushkin 
2706cf437593SDmytro Laktyushkin 	pp_display_cfg->min_engine_clock_deep_sleep_khz
27079037d802SDmytro Laktyushkin 			= context->bw.dce.sclk_deep_sleep_khz;
2708cf437593SDmytro Laktyushkin 
2709cf437593SDmytro Laktyushkin 	pp_display_cfg->avail_mclk_switch_time_us =
271028f72454SJordan Lazare 						dce110_get_min_vblank_time_us(context);
2711cf437593SDmytro Laktyushkin 	/* TODO: dce11.2*/
2712cf437593SDmytro Laktyushkin 	pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
2713cf437593SDmytro Laktyushkin 
27149037d802SDmytro Laktyushkin 	pp_display_cfg->disp_clk_khz = context->bw.dce.dispclk_khz;
2715cf437593SDmytro Laktyushkin 
271628f72454SJordan Lazare 	dce110_fill_display_configs(context, pp_display_cfg);
2717cf437593SDmytro Laktyushkin 
2718cf437593SDmytro Laktyushkin 	/* TODO: is this still applicable?*/
2719cf437593SDmytro Laktyushkin 	if (pp_display_cfg->display_count == 1) {
2720cf437593SDmytro Laktyushkin 		const struct dc_crtc_timing *timing =
27214fa086b9SLeo (Sunpeng) Li 			&context->streams[0]->timing;
2722cf437593SDmytro Laktyushkin 
2723cf437593SDmytro Laktyushkin 		pp_display_cfg->crtc_index =
2724cf437593SDmytro Laktyushkin 			pp_display_cfg->disp_configs[0].pipe_idx;
2725cf437593SDmytro Laktyushkin 		pp_display_cfg->line_time_in_us = timing->h_total * 1000
2726cf437593SDmytro Laktyushkin 							/ timing->pix_clk_khz;
2727cf437593SDmytro Laktyushkin 	}
2728cf437593SDmytro Laktyushkin 
2729cf437593SDmytro Laktyushkin 	if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof(
2730cf437593SDmytro Laktyushkin 			struct dm_pp_display_configuration)) !=  0)
2731cf437593SDmytro Laktyushkin 		dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
2732cf437593SDmytro Laktyushkin 
2733cf437593SDmytro Laktyushkin 	dc->prev_display_config = *pp_display_cfg;
2734cf437593SDmytro Laktyushkin }
2735cf437593SDmytro Laktyushkin 
2736cf437593SDmytro Laktyushkin static void dce110_set_bandwidth(
2737fb3466a4SBhawanpreet Lakha 		struct dc *dc,
2738608ac7bbSJerry Zuo 		struct dc_state *context,
2739cf437593SDmytro Laktyushkin 		bool decrease_allowed)
2740cf437593SDmytro Laktyushkin {
27412180e7ccSDmytro Laktyushkin 	dce110_set_displaymarks(dc, context);
2742cf437593SDmytro Laktyushkin 
2743608ac7bbSJerry Zuo 	if (decrease_allowed || context->bw.dce.dispclk_khz > dc->current_state->bw.dce.dispclk_khz) {
2744a2b8659dSTony Cheng 		dc->res_pool->display_clock->funcs->set_clock(
2745a2b8659dSTony Cheng 				dc->res_pool->display_clock,
27469037d802SDmytro Laktyushkin 				context->bw.dce.dispclk_khz * 115 / 100);
2747608ac7bbSJerry Zuo 		dc->current_state->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz;
2748cf437593SDmytro Laktyushkin 	}
2749cf437593SDmytro Laktyushkin 
2750cf437593SDmytro Laktyushkin 	pplib_apply_display_requirements(dc, context);
27514562236bSHarry Wentland }
27524562236bSHarry Wentland 
27534562236bSHarry Wentland static void dce110_program_front_end_for_pipe(
2754fb3466a4SBhawanpreet Lakha 		struct dc *dc, struct pipe_ctx *pipe_ctx)
27554562236bSHarry Wentland {
275686a66c4eSHarry Wentland 	struct mem_input *mi = pipe_ctx->plane_res.mi;
27574562236bSHarry Wentland 	struct pipe_ctx *old_pipe = NULL;
27583be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
27594562236bSHarry Wentland 	struct xfm_grph_csc_adjustment adjust;
27604562236bSHarry Wentland 	struct out_csc_color_matrix tbl_entry;
2761067c878aSYongqiang Sun 	struct pipe_ctx *cur_pipe_ctx =
2762067c878aSYongqiang Sun 					&dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
27634562236bSHarry Wentland 	unsigned int i;
27644562236bSHarry Wentland 
27654562236bSHarry Wentland 	memset(&tbl_entry, 0, sizeof(tbl_entry));
27664562236bSHarry Wentland 
2767608ac7bbSJerry Zuo 	if (dc->current_state)
2768608ac7bbSJerry Zuo 		old_pipe = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
27694562236bSHarry Wentland 
27704562236bSHarry Wentland 	memset(&adjust, 0, sizeof(adjust));
27714562236bSHarry Wentland 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
27724562236bSHarry Wentland 
27734562236bSHarry Wentland 	dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
27744562236bSHarry Wentland 
27754562236bSHarry Wentland 	set_default_colors(pipe_ctx);
27764fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
27774562236bSHarry Wentland 			== true) {
27784562236bSHarry Wentland 		tbl_entry.color_space =
27794fa086b9SLeo (Sunpeng) Li 			pipe_ctx->stream->output_color_space;
27804562236bSHarry Wentland 
27814562236bSHarry Wentland 		for (i = 0; i < 12; i++)
27824562236bSHarry Wentland 			tbl_entry.regval[i] =
27834fa086b9SLeo (Sunpeng) Li 			pipe_ctx->stream->csc_color_matrix.matrix[i];
27844562236bSHarry Wentland 
278586a66c4eSHarry Wentland 		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
278686a66c4eSHarry Wentland 				(pipe_ctx->plane_res.xfm, &tbl_entry);
27874562236bSHarry Wentland 	}
27884562236bSHarry Wentland 
27894fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
27904562236bSHarry Wentland 		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
27914562236bSHarry Wentland 		adjust.temperature_matrix[0] =
27924562236bSHarry Wentland 				pipe_ctx->stream->
27934fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[0];
27944562236bSHarry Wentland 		adjust.temperature_matrix[1] =
27954562236bSHarry Wentland 				pipe_ctx->stream->
27964fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[1];
27974562236bSHarry Wentland 		adjust.temperature_matrix[2] =
27984562236bSHarry Wentland 				pipe_ctx->stream->
27994fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[2];
28004562236bSHarry Wentland 		adjust.temperature_matrix[3] =
28014562236bSHarry Wentland 				pipe_ctx->stream->
28024fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[4];
28034562236bSHarry Wentland 		adjust.temperature_matrix[4] =
28044562236bSHarry Wentland 				pipe_ctx->stream->
28054fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[5];
28064562236bSHarry Wentland 		adjust.temperature_matrix[5] =
28074562236bSHarry Wentland 				pipe_ctx->stream->
28084fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[6];
28094562236bSHarry Wentland 		adjust.temperature_matrix[6] =
28104562236bSHarry Wentland 				pipe_ctx->stream->
28114fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[8];
28124562236bSHarry Wentland 		adjust.temperature_matrix[7] =
28134562236bSHarry Wentland 				pipe_ctx->stream->
28144fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[9];
28154562236bSHarry Wentland 		adjust.temperature_matrix[8] =
28164562236bSHarry Wentland 				pipe_ctx->stream->
28174fa086b9SLeo (Sunpeng) Li 				gamut_remap_matrix.matrix[10];
28184562236bSHarry Wentland 	}
28194562236bSHarry Wentland 
282086a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
28214562236bSHarry Wentland 
28226702a9acSHarry Wentland 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
2823c1473558SAndrey Grodzovsky 
28244562236bSHarry Wentland 	program_scaler(dc, pipe_ctx);
28254562236bSHarry Wentland 
28263eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC)
2827e008b0bcSRoman Li 	if (dc->fbc_compressor && old_pipe->stream) {
2828e008b0bcSRoman Li 		if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
2829e008b0bcSRoman Li 			dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
2830e008b0bcSRoman Li 		else
2831e008b0bcSRoman Li 			enable_fbc(dc, dc->current_state);
2832e008b0bcSRoman Li 	}
2833e008b0bcSRoman Li #endif
2834e008b0bcSRoman Li 
28354562236bSHarry Wentland 	mi->funcs->mem_input_program_surface_config(
28364562236bSHarry Wentland 			mi,
28373be5262eSHarry Wentland 			plane_state->format,
28383be5262eSHarry Wentland 			&plane_state->tiling_info,
28393be5262eSHarry Wentland 			&plane_state->plane_size,
28403be5262eSHarry Wentland 			plane_state->rotation,
2841624d7c47SYongqiang Sun 			NULL,
28424b28b76bSDmytro Laktyushkin 			false);
28434b28b76bSDmytro Laktyushkin 	if (mi->funcs->set_blank)
28443be5262eSHarry Wentland 		mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
28454562236bSHarry Wentland 
2846fb3466a4SBhawanpreet Lakha 	if (dc->config.gpu_vm_support)
28474562236bSHarry Wentland 		mi->funcs->mem_input_program_pte_vm(
284886a66c4eSHarry Wentland 				pipe_ctx->plane_res.mi,
28493be5262eSHarry Wentland 				plane_state->format,
28503be5262eSHarry Wentland 				&plane_state->tiling_info,
28513be5262eSHarry Wentland 				plane_state->rotation);
28524562236bSHarry Wentland 
2853067c878aSYongqiang Sun 	/* Moved programming gamma from dc to hwss */
2854067c878aSYongqiang Sun 	if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
2855067c878aSYongqiang Sun 		dc->hwss.set_input_transfer_func(
2856067c878aSYongqiang Sun 				pipe_ctx, pipe_ctx->plane_state);
2857067c878aSYongqiang Sun 		dc->hwss.set_output_transfer_func(
2858067c878aSYongqiang Sun 				pipe_ctx, pipe_ctx->stream);
2859067c878aSYongqiang Sun 	}
2860067c878aSYongqiang Sun 
28614562236bSHarry Wentland 	dm_logger_write(dc->ctx->logger, LOG_SURFACE,
28624562236bSHarry Wentland 			"Pipe:%d 0x%x: addr hi:0x%x, "
28634562236bSHarry Wentland 			"addr low:0x%x, "
28644562236bSHarry Wentland 			"src: %d, %d, %d,"
28654562236bSHarry Wentland 			" %d; dst: %d, %d, %d, %d;"
28664562236bSHarry Wentland 			"clip: %d, %d, %d, %d\n",
28674562236bSHarry Wentland 			pipe_ctx->pipe_idx,
28683be5262eSHarry Wentland 			pipe_ctx->plane_state,
28693be5262eSHarry Wentland 			pipe_ctx->plane_state->address.grph.addr.high_part,
28703be5262eSHarry Wentland 			pipe_ctx->plane_state->address.grph.addr.low_part,
28713be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.x,
28723be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.y,
28733be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.width,
28743be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.height,
28753be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.x,
28763be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.y,
28773be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.width,
28783be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.height,
28793be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.x,
28803be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.y,
28813be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.width,
28823be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.height);
28834562236bSHarry Wentland 
28844562236bSHarry Wentland 	dm_logger_write(dc->ctx->logger, LOG_SURFACE,
28854562236bSHarry Wentland 			"Pipe %d: width, height, x, y\n"
28864562236bSHarry Wentland 			"viewport:%d, %d, %d, %d\n"
28874562236bSHarry Wentland 			"recout:  %d, %d, %d, %d\n",
28884562236bSHarry Wentland 			pipe_ctx->pipe_idx,
28896702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.width,
28906702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.height,
28916702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.x,
28926702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.y,
28936702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.width,
28946702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.height,
28956702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.x,
28966702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.y);
28974562236bSHarry Wentland }
28984562236bSHarry Wentland 
28994562236bSHarry Wentland static void dce110_apply_ctx_for_surface(
2900fb3466a4SBhawanpreet Lakha 		struct dc *dc,
29013e9ad616SEric Yang 		const struct dc_stream_state *stream,
29023e9ad616SEric Yang 		int num_planes,
2903608ac7bbSJerry Zuo 		struct dc_state *context)
29044562236bSHarry Wentland {
29053e9ad616SEric Yang 	int i, be_idx;
29064562236bSHarry Wentland 
29073e9ad616SEric Yang 	if (num_planes == 0)
29084562236bSHarry Wentland 		return;
29094562236bSHarry Wentland 
29103e9ad616SEric Yang 	be_idx = -1;
29113e9ad616SEric Yang 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
29123dc780ecSYongqiang Sun 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
29133dc780ecSYongqiang Sun 		struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
29143dc780ecSYongqiang Sun 
29153e9ad616SEric Yang 		if (stream == context->res_ctx.pipe_ctx[i].stream) {
29163e9ad616SEric Yang 			be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst;
29173dc780ecSYongqiang Sun 			if (!pipe_ctx->top_pipe &&
29183dc780ecSYongqiang Sun 				(pipe_ctx->plane_state || old_pipe_ctx->plane_state))
29193dc780ecSYongqiang Sun 				dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
29203e9ad616SEric Yang 			break;
29213e9ad616SEric Yang 		}
29223e9ad616SEric Yang 	}
29233e9ad616SEric Yang 
2924a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
29254562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
29264562236bSHarry Wentland 
2927a2607aefSHarry Wentland 		if (pipe_ctx->stream != stream)
29284562236bSHarry Wentland 			continue;
29294562236bSHarry Wentland 
29303b21b6d2SJerry Zuo 		/* Need to allocate mem before program front end for Fiji */
29313b21b6d2SJerry Zuo 		if (pipe_ctx->plane_res.mi != NULL)
29323b21b6d2SJerry Zuo 			pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
29333b21b6d2SJerry Zuo 					pipe_ctx->plane_res.mi,
29343b21b6d2SJerry Zuo 					pipe_ctx->stream->timing.h_total,
29353b21b6d2SJerry Zuo 					pipe_ctx->stream->timing.v_total,
29363b21b6d2SJerry Zuo 					pipe_ctx->stream->timing.pix_clk_khz,
29373b21b6d2SJerry Zuo 					context->stream_count);
29383b21b6d2SJerry Zuo 
29394562236bSHarry Wentland 		dce110_program_front_end_for_pipe(dc, pipe_ctx);
2940b06b7680SLeon Elazar 		program_surface_visibility(dc, pipe_ctx);
29414562236bSHarry Wentland 
29424562236bSHarry Wentland 	}
29433dc780ecSYongqiang Sun 
29443dc780ecSYongqiang Sun 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
29453dc780ecSYongqiang Sun 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
29463dc780ecSYongqiang Sun 		struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
29473dc780ecSYongqiang Sun 
29483dc780ecSYongqiang Sun 		if ((stream == pipe_ctx->stream) &&
29493dc780ecSYongqiang Sun 			(!pipe_ctx->top_pipe) &&
29503dc780ecSYongqiang Sun 			(pipe_ctx->plane_state || old_pipe_ctx->plane_state))
29513dc780ecSYongqiang Sun 			dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
29523dc780ecSYongqiang Sun 	}
29534562236bSHarry Wentland }
29544562236bSHarry Wentland 
2955e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
29564562236bSHarry Wentland {
2957e6c258cbSYongqiang Sun 	int fe_idx = pipe_ctx->pipe_idx;
2958e6c258cbSYongqiang Sun 
29597950f0f9SDmytro Laktyushkin 	/* Do not power down fe when stream is active on dce*/
2960608ac7bbSJerry Zuo 	if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
29614562236bSHarry Wentland 		return;
29624562236bSHarry Wentland 
29634562236bSHarry Wentland 	dc->hwss.enable_display_power_gating(
2964cfe4645eSDmytro Laktyushkin 		dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
2965cfe4645eSDmytro Laktyushkin 
2966cfe4645eSDmytro Laktyushkin 	dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
2967cfe4645eSDmytro Laktyushkin 				dc->res_pool->transforms[fe_idx]);
29684562236bSHarry Wentland }
29694562236bSHarry Wentland 
29706be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect(
2971fb3466a4SBhawanpreet Lakha 		struct dc *dc,
29726be425f3SEric Yang 		struct resource_pool *res_pool,
29736be425f3SEric Yang 		struct pipe_ctx *pipe_ctx)
2974b6762f0cSEric Yang {
2975b6762f0cSEric Yang 	/* do nothing*/
2976b6762f0cSEric Yang }
2977b6762f0cSEric Yang 
2978bdf9a1a0SYue Hin Lau static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
2979bdf9a1a0SYue Hin Lau 		enum dc_color_space colorspace,
2980bdf9a1a0SYue Hin Lau 		uint16_t *matrix)
2981bdf9a1a0SYue Hin Lau {
2982bdf9a1a0SYue Hin Lau 	int i;
2983bdf9a1a0SYue Hin Lau 	struct out_csc_color_matrix tbl_entry;
2984bdf9a1a0SYue Hin Lau 
2985bdf9a1a0SYue Hin Lau 	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
2986bdf9a1a0SYue Hin Lau 				== true) {
2987bdf9a1a0SYue Hin Lau 			enum dc_color_space color_space =
2988bdf9a1a0SYue Hin Lau 				pipe_ctx->stream->output_color_space;
2989bdf9a1a0SYue Hin Lau 
2990bdf9a1a0SYue Hin Lau 			//uint16_t matrix[12];
2991bdf9a1a0SYue Hin Lau 			for (i = 0; i < 12; i++)
2992bdf9a1a0SYue Hin Lau 				tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
2993bdf9a1a0SYue Hin Lau 
2994bdf9a1a0SYue Hin Lau 			tbl_entry.color_space = color_space;
2995bdf9a1a0SYue Hin Lau 			//tbl_entry.regval = matrix;
299686a66c4eSHarry Wentland 			pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry);
2997bdf9a1a0SYue Hin Lau 	}
2998bdf9a1a0SYue Hin Lau }
2999bdf9a1a0SYue Hin Lau 
30006bf52028SHersen Wu static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
300141f97c07SHersen Wu 
300241f97c07SHersen Wu static void optimize_shared_resources(struct dc *dc) {}
300341f97c07SHersen Wu 
30044562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = {
30051bf56e62SZeyu Fan 	.program_gamut_remap = program_gamut_remap,
3006bdf9a1a0SYue Hin Lau 	.program_csc_matrix = program_csc_matrix,
30074562236bSHarry Wentland 	.init_hw = init_hw,
30084562236bSHarry Wentland 	.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
30094562236bSHarry Wentland 	.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
30104562236bSHarry Wentland 	.set_plane_config = set_plane_config,
30114562236bSHarry Wentland 	.update_plane_addr = update_plane_addr,
30124562236bSHarry Wentland 	.update_pending_status = dce110_update_pending_status,
3013d7194cf6SAric Cyr 	.set_input_transfer_func = dce110_set_input_transfer_func,
301490e508baSAnthony Koo 	.set_output_transfer_func = dce110_set_output_transfer_func,
30154562236bSHarry Wentland 	.power_down = dce110_power_down,
30164562236bSHarry Wentland 	.enable_accelerated_mode = dce110_enable_accelerated_mode,
30174562236bSHarry Wentland 	.enable_timing_synchronization = dce110_enable_timing_synchronization,
3018fa2123dbSMikita Lipski 	.enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
30194562236bSHarry Wentland 	.update_info_frame = dce110_update_info_frame,
30204562236bSHarry Wentland 	.enable_stream = dce110_enable_stream,
30214562236bSHarry Wentland 	.disable_stream = dce110_disable_stream,
30224562236bSHarry Wentland 	.unblank_stream = dce110_unblank_stream,
30234562236bSHarry Wentland 	.enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
30244562236bSHarry Wentland 	.enable_display_power_gating = dce110_enable_display_power_gating,
30254562236bSHarry Wentland 	.power_down_front_end = dce110_power_down_fe,
30264562236bSHarry Wentland 	.pipe_control_lock = dce_pipe_control_lock,
30274562236bSHarry Wentland 	.set_bandwidth = dce110_set_bandwidth,
30284562236bSHarry Wentland 	.set_drr = set_drr,
302972ada5f7SEric Cook 	.get_position = get_position,
30304562236bSHarry Wentland 	.set_static_screen_control = set_static_screen_control,
303154e8695eSDmytro Laktyushkin 	.reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
30324b5e7d62SHersen Wu 	.prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg,
303315e17335SCharlene Liu 	.setup_stereo = NULL,
303415e17335SCharlene Liu 	.set_avmute = dce110_set_avmute,
303541f97c07SHersen Wu 	.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
303641f97c07SHersen Wu 	.ready_shared_resources = ready_shared_resources,
303741f97c07SHersen Wu 	.optimize_shared_resources = optimize_shared_resources,
303887401969SAndrew Jiang 	.edp_backlight_control = hwss_edp_backlight_control,
303987401969SAndrew Jiang 	.edp_power_control = hwss_edp_power_control,
30404562236bSHarry Wentland };
30414562236bSHarry Wentland 
3042c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc)
30434562236bSHarry Wentland {
30444562236bSHarry Wentland 	dc->hwss = dce110_funcs;
30454562236bSHarry Wentland }
30464562236bSHarry Wentland 
3047