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 
371663ae1cSBhawanpreet Lakha #include "dce110_compressor.h"
381663ae1cSBhawanpreet Lakha 
394562236bSHarry Wentland #include "bios/bios_parser_helper.h"
404562236bSHarry Wentland #include "timing_generator.h"
414562236bSHarry Wentland #include "mem_input.h"
424562236bSHarry Wentland #include "opp.h"
434562236bSHarry Wentland #include "ipp.h"
444562236bSHarry Wentland #include "transform.h"
454562236bSHarry Wentland #include "stream_encoder.h"
464562236bSHarry Wentland #include "link_encoder.h"
4787401969SAndrew Jiang #include "link_hwss.h"
484562236bSHarry Wentland #include "clock_source.h"
49dc88b4a6SEric Yang #include "clk_mgr.h"
505e7773a2SAnthony Koo #include "abm.h"
514562236bSHarry Wentland #include "audio.h"
5208b16886SZeyu Fan #include "reg_helper.h"
534562236bSHarry Wentland 
544562236bSHarry Wentland /* include DCE11 register header files */
554562236bSHarry Wentland #include "dce/dce_11_0_d.h"
564562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h"
57e266fdf6SVitaly Prosyak #include "custom_float.h"
584562236bSHarry Wentland 
594cac1e6dSYongqiang Sun #include "atomfirmware.h"
604cac1e6dSYongqiang Sun 
6187401969SAndrew Jiang /*
6287401969SAndrew Jiang  * All values are in milliseconds;
6387401969SAndrew Jiang  * For eDP, after power-up/power/down,
6487401969SAndrew Jiang  * 300/500 msec max. delay from LCDVCC to black video generation
6587401969SAndrew Jiang  */
6687401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300
6787401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500
6887401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10
6987401969SAndrew Jiang 
705eefbc40SYue Hin Lau #define CTX \
715eefbc40SYue Hin Lau 	hws->ctx
725d4b05ddSBhawanpreet Lakha 
735d4b05ddSBhawanpreet Lakha #define DC_LOGGER_INIT()
745d4b05ddSBhawanpreet Lakha 
755eefbc40SYue Hin Lau #define REG(reg)\
765eefbc40SYue Hin Lau 	hws->regs->reg
775eefbc40SYue Hin Lau 
785eefbc40SYue Hin Lau #undef FN
795eefbc40SYue Hin Lau #define FN(reg_name, field_name) \
805eefbc40SYue Hin Lau 	hws->shifts->field_name, hws->masks->field_name
815eefbc40SYue Hin Lau 
824562236bSHarry Wentland struct dce110_hw_seq_reg_offsets {
834562236bSHarry Wentland 	uint32_t crtc;
844562236bSHarry Wentland };
854562236bSHarry Wentland 
864562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
874562236bSHarry Wentland {
884562236bSHarry Wentland 	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
894562236bSHarry Wentland },
904562236bSHarry Wentland {
914562236bSHarry Wentland 	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
924562236bSHarry Wentland },
934562236bSHarry Wentland {
944562236bSHarry Wentland 	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
954562236bSHarry Wentland },
964562236bSHarry Wentland {
974562236bSHarry Wentland 	.crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL),
984562236bSHarry Wentland }
994562236bSHarry Wentland };
1004562236bSHarry Wentland 
1014562236bSHarry Wentland #define HW_REG_BLND(reg, id)\
1024562236bSHarry Wentland 	(reg + reg_offsets[id].blnd)
1034562236bSHarry Wentland 
1044562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\
1054562236bSHarry Wentland 	(reg + reg_offsets[id].crtc)
1064562236bSHarry Wentland 
1074562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF
1084562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF
1094562236bSHarry Wentland 
1104562236bSHarry Wentland /*******************************************************************************
1114562236bSHarry Wentland  * Private definitions
1124562236bSHarry Wentland  ******************************************************************************/
1134562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/
1144562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx)
1154562236bSHarry Wentland {
1164562236bSHarry Wentland 	uint32_t addr;
1174562236bSHarry Wentland 	uint32_t value = 0;
1184562236bSHarry Wentland 	uint32_t chunk_int = 0;
1194562236bSHarry Wentland 	uint32_t chunk_mul = 0;
1204562236bSHarry Wentland 
1214562236bSHarry Wentland 	addr = mmUNP_DVMM_PTE_CONTROL;
1224562236bSHarry Wentland 	value = dm_read_reg(ctx, addr);
1234562236bSHarry Wentland 
1244562236bSHarry Wentland 	set_reg_field_value(
1254562236bSHarry Wentland 		value,
1264562236bSHarry Wentland 		0,
1274562236bSHarry Wentland 		DVMM_PTE_CONTROL,
1284562236bSHarry Wentland 		DVMM_USE_SINGLE_PTE);
1294562236bSHarry Wentland 
1304562236bSHarry Wentland 	set_reg_field_value(
1314562236bSHarry Wentland 		value,
1324562236bSHarry Wentland 		1,
1334562236bSHarry Wentland 		DVMM_PTE_CONTROL,
1344562236bSHarry Wentland 		DVMM_PTE_BUFFER_MODE0);
1354562236bSHarry Wentland 
1364562236bSHarry Wentland 	set_reg_field_value(
1374562236bSHarry Wentland 		value,
1384562236bSHarry Wentland 		1,
1394562236bSHarry Wentland 		DVMM_PTE_CONTROL,
1404562236bSHarry Wentland 		DVMM_PTE_BUFFER_MODE1);
1414562236bSHarry Wentland 
1424562236bSHarry Wentland 	dm_write_reg(ctx, addr, value);
1434562236bSHarry Wentland 
1444562236bSHarry Wentland 	addr = mmDVMM_PTE_REQ;
1454562236bSHarry Wentland 	value = dm_read_reg(ctx, addr);
1464562236bSHarry Wentland 
1474562236bSHarry Wentland 	chunk_int = get_reg_field_value(
1484562236bSHarry Wentland 		value,
1494562236bSHarry Wentland 		DVMM_PTE_REQ,
1504562236bSHarry Wentland 		HFLIP_PTEREQ_PER_CHUNK_INT);
1514562236bSHarry Wentland 
1524562236bSHarry Wentland 	chunk_mul = get_reg_field_value(
1534562236bSHarry Wentland 		value,
1544562236bSHarry Wentland 		DVMM_PTE_REQ,
1554562236bSHarry Wentland 		HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
1564562236bSHarry Wentland 
1574562236bSHarry Wentland 	if (chunk_int != 0x4 || chunk_mul != 0x4) {
1584562236bSHarry Wentland 
1594562236bSHarry Wentland 		set_reg_field_value(
1604562236bSHarry Wentland 			value,
1614562236bSHarry Wentland 			255,
1624562236bSHarry Wentland 			DVMM_PTE_REQ,
1634562236bSHarry Wentland 			MAX_PTEREQ_TO_ISSUE);
1644562236bSHarry Wentland 
1654562236bSHarry Wentland 		set_reg_field_value(
1664562236bSHarry Wentland 			value,
1674562236bSHarry Wentland 			4,
1684562236bSHarry Wentland 			DVMM_PTE_REQ,
1694562236bSHarry Wentland 			HFLIP_PTEREQ_PER_CHUNK_INT);
1704562236bSHarry Wentland 
1714562236bSHarry Wentland 		set_reg_field_value(
1724562236bSHarry Wentland 			value,
1734562236bSHarry Wentland 			4,
1744562236bSHarry Wentland 			DVMM_PTE_REQ,
1754562236bSHarry Wentland 			HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
1764562236bSHarry Wentland 
1774562236bSHarry Wentland 		dm_write_reg(ctx, addr, value);
1784562236bSHarry Wentland 	}
1794562236bSHarry Wentland }
1804562236bSHarry Wentland /**************************************************************************/
1814562236bSHarry Wentland 
1824562236bSHarry Wentland static void enable_display_pipe_clock_gating(
1834562236bSHarry Wentland 	struct dc_context *ctx,
1844562236bSHarry Wentland 	bool clock_gating)
1854562236bSHarry Wentland {
1864562236bSHarry Wentland 	/*TODO*/
1874562236bSHarry Wentland }
1884562236bSHarry Wentland 
1894562236bSHarry Wentland static bool dce110_enable_display_power_gating(
190fb3466a4SBhawanpreet Lakha 	struct dc *dc,
1914562236bSHarry Wentland 	uint8_t controller_id,
1924562236bSHarry Wentland 	struct dc_bios *dcb,
1934562236bSHarry Wentland 	enum pipe_gating_control power_gating)
1944562236bSHarry Wentland {
1954562236bSHarry Wentland 	enum bp_result bp_result = BP_RESULT_OK;
1964562236bSHarry Wentland 	enum bp_pipe_control_action cntl;
1974562236bSHarry Wentland 	struct dc_context *ctx = dc->ctx;
1984562236bSHarry Wentland 	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
1994562236bSHarry Wentland 
2004562236bSHarry Wentland 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
2014562236bSHarry Wentland 		return true;
2024562236bSHarry Wentland 
2034562236bSHarry Wentland 	if (power_gating == PIPE_GATING_CONTROL_INIT)
2044562236bSHarry Wentland 		cntl = ASIC_PIPE_INIT;
2054562236bSHarry Wentland 	else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
2064562236bSHarry Wentland 		cntl = ASIC_PIPE_ENABLE;
2074562236bSHarry Wentland 	else
2084562236bSHarry Wentland 		cntl = ASIC_PIPE_DISABLE;
2094562236bSHarry Wentland 
2104562236bSHarry Wentland 	if (controller_id == underlay_idx)
2114562236bSHarry Wentland 		controller_id = CONTROLLER_ID_UNDERLAY0 - 1;
2124562236bSHarry Wentland 
2134562236bSHarry Wentland 	if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){
2144562236bSHarry Wentland 
2154562236bSHarry Wentland 		bp_result = dcb->funcs->enable_disp_power_gating(
2164562236bSHarry Wentland 						dcb, controller_id + 1, cntl);
2174562236bSHarry Wentland 
2184562236bSHarry Wentland 		/* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
2194562236bSHarry Wentland 		 * by default when command table is called
2204562236bSHarry Wentland 		 *
2214562236bSHarry Wentland 		 * Bios parser accepts controller_id = 6 as indicative of
2224562236bSHarry Wentland 		 * underlay pipe in dce110. But we do not support more
2234562236bSHarry Wentland 		 * than 3.
2244562236bSHarry Wentland 		 */
2254562236bSHarry Wentland 		if (controller_id < CONTROLLER_ID_MAX - 1)
2264562236bSHarry Wentland 			dm_write_reg(ctx,
2274562236bSHarry Wentland 				HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
2284562236bSHarry Wentland 				0);
2294562236bSHarry Wentland 	}
2304562236bSHarry Wentland 
2314562236bSHarry Wentland 	if (power_gating != PIPE_GATING_CONTROL_ENABLE)
2324562236bSHarry Wentland 		dce110_init_pte(ctx);
2334562236bSHarry Wentland 
2344562236bSHarry Wentland 	if (bp_result == BP_RESULT_OK)
2354562236bSHarry Wentland 		return true;
2364562236bSHarry Wentland 	else
2374562236bSHarry Wentland 		return false;
2384562236bSHarry Wentland }
2394562236bSHarry Wentland 
2404562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params,
2413be5262eSHarry Wentland 		const struct dc_plane_state *plane_state)
2424562236bSHarry Wentland {
2434562236bSHarry Wentland 	prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
2444562236bSHarry Wentland 
2453be5262eSHarry Wentland 	switch (plane_state->format) {
2461352c779SNicholas Kazlauskas 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
2471352c779SNicholas Kazlauskas 		prescale_params->scale = 0x2082;
2481352c779SNicholas Kazlauskas 		break;
2494562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2508693049aSTony Cheng 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2514562236bSHarry Wentland 		prescale_params->scale = 0x2020;
2524562236bSHarry Wentland 		break;
2534562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2544562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2554562236bSHarry Wentland 		prescale_params->scale = 0x2008;
2564562236bSHarry Wentland 		break;
2574562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2584562236bSHarry Wentland 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2594562236bSHarry Wentland 		prescale_params->scale = 0x2000;
2604562236bSHarry Wentland 		break;
2614562236bSHarry Wentland 	default:
2624562236bSHarry Wentland 		ASSERT(false);
263d7194cf6SAric Cyr 		break;
2644562236bSHarry Wentland 	}
2654562236bSHarry Wentland }
2664562236bSHarry Wentland 
267a6114e85SHarry Wentland static bool
268a6114e85SHarry Wentland dce110_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
2693be5262eSHarry Wentland 			       const struct dc_plane_state *plane_state)
2704562236bSHarry Wentland {
27186a66c4eSHarry Wentland 	struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
2727b0c470fSLeo (Sunpeng) Li 	const struct dc_transfer_func *tf = NULL;
27390e508baSAnthony Koo 	struct ipp_prescale_params prescale_params = { 0 };
27490e508baSAnthony Koo 	bool result = true;
27590e508baSAnthony Koo 
27690e508baSAnthony Koo 	if (ipp == NULL)
27790e508baSAnthony Koo 		return false;
27890e508baSAnthony Koo 
2793be5262eSHarry Wentland 	if (plane_state->in_transfer_func)
2803be5262eSHarry Wentland 		tf = plane_state->in_transfer_func;
28190e508baSAnthony Koo 
2823be5262eSHarry Wentland 	build_prescale_params(&prescale_params, plane_state);
28390e508baSAnthony Koo 	ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
28490e508baSAnthony Koo 
28584ffa801SLeo (Sunpeng) Li 	if (plane_state->gamma_correction &&
28684ffa801SLeo (Sunpeng) Li 			!plane_state->gamma_correction->is_identity &&
28784ffa801SLeo (Sunpeng) Li 			dce_use_lut(plane_state->format))
2883be5262eSHarry Wentland 		ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
289d7194cf6SAric Cyr 
29090e508baSAnthony Koo 	if (tf == NULL) {
29190e508baSAnthony Koo 		/* Default case if no input transfer function specified */
292a6114e85SHarry Wentland 		ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
2937b0c470fSLeo (Sunpeng) Li 	} else if (tf->type == TF_TYPE_PREDEFINED) {
2947b0c470fSLeo (Sunpeng) Li 		switch (tf->tf) {
29590e508baSAnthony Koo 		case TRANSFER_FUNCTION_SRGB:
296a6114e85SHarry Wentland 			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
29790e508baSAnthony Koo 			break;
29890e508baSAnthony Koo 		case TRANSFER_FUNCTION_BT709:
299a6114e85SHarry Wentland 			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC);
30090e508baSAnthony Koo 			break;
30190e508baSAnthony Koo 		case TRANSFER_FUNCTION_LINEAR:
302a6114e85SHarry Wentland 			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
30390e508baSAnthony Koo 			break;
30490e508baSAnthony Koo 		case TRANSFER_FUNCTION_PQ:
30590e508baSAnthony Koo 		default:
30690e508baSAnthony Koo 			result = false;
307d7194cf6SAric Cyr 			break;
30890e508baSAnthony Koo 		}
3097b0c470fSLeo (Sunpeng) Li 	} else if (tf->type == TF_TYPE_BYPASS) {
31070063a59SAmy Zhang 		ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
31190e508baSAnthony Koo 	} else {
31290e508baSAnthony Koo 		/*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
31390e508baSAnthony Koo 		result = false;
31490e508baSAnthony Koo 	}
31590e508baSAnthony Koo 
31690e508baSAnthony Koo 	return result;
31790e508baSAnthony Koo }
31890e508baSAnthony Koo 
319bd1be8e8SHarry Wentland static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted,
320fcd2f4bfSAmy Zhang 				    struct curve_points *arr_points,
321fcd2f4bfSAmy Zhang 				    uint32_t hw_points_num)
322fcd2f4bfSAmy Zhang {
323fcd2f4bfSAmy Zhang 	struct custom_float_format fmt;
324fcd2f4bfSAmy Zhang 
325fcd2f4bfSAmy Zhang 	struct pwl_result_data *rgb = rgb_resulted;
326fcd2f4bfSAmy Zhang 
327fcd2f4bfSAmy Zhang 	uint32_t i = 0;
328fcd2f4bfSAmy Zhang 
329fcd2f4bfSAmy Zhang 	fmt.exponenta_bits = 6;
330fcd2f4bfSAmy Zhang 	fmt.mantissa_bits = 12;
331fcd2f4bfSAmy Zhang 	fmt.sign = true;
332fcd2f4bfSAmy Zhang 
333bd1be8e8SHarry Wentland 	if (!convert_to_custom_float_format(arr_points[0].x, &fmt,
334fcd2f4bfSAmy Zhang 					    &arr_points[0].custom_float_x)) {
335fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
336fcd2f4bfSAmy Zhang 		return false;
337fcd2f4bfSAmy Zhang 	}
338fcd2f4bfSAmy Zhang 
339bd1be8e8SHarry Wentland 	if (!convert_to_custom_float_format(arr_points[0].offset, &fmt,
340fcd2f4bfSAmy Zhang 					    &arr_points[0].custom_float_offset)) {
341fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
342fcd2f4bfSAmy Zhang 		return false;
343fcd2f4bfSAmy Zhang 	}
344fcd2f4bfSAmy Zhang 
345bd1be8e8SHarry Wentland 	if (!convert_to_custom_float_format(arr_points[0].slope, &fmt,
346fcd2f4bfSAmy Zhang 					    &arr_points[0].custom_float_slope)) {
347fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
348fcd2f4bfSAmy Zhang 		return false;
349fcd2f4bfSAmy Zhang 	}
350fcd2f4bfSAmy Zhang 
351fcd2f4bfSAmy Zhang 	fmt.mantissa_bits = 10;
352fcd2f4bfSAmy Zhang 	fmt.sign = false;
353fcd2f4bfSAmy Zhang 
354bd1be8e8SHarry Wentland 	if (!convert_to_custom_float_format(arr_points[1].x, &fmt,
355fcd2f4bfSAmy Zhang 					    &arr_points[1].custom_float_x)) {
356fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
357fcd2f4bfSAmy Zhang 		return false;
358fcd2f4bfSAmy Zhang 	}
359fcd2f4bfSAmy Zhang 
360bd1be8e8SHarry Wentland 	if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
361fcd2f4bfSAmy Zhang 					    &arr_points[1].custom_float_y)) {
362fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
363fcd2f4bfSAmy Zhang 		return false;
364fcd2f4bfSAmy Zhang 	}
365fcd2f4bfSAmy Zhang 
3664d06ccd0SHarry Wentland 	if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
3674d06ccd0SHarry Wentland 					    &arr_points[1].custom_float_slope)) {
368fcd2f4bfSAmy Zhang 		BREAK_TO_DEBUGGER();
369fcd2f4bfSAmy Zhang 		return false;
370fcd2f4bfSAmy Zhang 	}
371fcd2f4bfSAmy Zhang 
372fcd2f4bfSAmy Zhang 	fmt.mantissa_bits = 12;
373fcd2f4bfSAmy Zhang 	fmt.sign = true;
374fcd2f4bfSAmy Zhang 
375fcd2f4bfSAmy Zhang 	while (i != hw_points_num) {
376bd1be8e8SHarry Wentland 		if (!convert_to_custom_float_format(rgb->red, &fmt,
377fcd2f4bfSAmy Zhang 						    &rgb->red_reg)) {
378fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
379fcd2f4bfSAmy Zhang 			return false;
380fcd2f4bfSAmy Zhang 		}
381fcd2f4bfSAmy Zhang 
382bd1be8e8SHarry Wentland 		if (!convert_to_custom_float_format(rgb->green, &fmt,
383fcd2f4bfSAmy Zhang 						    &rgb->green_reg)) {
384fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
385fcd2f4bfSAmy Zhang 			return false;
386fcd2f4bfSAmy Zhang 		}
387fcd2f4bfSAmy Zhang 
388bd1be8e8SHarry Wentland 		if (!convert_to_custom_float_format(rgb->blue, &fmt,
389fcd2f4bfSAmy Zhang 						    &rgb->blue_reg)) {
390fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
391fcd2f4bfSAmy Zhang 			return false;
392fcd2f4bfSAmy Zhang 		}
393fcd2f4bfSAmy Zhang 
394bd1be8e8SHarry Wentland 		if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
395fcd2f4bfSAmy Zhang 						    &rgb->delta_red_reg)) {
396fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
397fcd2f4bfSAmy Zhang 			return false;
398fcd2f4bfSAmy Zhang 		}
399fcd2f4bfSAmy Zhang 
400bd1be8e8SHarry Wentland 		if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
401fcd2f4bfSAmy Zhang 						    &rgb->delta_green_reg)) {
402fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
403fcd2f4bfSAmy Zhang 			return false;
404fcd2f4bfSAmy Zhang 		}
405fcd2f4bfSAmy Zhang 
406bd1be8e8SHarry Wentland 		if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
407fcd2f4bfSAmy Zhang 						    &rgb->delta_blue_reg)) {
408fcd2f4bfSAmy Zhang 			BREAK_TO_DEBUGGER();
409fcd2f4bfSAmy Zhang 			return false;
410fcd2f4bfSAmy Zhang 		}
411fcd2f4bfSAmy Zhang 
412fcd2f4bfSAmy Zhang 		++rgb;
413fcd2f4bfSAmy Zhang 		++i;
414fcd2f4bfSAmy Zhang 	}
415fcd2f4bfSAmy Zhang 
416fcd2f4bfSAmy Zhang 	return true;
417fcd2f4bfSAmy Zhang }
418fcd2f4bfSAmy Zhang 
41908616da5SLeo (Sunpeng) Li #define MAX_LOW_POINT      25
4208f8372c7SKrunoslav Kovac #define NUMBER_REGIONS     16
4218f8372c7SKrunoslav Kovac #define NUMBER_SW_SEGMENTS 16
4228f8372c7SKrunoslav Kovac 
423b310b081SHarry Wentland static bool
424b310b081SHarry Wentland dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
425b310b081SHarry Wentland 				      struct pwl_params *regamma_params)
426fcd2f4bfSAmy Zhang {
42723ae4f8eSAmy Zhang 	struct curve_points *arr_points;
42823ae4f8eSAmy Zhang 	struct pwl_result_data *rgb_resulted;
42923ae4f8eSAmy Zhang 	struct pwl_result_data *rgb;
43023ae4f8eSAmy Zhang 	struct pwl_result_data *rgb_plus_1;
431fcd2f4bfSAmy Zhang 	struct fixed31_32 y_r;
432fcd2f4bfSAmy Zhang 	struct fixed31_32 y_g;
433fcd2f4bfSAmy Zhang 	struct fixed31_32 y_b;
434fcd2f4bfSAmy Zhang 	struct fixed31_32 y1_min;
435fcd2f4bfSAmy Zhang 	struct fixed31_32 y3_max;
436fcd2f4bfSAmy Zhang 
4378f8372c7SKrunoslav Kovac 	int32_t region_start, region_end;
4388f8372c7SKrunoslav Kovac 	uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points;
43923ae4f8eSAmy Zhang 
440b310b081SHarry Wentland 	if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS)
44123ae4f8eSAmy Zhang 		return false;
44223ae4f8eSAmy Zhang 
44323ae4f8eSAmy Zhang 	arr_points = regamma_params->arr_points;
44423ae4f8eSAmy Zhang 	rgb_resulted = regamma_params->rgb_resulted;
44523ae4f8eSAmy Zhang 	hw_points = 0;
446fcd2f4bfSAmy Zhang 
447fcd2f4bfSAmy Zhang 	memset(regamma_params, 0, sizeof(struct pwl_params));
448fcd2f4bfSAmy Zhang 
449fcd2f4bfSAmy Zhang 	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
450534db198SAmy Zhang 		/* 16 segments
451fcd2f4bfSAmy Zhang 		 * segments are from 2^-11 to 2^5
452fcd2f4bfSAmy Zhang 		 */
45308616da5SLeo (Sunpeng) Li 		region_start = -11;
45408616da5SLeo (Sunpeng) Li 		region_end = region_start + NUMBER_REGIONS;
455fcd2f4bfSAmy Zhang 
4568f8372c7SKrunoslav Kovac 		for (i = 0; i < NUMBER_REGIONS; i++)
4578f8372c7SKrunoslav Kovac 			seg_distr[i] = 4;
458534db198SAmy Zhang 
459fcd2f4bfSAmy Zhang 	} else {
460534db198SAmy Zhang 		/* 10 segments
461fc6de1c5SLeo (Sunpeng) Li 		 * segment is from 2^-10 to 2^1
462fc6de1c5SLeo (Sunpeng) Li 		 * We include an extra segment for range [2^0, 2^1). This is to
463fc6de1c5SLeo (Sunpeng) Li 		 * ensure that colors with normalized values of 1 don't miss the
464fc6de1c5SLeo (Sunpeng) Li 		 * LUT.
465fcd2f4bfSAmy Zhang 		 */
4668f8372c7SKrunoslav Kovac 		region_start = -10;
467fc6de1c5SLeo (Sunpeng) Li 		region_end = 1;
468534db198SAmy Zhang 
4698f8372c7SKrunoslav Kovac 		seg_distr[0] = 4;
470534db198SAmy Zhang 		seg_distr[1] = 4;
471534db198SAmy Zhang 		seg_distr[2] = 4;
472534db198SAmy Zhang 		seg_distr[3] = 4;
473534db198SAmy Zhang 		seg_distr[4] = 4;
474534db198SAmy Zhang 		seg_distr[5] = 4;
475534db198SAmy Zhang 		seg_distr[6] = 4;
476534db198SAmy Zhang 		seg_distr[7] = 4;
4778f8372c7SKrunoslav Kovac 		seg_distr[8] = 4;
4788f8372c7SKrunoslav Kovac 		seg_distr[9] = 4;
479fc6de1c5SLeo (Sunpeng) Li 		seg_distr[10] = 0;
480534db198SAmy Zhang 		seg_distr[11] = -1;
481534db198SAmy Zhang 		seg_distr[12] = -1;
482534db198SAmy Zhang 		seg_distr[13] = -1;
483534db198SAmy Zhang 		seg_distr[14] = -1;
484534db198SAmy Zhang 		seg_distr[15] = -1;
485fcd2f4bfSAmy Zhang 	}
486fcd2f4bfSAmy Zhang 
487534db198SAmy Zhang 	for (k = 0; k < 16; k++) {
488534db198SAmy Zhang 		if (seg_distr[k] != -1)
489534db198SAmy Zhang 			hw_points += (1 << seg_distr[k]);
490534db198SAmy Zhang 	}
491534db198SAmy Zhang 
492fcd2f4bfSAmy Zhang 	j = 0;
4938f8372c7SKrunoslav Kovac 	for (k = 0; k < (region_end - region_start); k++) {
494ec47734aSLeo (Sunpeng) Li 		increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
4958f8372c7SKrunoslav Kovac 		start_index = (region_start + k + MAX_LOW_POINT) *
4968f8372c7SKrunoslav Kovac 				NUMBER_SW_SEGMENTS;
4978f8372c7SKrunoslav Kovac 		for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
4988f8372c7SKrunoslav Kovac 				i += increment) {
499534db198SAmy Zhang 			if (j == hw_points - 1)
500fcd2f4bfSAmy Zhang 				break;
501fcd2f4bfSAmy Zhang 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
502fcd2f4bfSAmy Zhang 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
503fcd2f4bfSAmy Zhang 			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
504fcd2f4bfSAmy Zhang 			j++;
505fcd2f4bfSAmy Zhang 		}
506534db198SAmy Zhang 	}
507534db198SAmy Zhang 
508534db198SAmy Zhang 	/* last point */
5098f8372c7SKrunoslav Kovac 	start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
510b310b081SHarry Wentland 	rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
511b310b081SHarry Wentland 	rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
512b310b081SHarry Wentland 	rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
513fcd2f4bfSAmy Zhang 
514eb0e5154SDmytro Laktyushkin 	arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
515eb0e5154SDmytro Laktyushkin 					     dc_fixpt_from_int(region_start));
516eb0e5154SDmytro Laktyushkin 	arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
517eb0e5154SDmytro Laktyushkin 					     dc_fixpt_from_int(region_end));
518fcd2f4bfSAmy Zhang 
519fcd2f4bfSAmy Zhang 	y_r = rgb_resulted[0].red;
520fcd2f4bfSAmy Zhang 	y_g = rgb_resulted[0].green;
521fcd2f4bfSAmy Zhang 	y_b = rgb_resulted[0].blue;
522fcd2f4bfSAmy Zhang 
523eb0e5154SDmytro Laktyushkin 	y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
524fcd2f4bfSAmy Zhang 
525fcd2f4bfSAmy Zhang 	arr_points[0].y = y1_min;
526eb0e5154SDmytro Laktyushkin 	arr_points[0].slope = dc_fixpt_div(arr_points[0].y,
527fcd2f4bfSAmy Zhang 						 arr_points[0].x);
528fcd2f4bfSAmy Zhang 
529fcd2f4bfSAmy Zhang 	y_r = rgb_resulted[hw_points - 1].red;
530fcd2f4bfSAmy Zhang 	y_g = rgb_resulted[hw_points - 1].green;
531fcd2f4bfSAmy Zhang 	y_b = rgb_resulted[hw_points - 1].blue;
532fcd2f4bfSAmy Zhang 
533fcd2f4bfSAmy Zhang 	/* see comment above, m_arrPoints[1].y should be the Y value for the
534fcd2f4bfSAmy Zhang 	 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
535fcd2f4bfSAmy Zhang 	 */
536eb0e5154SDmytro Laktyushkin 	y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
537fcd2f4bfSAmy Zhang 
538fcd2f4bfSAmy Zhang 	arr_points[1].y = y3_max;
539fcd2f4bfSAmy Zhang 
540eb0e5154SDmytro Laktyushkin 	arr_points[1].slope = dc_fixpt_zero;
541fcd2f4bfSAmy Zhang 
542fcd2f4bfSAmy Zhang 	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
543fcd2f4bfSAmy Zhang 		/* for PQ, we want to have a straight line from last HW X point,
544fcd2f4bfSAmy Zhang 		 * and the slope to be such that we hit 1.0 at 10000 nits.
545fcd2f4bfSAmy Zhang 		 */
546eb0e5154SDmytro Laktyushkin 		const struct fixed31_32 end_value = dc_fixpt_from_int(125);
547fcd2f4bfSAmy Zhang 
548eb0e5154SDmytro Laktyushkin 		arr_points[1].slope = dc_fixpt_div(
549eb0e5154SDmytro Laktyushkin 				dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
550eb0e5154SDmytro Laktyushkin 				dc_fixpt_sub(end_value, arr_points[1].x));
551fcd2f4bfSAmy Zhang 	}
552fcd2f4bfSAmy Zhang 
553fcd2f4bfSAmy Zhang 	regamma_params->hw_points_num = hw_points;
554fcd2f4bfSAmy Zhang 
55569133b89SAric Cyr 	k = 0;
55669133b89SAric Cyr 	for (i = 1; i < 16; i++) {
557534db198SAmy Zhang 		if (seg_distr[k] != -1) {
558b310b081SHarry Wentland 			regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
559534db198SAmy Zhang 			regamma_params->arr_curve_points[i].offset =
560b310b081SHarry Wentland 					regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
561fcd2f4bfSAmy Zhang 		}
56269133b89SAric Cyr 		k++;
563534db198SAmy Zhang 	}
564534db198SAmy Zhang 
565534db198SAmy Zhang 	if (seg_distr[k] != -1)
566b310b081SHarry Wentland 		regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
567fcd2f4bfSAmy Zhang 
56823ae4f8eSAmy Zhang 	rgb = rgb_resulted;
56923ae4f8eSAmy Zhang 	rgb_plus_1 = rgb_resulted + 1;
570fcd2f4bfSAmy Zhang 
571fcd2f4bfSAmy Zhang 	i = 1;
572fcd2f4bfSAmy Zhang 
573fcd2f4bfSAmy Zhang 	while (i != hw_points + 1) {
574eb0e5154SDmytro Laktyushkin 		if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
575fcd2f4bfSAmy Zhang 			rgb_plus_1->red = rgb->red;
576eb0e5154SDmytro Laktyushkin 		if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
577fcd2f4bfSAmy Zhang 			rgb_plus_1->green = rgb->green;
578eb0e5154SDmytro Laktyushkin 		if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
579fcd2f4bfSAmy Zhang 			rgb_plus_1->blue = rgb->blue;
580fcd2f4bfSAmy Zhang 
581eb0e5154SDmytro Laktyushkin 		rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
582eb0e5154SDmytro Laktyushkin 		rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
583eb0e5154SDmytro Laktyushkin 		rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
584fcd2f4bfSAmy Zhang 
585fcd2f4bfSAmy Zhang 		++rgb_plus_1;
586fcd2f4bfSAmy Zhang 		++rgb;
587fcd2f4bfSAmy Zhang 		++i;
588fcd2f4bfSAmy Zhang 	}
589fcd2f4bfSAmy Zhang 
590fcd2f4bfSAmy Zhang 	convert_to_custom_float(rgb_resulted, arr_points, hw_points);
591fcd2f4bfSAmy Zhang 
592fcd2f4bfSAmy Zhang 	return true;
593fcd2f4bfSAmy Zhang }
594fcd2f4bfSAmy Zhang 
595a6114e85SHarry Wentland static bool
596a6114e85SHarry Wentland dce110_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
5970971c40eSHarry Wentland 				const struct dc_stream_state *stream)
59890e508baSAnthony Koo {
59986a66c4eSHarry Wentland 	struct transform *xfm = pipe_ctx->plane_res.xfm;
6004562236bSHarry Wentland 
6017a09f5beSYue Hin Lau 	xfm->funcs->opp_power_on_regamma_lut(xfm, true);
6027a09f5beSYue Hin Lau 	xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
6034562236bSHarry Wentland 
6044fa086b9SLeo (Sunpeng) Li 	if (stream->out_transfer_func &&
605efd52204SHarry Wentland 	    stream->out_transfer_func->type == TF_TYPE_PREDEFINED &&
606efd52204SHarry Wentland 	    stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) {
6077a09f5beSYue Hin Lau 		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
608efd52204SHarry Wentland 	} else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func,
609efd52204SHarry Wentland 							 &xfm->regamma_params)) {
6107a09f5beSYue Hin Lau 		xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
6117a09f5beSYue Hin Lau 		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
6124562236bSHarry Wentland 	} else {
6137a09f5beSYue Hin Lau 		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
6144562236bSHarry Wentland 	}
6154562236bSHarry Wentland 
6167a09f5beSYue Hin Lau 	xfm->funcs->opp_power_on_regamma_lut(xfm, false);
6174562236bSHarry Wentland 
618cc0cb445SLeon Elazar 	return true;
6194562236bSHarry Wentland }
6204562236bSHarry Wentland 
6214562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
6224562236bSHarry Wentland {
62302553f57SEric Bernstein 	bool is_hdmi_tmds;
6246f0db2dcSKrunoslav Kovac 	bool is_dp;
6256f0db2dcSKrunoslav Kovac 
62686e2e1beSHersen Wu 	ASSERT(pipe_ctx->stream);
62786e2e1beSHersen Wu 
6288e9c4c8cSHarry Wentland 	if (pipe_ctx->stream_res.stream_enc == NULL)
62986e2e1beSHersen Wu 		return;  /* this is not root pipe */
63086e2e1beSHersen Wu 
63102553f57SEric Bernstein 	is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
6326f0db2dcSKrunoslav Kovac 	is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
6336f0db2dcSKrunoslav Kovac 
63402553f57SEric Bernstein 	if (!is_hdmi_tmds && !is_dp)
6356f0db2dcSKrunoslav Kovac 		return;
6366f0db2dcSKrunoslav Kovac 
63702553f57SEric Bernstein 	if (is_hdmi_tmds)
6388e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
6398e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
64096c50c0dSHarry Wentland 			&pipe_ctx->stream_res.encoder_info_frame);
6416f0db2dcSKrunoslav Kovac 	else
6428e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
6438e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc,
64496c50c0dSHarry Wentland 			&pipe_ctx->stream_res.encoder_info_frame);
6454562236bSHarry Wentland }
6464562236bSHarry Wentland 
6474562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
6484562236bSHarry Wentland {
6494562236bSHarry Wentland 	enum dc_lane_count lane_count =
650ceb3dbb4SJun Lei 		pipe_ctx->stream->link->cur_link_settings.lane_count;
6514562236bSHarry Wentland 
6524fa086b9SLeo (Sunpeng) Li 	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
653ceb3dbb4SJun Lei 	struct dc_link *link = pipe_ctx->stream->link;
6544562236bSHarry Wentland 
655f215a57dSEric Yang 
6564562236bSHarry Wentland 	uint32_t active_total_with_borders;
6574562236bSHarry Wentland 	uint32_t early_control = 0;
6586b670fa9SHarry Wentland 	struct timing_generator *tg = pipe_ctx->stream_res.tg;
6594562236bSHarry Wentland 
660f215a57dSEric Yang 	/* For MST, there are multiply stream go to only one link.
661f215a57dSEric Yang 	 * connect DIG back_end to front_end while enable_stream and
662f215a57dSEric Yang 	 * disconnect them during disable_stream
663f215a57dSEric Yang 	 * BY this, it is logic clean to separate stream and link */
664f215a57dSEric Yang 	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
665f215a57dSEric Yang 						    pipe_ctx->stream_res.stream_enc->id, true);
666f215a57dSEric Yang 
667f215a57dSEric Yang 	/* update AVI info frame (HDMI, DP)*/
668f215a57dSEric Yang 	/* TODO: FPGA may change to hwss.update_info_frame */
6694562236bSHarry Wentland 	dce110_update_info_frame(pipe_ctx);
670f215a57dSEric Yang 
6714562236bSHarry Wentland 	/* enable early control to avoid corruption on DP monitor*/
6724562236bSHarry Wentland 	active_total_with_borders =
6734562236bSHarry Wentland 			timing->h_addressable
6744562236bSHarry Wentland 				+ timing->h_border_left
6754562236bSHarry Wentland 				+ timing->h_border_right;
6764562236bSHarry Wentland 
6774562236bSHarry Wentland 	if (lane_count != 0)
6784562236bSHarry Wentland 		early_control = active_total_with_borders % lane_count;
6794562236bSHarry Wentland 
6804562236bSHarry Wentland 	if (early_control == 0)
6814562236bSHarry Wentland 		early_control = lane_count;
6824562236bSHarry Wentland 
6834562236bSHarry Wentland 	tg->funcs->set_early_control(tg, early_control);
6844562236bSHarry Wentland 
6854562236bSHarry Wentland 	/* enable audio only within mode set */
686afaacef4SHarry Wentland 	if (pipe_ctx->stream_res.audio != NULL) {
6874562236bSHarry Wentland 		if (dc_is_dp_signal(pipe_ctx->stream->signal))
6888e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
6894562236bSHarry Wentland 	}
6904562236bSHarry Wentland 
691f215a57dSEric Yang 
692f215a57dSEric Yang 
6934562236bSHarry Wentland 
6944562236bSHarry Wentland }
6954562236bSHarry Wentland 
6965eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/
6975eefbc40SYue Hin Lau static bool is_panel_backlight_on(struct dce_hwseq *hws)
6985eefbc40SYue Hin Lau {
6995eefbc40SYue Hin Lau 	uint32_t value;
7005eefbc40SYue Hin Lau 
7015eefbc40SYue Hin Lau 	REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
7025eefbc40SYue Hin Lau 
7035eefbc40SYue Hin Lau 	return value;
7045eefbc40SYue Hin Lau }
7055eefbc40SYue Hin Lau 
70687401969SAndrew Jiang static bool is_panel_powered_on(struct dce_hwseq *hws)
70787401969SAndrew Jiang {
708d03f3f63SEric Yang 	uint32_t pwr_seq_state, dig_on, dig_on_ovrd;
70987401969SAndrew Jiang 
710d03f3f63SEric Yang 
711d03f3f63SEric Yang 	REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &pwr_seq_state);
712d03f3f63SEric Yang 
713d03f3f63SEric Yang 	REG_GET_2(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, &dig_on, LVTMA_DIGON_OVRD, &dig_on_ovrd);
714d03f3f63SEric Yang 
715d03f3f63SEric Yang 	return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1);
71687401969SAndrew Jiang }
71787401969SAndrew Jiang 
7185eefbc40SYue Hin Lau static enum bp_result link_transmitter_control(
71987401969SAndrew Jiang 		struct dc_bios *bios,
7205eefbc40SYue Hin Lau 	struct bp_transmitter_control *cntl)
7215eefbc40SYue Hin Lau {
7225eefbc40SYue Hin Lau 	enum bp_result result;
7235eefbc40SYue Hin Lau 
72487401969SAndrew Jiang 	result = bios->funcs->transmitter_control(bios, cntl);
7255eefbc40SYue Hin Lau 
7265eefbc40SYue Hin Lau 	return result;
7275eefbc40SYue Hin Lau }
7285eefbc40SYue Hin Lau 
72987401969SAndrew Jiang /*
73087401969SAndrew Jiang  * @brief
73187401969SAndrew Jiang  * eDP only.
73287401969SAndrew Jiang  */
73387401969SAndrew Jiang void hwss_edp_wait_for_hpd_ready(
734069d418fSAndrew Jiang 		struct dc_link *link,
73587401969SAndrew Jiang 		bool power_up)
73687401969SAndrew Jiang {
737069d418fSAndrew Jiang 	struct dc_context *ctx = link->ctx;
738069d418fSAndrew Jiang 	struct graphics_object_id connector = link->link_enc->connector;
73987401969SAndrew Jiang 	struct gpio *hpd;
74087401969SAndrew Jiang 	bool edp_hpd_high = false;
74187401969SAndrew Jiang 	uint32_t time_elapsed = 0;
74287401969SAndrew Jiang 	uint32_t timeout = power_up ?
74387401969SAndrew Jiang 		PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
74487401969SAndrew Jiang 
74587401969SAndrew Jiang 	if (dal_graphics_object_id_get_connector_id(connector)
74687401969SAndrew Jiang 			!= CONNECTOR_ID_EDP) {
74787401969SAndrew Jiang 		BREAK_TO_DEBUGGER();
74887401969SAndrew Jiang 		return;
74987401969SAndrew Jiang 	}
75087401969SAndrew Jiang 
75187401969SAndrew Jiang 	if (!power_up)
75287401969SAndrew Jiang 		/*
75387401969SAndrew Jiang 		 * From KV, we will not HPD low after turning off VCC -
75487401969SAndrew Jiang 		 * instead, we will check the SW timer in power_up().
75587401969SAndrew Jiang 		 */
75687401969SAndrew Jiang 		return;
75787401969SAndrew Jiang 
75887401969SAndrew Jiang 	/*
75987401969SAndrew Jiang 	 * When we power on/off the eDP panel,
76087401969SAndrew Jiang 	 * we need to wait until SENSE bit is high/low.
76187401969SAndrew Jiang 	 */
76287401969SAndrew Jiang 
76387401969SAndrew Jiang 	/* obtain HPD */
76487401969SAndrew Jiang 	/* TODO what to do with this? */
76587401969SAndrew Jiang 	hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
76687401969SAndrew Jiang 
76787401969SAndrew Jiang 	if (!hpd) {
76887401969SAndrew Jiang 		BREAK_TO_DEBUGGER();
76987401969SAndrew Jiang 		return;
77087401969SAndrew Jiang 	}
77187401969SAndrew Jiang 
77287401969SAndrew Jiang 	dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
77387401969SAndrew Jiang 
77487401969SAndrew Jiang 	/* wait until timeout or panel detected */
77587401969SAndrew Jiang 
77687401969SAndrew Jiang 	do {
77787401969SAndrew Jiang 		uint32_t detected = 0;
77887401969SAndrew Jiang 
77987401969SAndrew Jiang 		dal_gpio_get_value(hpd, &detected);
78087401969SAndrew Jiang 
78187401969SAndrew Jiang 		if (!(detected ^ power_up)) {
78287401969SAndrew Jiang 			edp_hpd_high = true;
78387401969SAndrew Jiang 			break;
78487401969SAndrew Jiang 		}
78587401969SAndrew Jiang 
78687401969SAndrew Jiang 		msleep(HPD_CHECK_INTERVAL);
78787401969SAndrew Jiang 
78887401969SAndrew Jiang 		time_elapsed += HPD_CHECK_INTERVAL;
78987401969SAndrew Jiang 	} while (time_elapsed < timeout);
79087401969SAndrew Jiang 
79187401969SAndrew Jiang 	dal_gpio_close(hpd);
79287401969SAndrew Jiang 
79387401969SAndrew Jiang 	dal_gpio_destroy_irq(&hpd);
79487401969SAndrew Jiang 
79587401969SAndrew Jiang 	if (false == edp_hpd_high) {
7961296423bSBhawanpreet Lakha 		DC_LOG_ERROR(
79787401969SAndrew Jiang 				"%s: wait timed out!\n", __func__);
79887401969SAndrew Jiang 	}
79987401969SAndrew Jiang }
80087401969SAndrew Jiang 
80187401969SAndrew Jiang void hwss_edp_power_control(
802069d418fSAndrew Jiang 		struct dc_link *link,
80387401969SAndrew Jiang 		bool power_up)
80487401969SAndrew Jiang {
805069d418fSAndrew Jiang 	struct dc_context *ctx = link->ctx;
80687401969SAndrew Jiang 	struct dce_hwseq *hwseq = ctx->dc->hwseq;
80787401969SAndrew Jiang 	struct bp_transmitter_control cntl = { 0 };
80887401969SAndrew Jiang 	enum bp_result bp_result;
80987401969SAndrew Jiang 
81087401969SAndrew Jiang 
811069d418fSAndrew Jiang 	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
81287401969SAndrew Jiang 			!= CONNECTOR_ID_EDP) {
81387401969SAndrew Jiang 		BREAK_TO_DEBUGGER();
81487401969SAndrew Jiang 		return;
81587401969SAndrew Jiang 	}
81687401969SAndrew Jiang 
81787401969SAndrew Jiang 	if (power_up != is_panel_powered_on(hwseq)) {
81887401969SAndrew Jiang 		/* Send VBIOS command to prompt eDP panel power */
81978d5d04dSCharlene Liu 		if (power_up) {
82078d5d04dSCharlene Liu 			unsigned long long current_ts = dm_get_timestamp(ctx);
82178d5d04dSCharlene Liu 			unsigned long long duration_in_ms =
82293ed1814SHugo Hu 					div64_u64(dm_get_elapse_time_in_ns(
82378d5d04dSCharlene Liu 							ctx,
82478d5d04dSCharlene Liu 							current_ts,
82593ed1814SHugo Hu 							link->link_trace.time_stamp.edp_poweroff), 1000000);
82678d5d04dSCharlene Liu 			unsigned long long wait_time_ms = 0;
82778d5d04dSCharlene Liu 
82878d5d04dSCharlene Liu 			/* max 500ms from LCDVDD off to on */
8296c4fff06SYue Hin Lau 			unsigned long long edp_poweroff_time_ms = 500;
830ff587987SHugo Hu 
8316c4fff06SYue Hin Lau 			if (link->local_sink != NULL)
8326c4fff06SYue Hin Lau 				edp_poweroff_time_ms =
8336c4fff06SYue Hin Lau 						500 + link->local_sink->edid_caps.panel_patch.extra_t12_ms;
83478d5d04dSCharlene Liu 			if (link->link_trace.time_stamp.edp_poweroff == 0)
835ff587987SHugo Hu 				wait_time_ms = edp_poweroff_time_ms;
836ff587987SHugo Hu 			else if (duration_in_ms < edp_poweroff_time_ms)
837ff587987SHugo Hu 				wait_time_ms = edp_poweroff_time_ms - duration_in_ms;
83878d5d04dSCharlene Liu 
83978d5d04dSCharlene Liu 			if (wait_time_ms) {
84078d5d04dSCharlene Liu 				msleep(wait_time_ms);
84178d5d04dSCharlene Liu 				dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
84278d5d04dSCharlene Liu 						__func__, wait_time_ms);
84378d5d04dSCharlene Liu 			}
84478d5d04dSCharlene Liu 
84578d5d04dSCharlene Liu 		}
84687401969SAndrew Jiang 
8471296423bSBhawanpreet Lakha 		DC_LOG_HW_RESUME_S3(
84887401969SAndrew Jiang 				"%s: Panel Power action: %s\n",
84987401969SAndrew Jiang 				__func__, (power_up ? "On":"Off"));
85087401969SAndrew Jiang 
85187401969SAndrew Jiang 		cntl.action = power_up ?
85287401969SAndrew Jiang 			TRANSMITTER_CONTROL_POWER_ON :
85387401969SAndrew Jiang 			TRANSMITTER_CONTROL_POWER_OFF;
854069d418fSAndrew Jiang 		cntl.transmitter = link->link_enc->transmitter;
855069d418fSAndrew Jiang 		cntl.connector_obj_id = link->link_enc->connector;
85687401969SAndrew Jiang 		cntl.coherent = false;
85787401969SAndrew Jiang 		cntl.lanes_number = LANE_COUNT_FOUR;
858069d418fSAndrew Jiang 		cntl.hpd_sel = link->link_enc->hpd_source;
85987401969SAndrew Jiang 		bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
86087401969SAndrew Jiang 
86178d5d04dSCharlene Liu 		if (!power_up)
86278d5d04dSCharlene Liu 			/*save driver power off time stamp*/
86378d5d04dSCharlene Liu 			link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx);
86478d5d04dSCharlene Liu 		else
86578d5d04dSCharlene Liu 			link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx);
86678d5d04dSCharlene Liu 
86787401969SAndrew Jiang 		if (bp_result != BP_RESULT_OK)
8681296423bSBhawanpreet Lakha 			DC_LOG_ERROR(
86987401969SAndrew Jiang 					"%s: Panel Power bp_result: %d\n",
87087401969SAndrew Jiang 					__func__, bp_result);
87187401969SAndrew Jiang 	} else {
8721296423bSBhawanpreet Lakha 		DC_LOG_HW_RESUME_S3(
87387401969SAndrew Jiang 				"%s: Skipping Panel Power action: %s\n",
87487401969SAndrew Jiang 				__func__, (power_up ? "On":"Off"));
87587401969SAndrew Jiang 	}
87687401969SAndrew Jiang }
8775eefbc40SYue Hin Lau 
8785eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/
8795eefbc40SYue Hin Lau /*
8805eefbc40SYue Hin Lau  * @brief
8815eefbc40SYue Hin Lau  * eDP only. Control the backlight of the eDP panel
8825eefbc40SYue Hin Lau  */
88387401969SAndrew Jiang void hwss_edp_backlight_control(
8845eefbc40SYue Hin Lau 		struct dc_link *link,
8855eefbc40SYue Hin Lau 		bool enable)
8865eefbc40SYue Hin Lau {
887069d418fSAndrew Jiang 	struct dc_context *ctx = link->ctx;
888069d418fSAndrew Jiang 	struct dce_hwseq *hws = ctx->dc->hwseq;
8895eefbc40SYue Hin Lau 	struct bp_transmitter_control cntl = { 0 };
8905eefbc40SYue Hin Lau 
891069d418fSAndrew Jiang 	if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
8925eefbc40SYue Hin Lau 		!= CONNECTOR_ID_EDP) {
8935eefbc40SYue Hin Lau 		BREAK_TO_DEBUGGER();
8945eefbc40SYue Hin Lau 		return;
8955eefbc40SYue Hin Lau 	}
8965eefbc40SYue Hin Lau 
8975eefbc40SYue Hin Lau 	if (enable && is_panel_backlight_on(hws)) {
8981296423bSBhawanpreet Lakha 		DC_LOG_HW_RESUME_S3(
8995eefbc40SYue Hin Lau 				"%s: panel already powered up. Do nothing.\n",
9005eefbc40SYue Hin Lau 				__func__);
9015eefbc40SYue Hin Lau 		return;
9025eefbc40SYue Hin Lau 	}
9035eefbc40SYue Hin Lau 
9045eefbc40SYue Hin Lau 	/* Send VBIOS command to control eDP panel backlight */
9055eefbc40SYue Hin Lau 
9061296423bSBhawanpreet Lakha 	DC_LOG_HW_RESUME_S3(
9075eefbc40SYue Hin Lau 			"%s: backlight action: %s\n",
9085eefbc40SYue Hin Lau 			__func__, (enable ? "On":"Off"));
9095eefbc40SYue Hin Lau 
9105eefbc40SYue Hin Lau 	cntl.action = enable ?
9115eefbc40SYue Hin Lau 		TRANSMITTER_CONTROL_BACKLIGHT_ON :
9125eefbc40SYue Hin Lau 		TRANSMITTER_CONTROL_BACKLIGHT_OFF;
91387401969SAndrew Jiang 
9145eefbc40SYue Hin Lau 	/*cntl.engine_id = ctx->engine;*/
9155eefbc40SYue Hin Lau 	cntl.transmitter = link->link_enc->transmitter;
9165eefbc40SYue Hin Lau 	cntl.connector_obj_id = link->link_enc->connector;
9175eefbc40SYue Hin Lau 	/*todo: unhardcode*/
9185eefbc40SYue Hin Lau 	cntl.lanes_number = LANE_COUNT_FOUR;
9195eefbc40SYue Hin Lau 	cntl.hpd_sel = link->link_enc->hpd_source;
920cf1835f0SCharlene Liu 	cntl.signal = SIGNAL_TYPE_EDP;
9215eefbc40SYue Hin Lau 
9225eefbc40SYue Hin Lau 	/* For eDP, the following delays might need to be considered
9235eefbc40SYue Hin Lau 	 * after link training completed:
9245eefbc40SYue Hin Lau 	 * idle period - min. accounts for required BS-Idle pattern,
9255eefbc40SYue Hin Lau 	 * max. allows for source frame synchronization);
9265eefbc40SYue Hin Lau 	 * 50 msec max. delay from valid video data from source
9275eefbc40SYue Hin Lau 	 * to video on dislpay or backlight enable.
9285eefbc40SYue Hin Lau 	 *
9295eefbc40SYue Hin Lau 	 * Disable the delay for now.
9305eefbc40SYue Hin Lau 	 * Enable it in the future if necessary.
9315eefbc40SYue Hin Lau 	 */
9325eefbc40SYue Hin Lau 	/* dc_service_sleep_in_milliseconds(50); */
9335180d4a4SCharlene Liu 		/*edp 1.2*/
9345180d4a4SCharlene Liu 	if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
9355180d4a4SCharlene Liu 		edp_receiver_ready_T7(link);
936069d418fSAndrew Jiang 	link_transmitter_control(ctx->dc_bios, &cntl);
93769b9723aSCharlene Liu 	/*edp 1.2*/
9385180d4a4SCharlene Liu 	if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF)
93969b9723aSCharlene Liu 		edp_receiver_ready_T9(link);
9405eefbc40SYue Hin Lau }
9415eefbc40SYue Hin Lau 
94276d981a9SAlex Deucher // Static helper function which calls the correct function
94376d981a9SAlex Deucher // based on pp_smu version
94476d981a9SAlex Deucher static void set_pme_wa_enable_by_version(struct dc *dc)
94576d981a9SAlex Deucher {
94676d981a9SAlex Deucher 	struct pp_smu_funcs *pp_smu = NULL;
94776d981a9SAlex Deucher 
94876d981a9SAlex Deucher 	if (dc->res_pool->pp_smu)
94976d981a9SAlex Deucher 		pp_smu = dc->res_pool->pp_smu;
95076d981a9SAlex Deucher 
95176d981a9SAlex Deucher 	if (pp_smu) {
95276d981a9SAlex Deucher 		if (pp_smu->ctx.ver == PP_SMU_VER_RV && pp_smu->rv_funcs.set_pme_wa_enable)
95376d981a9SAlex Deucher 			pp_smu->rv_funcs.set_pme_wa_enable(&(pp_smu->ctx));
95476d981a9SAlex Deucher 	}
95576d981a9SAlex Deucher }
95676d981a9SAlex Deucher 
9571a05873fSAnthony Koo void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
9584562236bSHarry Wentland {
9591a05873fSAnthony Koo 	/* notify audio driver for audio modes of monitor */
9600f1a6ad7SJun Lei 	struct dc *core_dc = pipe_ctx->stream->ctx->dc;
9610f1a6ad7SJun Lei 	struct pp_smu_funcs *pp_smu = NULL;
9621a05873fSAnthony Koo 	unsigned int i, num_audio = 1;
9631a05873fSAnthony Koo 
9640a32df9cSEryk Brol 	if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
9650a32df9cSEryk Brol 		return;
9660a32df9cSEryk Brol 
9670f1a6ad7SJun Lei 	if (core_dc->res_pool->pp_smu)
9680f1a6ad7SJun Lei 		pp_smu = core_dc->res_pool->pp_smu;
9690f1a6ad7SJun Lei 
9701a05873fSAnthony Koo 	if (pipe_ctx->stream_res.audio) {
9711a05873fSAnthony Koo 		for (i = 0; i < MAX_PIPES; i++) {
9721a05873fSAnthony Koo 			/*current_state not updated yet*/
9731a05873fSAnthony Koo 			if (core_dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
9741a05873fSAnthony Koo 				num_audio++;
9751a05873fSAnthony Koo 		}
9761a05873fSAnthony Koo 
9771a05873fSAnthony Koo 		pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
9781a05873fSAnthony Koo 
97976d981a9SAlex Deucher 		if (num_audio >= 1 && pp_smu != NULL)
9801a05873fSAnthony Koo 			/*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
98176d981a9SAlex Deucher 			set_pme_wa_enable_by_version(core_dc);
9821a05873fSAnthony Koo 		/* un-mute audio */
9831a05873fSAnthony Koo 		/* TODO: audio should be per stream rather than per link */
9841a05873fSAnthony Koo 		pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
9851a05873fSAnthony Koo 					pipe_ctx->stream_res.stream_enc, false);
9860a32df9cSEryk Brol 		if (pipe_ctx->stream_res.audio)
9870a32df9cSEryk Brol 			pipe_ctx->stream_res.audio->enabled = true;
9881a05873fSAnthony Koo 	}
9891a05873fSAnthony Koo }
9901a05873fSAnthony Koo 
9911a05873fSAnthony Koo void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option)
9921a05873fSAnthony Koo {
9934176664bSCharlene Liu 	struct dc *dc = pipe_ctx->stream->ctx->dc;
9940f1a6ad7SJun Lei 	struct pp_smu_funcs *pp_smu = NULL;
9954562236bSHarry Wentland 
9960a32df9cSEryk Brol 	if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
9970a32df9cSEryk Brol 		return;
9980a32df9cSEryk Brol 
9992b7c97d6SCharlene Liu 	pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
10002b7c97d6SCharlene Liu 			pipe_ctx->stream_res.stream_enc, true);
1001afaacef4SHarry Wentland 	if (pipe_ctx->stream_res.audio) {
10020f1a6ad7SJun Lei 		if (dc->res_pool->pp_smu)
10030f1a6ad7SJun Lei 			pp_smu = dc->res_pool->pp_smu;
1004070fe724SCharlene Liu 
10057c357e61SCharlene Liu 		if (option != KEEP_ACQUIRED_RESOURCE ||
10060f1a6ad7SJun Lei 				!dc->debug.az_endpoint_mute_only)
10077c357e61SCharlene Liu 			/*only disalbe az_endpoint if power down or free*/
1008afaacef4SHarry Wentland 			pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
10094562236bSHarry Wentland 
10104562236bSHarry Wentland 		if (dc_is_dp_signal(pipe_ctx->stream->signal))
10118e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
10128e9c4c8cSHarry Wentland 					pipe_ctx->stream_res.stream_enc);
10134562236bSHarry Wentland 		else
10148e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
10158e9c4c8cSHarry Wentland 					pipe_ctx->stream_res.stream_enc);
10164176664bSCharlene Liu 		/*don't free audio if it is from retrain or internal disable stream*/
10174176664bSCharlene Liu 		if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
10184176664bSCharlene Liu 			/*we have to dynamic arbitrate the audio endpoints*/
10194176664bSCharlene Liu 			/*we free the resource, need reset is_audio_acquired*/
10204176664bSCharlene Liu 			update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
1021fb5fb63aSCharlene Liu 			pipe_ctx->stream_res.audio = NULL;
10224176664bSCharlene Liu 		}
102376d981a9SAlex Deucher 		if (pp_smu != NULL)
1024070fe724SCharlene Liu 			/*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
102576d981a9SAlex Deucher 			set_pme_wa_enable_by_version(dc);
10264562236bSHarry Wentland 
10274562236bSHarry Wentland 		/* TODO: notify audio driver for if audio modes list changed
10284562236bSHarry Wentland 		 * add audio mode list change flag */
10294562236bSHarry Wentland 		/* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
10304562236bSHarry Wentland 		 * stream->stream_engine_id);
10314562236bSHarry Wentland 		 */
10320a32df9cSEryk Brol 		if (pipe_ctx->stream_res.audio)
10330a32df9cSEryk Brol 			pipe_ctx->stream_res.audio->enabled = false;
10344562236bSHarry Wentland 	}
10351a05873fSAnthony Koo }
10364562236bSHarry Wentland 
10371a05873fSAnthony Koo void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
10381a05873fSAnthony Koo {
10391a05873fSAnthony Koo 	struct dc_stream_state *stream = pipe_ctx->stream;
1040ceb3dbb4SJun Lei 	struct dc_link *link = stream->link;
10411a05873fSAnthony Koo 	struct dc *dc = pipe_ctx->stream->ctx->dc;
10421a05873fSAnthony Koo 
104302553f57SEric Bernstein 	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
10441a05873fSAnthony Koo 		pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
10451a05873fSAnthony Koo 			pipe_ctx->stream_res.stream_enc);
10461a05873fSAnthony Koo 
10471a05873fSAnthony Koo 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
10481a05873fSAnthony Koo 		pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
10491a05873fSAnthony Koo 			pipe_ctx->stream_res.stream_enc);
10501a05873fSAnthony Koo 
10511a05873fSAnthony Koo 	dc->hwss.disable_audio_stream(pipe_ctx, option);
1052904623eeSYongqiang Sun 
10534562236bSHarry Wentland 	link->link_enc->funcs->connect_dig_be_to_fe(
10544562236bSHarry Wentland 			link->link_enc,
10558e9c4c8cSHarry Wentland 			pipe_ctx->stream_res.stream_enc->id,
10564562236bSHarry Wentland 			false);
10574562236bSHarry Wentland 
10584562236bSHarry Wentland }
10594562236bSHarry Wentland 
10604562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
10614562236bSHarry Wentland 		struct dc_link_settings *link_settings)
10624562236bSHarry Wentland {
10634562236bSHarry Wentland 	struct encoder_unblank_param params = { { 0 } };
106441b49742SCharlene Liu 	struct dc_stream_state *stream = pipe_ctx->stream;
1065ceb3dbb4SJun Lei 	struct dc_link *link = stream->link;
10664562236bSHarry Wentland 
10674562236bSHarry Wentland 	/* only 3 items below are used by unblank */
10687fe538a4SCharlene Liu 	params.timing = pipe_ctx->stream->timing;
10694562236bSHarry Wentland 	params.link_settings.link_rate = link_settings->link_rate;
107041b49742SCharlene Liu 
107141b49742SCharlene Liu 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
10728e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
107341b49742SCharlene Liu 
107414d6f644SYongqiang Sun 	if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
107541b49742SCharlene Liu 		link->dc->hwss.edp_backlight_control(link, true);
107614d6f644SYongqiang Sun 	}
107741b49742SCharlene Liu }
10782c850b7bSDmytro Laktyushkin 
107941b49742SCharlene Liu void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
108041b49742SCharlene Liu {
108141b49742SCharlene Liu 	struct dc_stream_state *stream = pipe_ctx->stream;
1082ceb3dbb4SJun Lei 	struct dc_link *link = stream->link;
108341b49742SCharlene Liu 
1084ab892598SRoman Li 	if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
108541b49742SCharlene Liu 		link->dc->hwss.edp_backlight_control(link, false);
1086ab892598SRoman Li 		dc_link_set_abm_disable(link);
1087ab892598SRoman Li 	}
108841b49742SCharlene Liu 
108941b49742SCharlene Liu 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
109041b49742SCharlene Liu 		pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
10914562236bSHarry Wentland }
10924562236bSHarry Wentland 
109315e17335SCharlene Liu 
109415e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
109515e17335SCharlene Liu {
10968e9c4c8cSHarry Wentland 	if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
10978e9c4c8cSHarry Wentland 		pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
109815e17335SCharlene Liu }
109915e17335SCharlene Liu 
11004562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
11014562236bSHarry Wentland {
11024562236bSHarry Wentland 	switch (crtc_id) {
11034562236bSHarry Wentland 	case CONTROLLER_ID_D0:
11044562236bSHarry Wentland 		return DTO_SOURCE_ID0;
11054562236bSHarry Wentland 	case CONTROLLER_ID_D1:
11064562236bSHarry Wentland 		return DTO_SOURCE_ID1;
11074562236bSHarry Wentland 	case CONTROLLER_ID_D2:
11084562236bSHarry Wentland 		return DTO_SOURCE_ID2;
11094562236bSHarry Wentland 	case CONTROLLER_ID_D3:
11104562236bSHarry Wentland 		return DTO_SOURCE_ID3;
11114562236bSHarry Wentland 	case CONTROLLER_ID_D4:
11124562236bSHarry Wentland 		return DTO_SOURCE_ID4;
11134562236bSHarry Wentland 	case CONTROLLER_ID_D5:
11144562236bSHarry Wentland 		return DTO_SOURCE_ID5;
11154562236bSHarry Wentland 	default:
11164562236bSHarry Wentland 		return DTO_SOURCE_UNKNOWN;
11174562236bSHarry Wentland 	}
11184562236bSHarry Wentland }
11194562236bSHarry Wentland 
11204562236bSHarry Wentland static void build_audio_output(
1121ab8db3e1SAndrey Grodzovsky 	struct dc_state *state,
11224562236bSHarry Wentland 	const struct pipe_ctx *pipe_ctx,
11234562236bSHarry Wentland 	struct audio_output *audio_output)
11244562236bSHarry Wentland {
11250971c40eSHarry Wentland 	const struct dc_stream_state *stream = pipe_ctx->stream;
11268e9c4c8cSHarry Wentland 	audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id;
11274562236bSHarry Wentland 
11284562236bSHarry Wentland 	audio_output->signal = pipe_ctx->stream->signal;
11294562236bSHarry Wentland 
11304562236bSHarry Wentland 	/* audio_crtc_info  */
11314562236bSHarry Wentland 
11324562236bSHarry Wentland 	audio_output->crtc_info.h_total =
11334fa086b9SLeo (Sunpeng) Li 		stream->timing.h_total;
11344562236bSHarry Wentland 
11354562236bSHarry Wentland 	/*
11364562236bSHarry Wentland 	 * Audio packets are sent during actual CRTC blank physical signal, we
11374562236bSHarry Wentland 	 * need to specify actual active signal portion
11384562236bSHarry Wentland 	 */
11394562236bSHarry Wentland 	audio_output->crtc_info.h_active =
11404fa086b9SLeo (Sunpeng) Li 			stream->timing.h_addressable
11414fa086b9SLeo (Sunpeng) Li 			+ stream->timing.h_border_left
11424fa086b9SLeo (Sunpeng) Li 			+ stream->timing.h_border_right;
11434562236bSHarry Wentland 
11444562236bSHarry Wentland 	audio_output->crtc_info.v_active =
11454fa086b9SLeo (Sunpeng) Li 			stream->timing.v_addressable
11464fa086b9SLeo (Sunpeng) Li 			+ stream->timing.v_border_top
11474fa086b9SLeo (Sunpeng) Li 			+ stream->timing.v_border_bottom;
11484562236bSHarry Wentland 
11494562236bSHarry Wentland 	audio_output->crtc_info.pixel_repetition = 1;
11504562236bSHarry Wentland 
11514562236bSHarry Wentland 	audio_output->crtc_info.interlaced =
11524fa086b9SLeo (Sunpeng) Li 			stream->timing.flags.INTERLACE;
11534562236bSHarry Wentland 
11544562236bSHarry Wentland 	audio_output->crtc_info.refresh_rate =
1155380604e2SKen Chalmers 		(stream->timing.pix_clk_100hz*10000)/
11564fa086b9SLeo (Sunpeng) Li 		(stream->timing.h_total*stream->timing.v_total);
11574562236bSHarry Wentland 
11584562236bSHarry Wentland 	audio_output->crtc_info.color_depth =
11594fa086b9SLeo (Sunpeng) Li 		stream->timing.display_color_depth;
11604562236bSHarry Wentland 
11614562236bSHarry Wentland 	audio_output->crtc_info.requested_pixel_clock =
1162380604e2SKen Chalmers 			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
11634562236bSHarry Wentland 
11644562236bSHarry Wentland 	audio_output->crtc_info.calculated_pixel_clock =
1165380604e2SKen Chalmers 			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
11664562236bSHarry Wentland 
116787b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/
116887b58768SCharlene Liu 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal) &&
116987b58768SCharlene Liu 		audio_output->crtc_info.requested_pixel_clock ==
1170380604e2SKen Chalmers 				(stream->timing.pix_clk_100hz / 10)) {
117110688217SHarry Wentland 		if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
117287b58768SCharlene Liu 			audio_output->crtc_info.requested_pixel_clock =
117387b58768SCharlene Liu 					audio_output->crtc_info.requested_pixel_clock/2;
117487b58768SCharlene Liu 			audio_output->crtc_info.calculated_pixel_clock =
1175380604e2SKen Chalmers 					pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/20;
117687b58768SCharlene Liu 
117787b58768SCharlene Liu 		}
117887b58768SCharlene Liu 	}
117987b58768SCharlene Liu 
11804562236bSHarry Wentland 	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
11814562236bSHarry Wentland 			pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
11824562236bSHarry Wentland 		audio_output->pll_info.dp_dto_source_clock_in_khz =
11830de34efcSDmytro Laktyushkin 				state->clk_mgr->funcs->get_dp_ref_clk_frequency(
11840de34efcSDmytro Laktyushkin 						state->clk_mgr);
11854562236bSHarry Wentland 	}
11864562236bSHarry Wentland 
11874562236bSHarry Wentland 	audio_output->pll_info.feed_back_divider =
11884562236bSHarry Wentland 			pipe_ctx->pll_settings.feedback_divider;
11894562236bSHarry Wentland 
11904562236bSHarry Wentland 	audio_output->pll_info.dto_source =
11914562236bSHarry Wentland 		translate_to_dto_source(
1192e07f541fSYongqiang Sun 			pipe_ctx->stream_res.tg->inst + 1);
11934562236bSHarry Wentland 
11944562236bSHarry Wentland 	/* TODO hard code to enable for now. Need get from stream */
11954562236bSHarry Wentland 	audio_output->pll_info.ss_enabled = true;
11964562236bSHarry Wentland 
11974562236bSHarry Wentland 	audio_output->pll_info.ss_percentage =
11984562236bSHarry Wentland 			pipe_ctx->pll_settings.ss_percentage;
11994562236bSHarry Wentland }
12004562236bSHarry Wentland 
12014562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx,
12024562236bSHarry Wentland 		struct tg_color *color)
12034562236bSHarry Wentland {
12042a54bd6eSJerry (Fangzhi) Zuo 	uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4;
12054562236bSHarry Wentland 
12066702a9acSHarry Wentland 	switch (pipe_ctx->plane_res.scl_data.format) {
12074562236bSHarry Wentland 	case PIXEL_FORMAT_ARGB8888:
12084562236bSHarry Wentland 		/* set boarder color to red */
12094562236bSHarry Wentland 		color->color_r_cr = color_value;
12104562236bSHarry Wentland 		break;
12114562236bSHarry Wentland 
12124562236bSHarry Wentland 	case PIXEL_FORMAT_ARGB2101010:
12134562236bSHarry Wentland 		/* set boarder color to blue */
12144562236bSHarry Wentland 		color->color_b_cb = color_value;
12154562236bSHarry Wentland 		break;
121687449a90SAnthony Koo 	case PIXEL_FORMAT_420BPP8:
12174562236bSHarry Wentland 		/* set boarder color to green */
12184562236bSHarry Wentland 		color->color_g_y = color_value;
12194562236bSHarry Wentland 		break;
122087449a90SAnthony Koo 	case PIXEL_FORMAT_420BPP10:
122187449a90SAnthony Koo 		/* set boarder color to yellow */
122287449a90SAnthony Koo 		color->color_g_y = color_value;
122387449a90SAnthony Koo 		color->color_r_cr = color_value;
122487449a90SAnthony Koo 		break;
12254562236bSHarry Wentland 	case PIXEL_FORMAT_FP16:
12264562236bSHarry Wentland 		/* set boarder color to white */
12274562236bSHarry Wentland 		color->color_r_cr = color_value;
12284562236bSHarry Wentland 		color->color_b_cb = color_value;
12294562236bSHarry Wentland 		color->color_g_y = color_value;
12304562236bSHarry Wentland 		break;
12314562236bSHarry Wentland 	default:
12324562236bSHarry Wentland 		break;
12334562236bSHarry Wentland 	}
12344562236bSHarry Wentland }
12354562236bSHarry Wentland 
1236fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc,
12374562236bSHarry Wentland 		const struct pipe_ctx *pipe_ctx)
12384562236bSHarry Wentland {
12394562236bSHarry Wentland 	struct tg_color color = {0};
12404562236bSHarry Wentland 
1241dc37a9a0SLeo (Sunpeng) Li #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1242ff5ef992SAlex Deucher 	/* TOFPGA */
124386a66c4eSHarry Wentland 	if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
1244ff5ef992SAlex Deucher 		return;
1245ff5ef992SAlex Deucher #endif
1246ff5ef992SAlex Deucher 
1247bf53769dSGloria Li 	if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
12484562236bSHarry Wentland 		get_surface_visual_confirm_color(pipe_ctx, &color);
12494562236bSHarry Wentland 	else
12504562236bSHarry Wentland 		color_space_to_black_color(dc,
12514fa086b9SLeo (Sunpeng) Li 				pipe_ctx->stream->output_color_space,
12524562236bSHarry Wentland 				&color);
12534562236bSHarry Wentland 
125486a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
125586a66c4eSHarry Wentland 		pipe_ctx->plane_res.xfm,
12566702a9acSHarry Wentland 		pipe_ctx->plane_res.scl_data.lb_params.depth,
12574562236bSHarry Wentland 		&pipe_ctx->stream->bit_depth_params);
12584562236bSHarry Wentland 
125912750d16SEric Yang 	if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {
126012750d16SEric Yang 		/*
126112750d16SEric Yang 		 * The way 420 is packed, 2 channels carry Y component, 1 channel
126212750d16SEric Yang 		 * alternate between Cb and Cr, so both channels need the pixel
126312750d16SEric Yang 		 * value for Y
126412750d16SEric Yang 		 */
126512750d16SEric Yang 		if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
126612750d16SEric Yang 			color.color_r_cr = color.color_g_y;
126712750d16SEric Yang 
12686b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
12696b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
12704562236bSHarry Wentland 				&color);
127112750d16SEric Yang 	}
12724562236bSHarry Wentland 
127386a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
12746702a9acSHarry Wentland 		&pipe_ctx->plane_res.scl_data);
12754562236bSHarry Wentland }
12764562236bSHarry Wentland 
12773158223eSEric Bernstein static enum dc_status dce110_enable_stream_timing(
12784562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx,
1279608ac7bbSJerry Zuo 		struct dc_state *context,
1280fb3466a4SBhawanpreet Lakha 		struct dc *dc)
12814562236bSHarry Wentland {
12820971c40eSHarry Wentland 	struct dc_stream_state *stream = pipe_ctx->stream;
1283608ac7bbSJerry Zuo 	struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
12844562236bSHarry Wentland 			pipe_ctx[pipe_ctx->pipe_idx];
12854562236bSHarry Wentland 	struct tg_color black_color = {0};
12864562236bSHarry Wentland 
12874562236bSHarry Wentland 	if (!pipe_ctx_old->stream) {
12884562236bSHarry Wentland 
12894562236bSHarry Wentland 		/* program blank color */
12904562236bSHarry Wentland 		color_space_to_black_color(dc,
12914fa086b9SLeo (Sunpeng) Li 				stream->output_color_space, &black_color);
12926b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_blank_color(
12936b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
12944562236bSHarry Wentland 				&black_color);
12954b5e7d62SHersen Wu 
12964562236bSHarry Wentland 		/*
12974562236bSHarry Wentland 		 * Must blank CRTC after disabling power gating and before any
12984562236bSHarry Wentland 		 * programming, otherwise CRTC will be hung in bad state
12994562236bSHarry Wentland 		 */
13006b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
13014562236bSHarry Wentland 
13024562236bSHarry Wentland 		if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
13034562236bSHarry Wentland 				pipe_ctx->clock_source,
130410688217SHarry Wentland 				&pipe_ctx->stream_res.pix_clk_params,
13054562236bSHarry Wentland 				&pipe_ctx->pll_settings)) {
13064562236bSHarry Wentland 			BREAK_TO_DEBUGGER();
13074562236bSHarry Wentland 			return DC_ERROR_UNEXPECTED;
13084562236bSHarry Wentland 		}
13094562236bSHarry Wentland 
13106b670fa9SHarry Wentland 		pipe_ctx->stream_res.tg->funcs->program_timing(
13116b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg,
13124fa086b9SLeo (Sunpeng) Li 				&stream->timing,
1313e7e10c46SDmytro Laktyushkin 				0,
1314e7e10c46SDmytro Laktyushkin 				0,
1315e7e10c46SDmytro Laktyushkin 				0,
1316e7e10c46SDmytro Laktyushkin 				0,
1317e7e10c46SDmytro Laktyushkin 				pipe_ctx->stream->signal,
13184562236bSHarry Wentland 				true);
13194562236bSHarry Wentland 	}
13204562236bSHarry Wentland 
13214562236bSHarry Wentland 	if (!pipe_ctx_old->stream) {
13226b670fa9SHarry Wentland 		if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(
13236b670fa9SHarry Wentland 				pipe_ctx->stream_res.tg)) {
13244562236bSHarry Wentland 			BREAK_TO_DEBUGGER();
13254562236bSHarry Wentland 			return DC_ERROR_UNEXPECTED;
13264562236bSHarry Wentland 		}
13274562236bSHarry Wentland 	}
13284562236bSHarry Wentland 
13294562236bSHarry Wentland 	return DC_OK;
13304562236bSHarry Wentland }
13314562236bSHarry Wentland 
13324562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw(
13334562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx,
1334608ac7bbSJerry Zuo 		struct dc_state *context,
1335fb3466a4SBhawanpreet Lakha 		struct dc *dc)
13364562236bSHarry Wentland {
13370971c40eSHarry Wentland 	struct dc_stream_state *stream = pipe_ctx->stream;
13389c0fb8d4SAnthony Koo 	struct drr_params params = {0};
13399c0fb8d4SAnthony Koo 	unsigned int event_triggers = 0;
13404562236bSHarry Wentland 
1341240d09d0SGary Kattan 	if (dc->hwss.disable_stream_gating) {
1342240d09d0SGary Kattan 		dc->hwss.disable_stream_gating(dc, pipe_ctx);
1343240d09d0SGary Kattan 	}
1344240d09d0SGary Kattan 
13451a05873fSAnthony Koo 	if (pipe_ctx->stream_res.audio != NULL) {
13461a05873fSAnthony Koo 		struct audio_output audio_output;
13471a05873fSAnthony Koo 
13481a05873fSAnthony Koo 		build_audio_output(context, pipe_ctx, &audio_output);
13491a05873fSAnthony Koo 
13501a05873fSAnthony Koo 		if (dc_is_dp_signal(pipe_ctx->stream->signal))
13511a05873fSAnthony Koo 			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
13521a05873fSAnthony Koo 					pipe_ctx->stream_res.stream_enc,
13531a05873fSAnthony Koo 					pipe_ctx->stream_res.audio->inst,
13541a05873fSAnthony Koo 					&pipe_ctx->stream->audio_info);
13551a05873fSAnthony Koo 		else
13561a05873fSAnthony Koo 			pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup(
13571a05873fSAnthony Koo 					pipe_ctx->stream_res.stream_enc,
13581a05873fSAnthony Koo 					pipe_ctx->stream_res.audio->inst,
13591a05873fSAnthony Koo 					&pipe_ctx->stream->audio_info,
13601a05873fSAnthony Koo 					&audio_output.crtc_info);
13611a05873fSAnthony Koo 
13621a05873fSAnthony Koo 		pipe_ctx->stream_res.audio->funcs->az_configure(
13631a05873fSAnthony Koo 				pipe_ctx->stream_res.audio,
13641a05873fSAnthony Koo 				pipe_ctx->stream->signal,
13651a05873fSAnthony Koo 				&audio_output.crtc_info,
13661a05873fSAnthony Koo 				&pipe_ctx->stream->audio_info);
13671a05873fSAnthony Koo 	}
13681a05873fSAnthony Koo 
13694562236bSHarry Wentland 	/*  */
1370d2d7885fSAnthony Koo 	/* Do not touch stream timing on seamless boot optimization. */
1371d2d7885fSAnthony Koo 	if (!pipe_ctx->stream->apply_seamless_boot_optimization)
13723158223eSEric Bernstein 		dc->hwss.enable_stream_timing(pipe_ctx, context, dc);
13734562236bSHarry Wentland 
1374d6001aedSYongqiang Sun 	if (dc->hwss.setup_vupdate_interrupt)
1375d6001aedSYongqiang Sun 		dc->hwss.setup_vupdate_interrupt(pipe_ctx);
1376a122b62dSAnthony Koo 
13779c0fb8d4SAnthony Koo 	params.vertical_total_min = stream->adjust.v_total_min;
13789c0fb8d4SAnthony Koo 	params.vertical_total_max = stream->adjust.v_total_max;
13799c0fb8d4SAnthony Koo 	if (pipe_ctx->stream_res.tg->funcs->set_drr)
13809c0fb8d4SAnthony Koo 		pipe_ctx->stream_res.tg->funcs->set_drr(
13819c0fb8d4SAnthony Koo 			pipe_ctx->stream_res.tg, &params);
13829c0fb8d4SAnthony Koo 
13839c0fb8d4SAnthony Koo 	// DRR should set trigger event to monitor surface update event
13849c0fb8d4SAnthony Koo 	if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
13859c0fb8d4SAnthony Koo 		event_triggers = 0x80;
13869c0fb8d4SAnthony Koo 	if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
13879c0fb8d4SAnthony Koo 		pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
13889c0fb8d4SAnthony Koo 				pipe_ctx->stream_res.tg, event_triggers);
13899c0fb8d4SAnthony Koo 
1390248cbed6SEric Bernstein 	if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
1391d2c460e7Shersen wu 		pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
1392d2c460e7Shersen wu 			pipe_ctx->stream_res.stream_enc,
1393d2c460e7Shersen wu 			pipe_ctx->stream_res.tg->inst);
1394aa9c4abeSNikola Cornij 
1395f0c4d997SCorbin McElhanney 	pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
1396f0c4d997SCorbin McElhanney 			pipe_ctx->stream_res.opp,
1397f0c4d997SCorbin McElhanney 			COLOR_SPACE_YCBCR601,
1398f0c4d997SCorbin McElhanney 			stream->timing.display_color_depth,
1399661a8cd9SDmytro Laktyushkin 			stream->signal);
14004562236bSHarry Wentland 
1401a6a6cb34SHarry Wentland 	pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
1402a6a6cb34SHarry Wentland 		pipe_ctx->stream_res.opp,
1403181a888fSCharlene Liu 		&stream->bit_depth_params,
1404181a888fSCharlene Liu 		&stream->clamping);
1405603767f9STony Cheng 
14061e7e86c4SSamson Tam 	if (!stream->dpms_off)
1407ab8db3e1SAndrey Grodzovsky 		core_link_enable_stream(context, pipe_ctx);
14084562236bSHarry Wentland 
14096702a9acSHarry Wentland 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
14104562236bSHarry Wentland 
1411ceb3dbb4SJun Lei 	pipe_ctx->stream->link->psr_enabled = false;
141294267b3dSSylvia Tsai 
14134562236bSHarry Wentland 	return DC_OK;
14144562236bSHarry Wentland }
14154562236bSHarry Wentland 
14164562236bSHarry Wentland /******************************************************************************/
14174562236bSHarry Wentland 
1418fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc)
14194562236bSHarry Wentland {
14204562236bSHarry Wentland 	int i;
1421a0c38ebaSCharlene Liu 	enum connector_id connector_id;
142268d77dd8SAndrew Jiang 	enum signal_type signal = SIGNAL_TYPE_NONE;
1423b9b171ffSHersen Wu 
1424b9b171ffSHersen Wu 	/* do not know BIOS back-front mapping, simply blank all. It will not
1425b9b171ffSHersen Wu 	 * hurt for non-DP
1426b9b171ffSHersen Wu 	 */
1427b9b171ffSHersen Wu 	for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
1428b9b171ffSHersen Wu 		dc->res_pool->stream_enc[i]->funcs->dp_blank(
1429b9b171ffSHersen Wu 					dc->res_pool->stream_enc[i]);
1430b9b171ffSHersen Wu 	}
1431b9b171ffSHersen Wu 
14324562236bSHarry Wentland 	for (i = 0; i < dc->link_count; i++) {
1433a0c38ebaSCharlene Liu 		connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
1434a0c38ebaSCharlene Liu 		if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
1435a0c38ebaSCharlene Liu 			(connector_id == CONNECTOR_ID_EDP)) {
1436a0c38ebaSCharlene Liu 
1437a0c38ebaSCharlene Liu 			if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
1438a0c38ebaSCharlene Liu 				dp_receiver_power_ctrl(dc->links[i], false);
1439904623eeSYongqiang Sun 			if (connector_id == CONNECTOR_ID_EDP)
144068d77dd8SAndrew Jiang 				signal = SIGNAL_TYPE_EDP;
1441a0c38ebaSCharlene Liu 		}
1442a0c38ebaSCharlene Liu 
14434562236bSHarry Wentland 		dc->links[i]->link_enc->funcs->disable_output(
1444069d418fSAndrew Jiang 				dc->links[i]->link_enc, signal);
14454562236bSHarry Wentland 	}
14464562236bSHarry Wentland }
14474562236bSHarry Wentland 
1448fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc)
14494562236bSHarry Wentland {
14504562236bSHarry Wentland 	int i;
14514562236bSHarry Wentland 
14527f93c1deSCharlene Liu 	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
14534562236bSHarry Wentland 		dc->res_pool->timing_generators[i]->funcs->disable_crtc(
14544562236bSHarry Wentland 				dc->res_pool->timing_generators[i]);
14554562236bSHarry Wentland 	}
14564562236bSHarry Wentland }
14574562236bSHarry Wentland 
1458fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc)
14594562236bSHarry Wentland {
14604562236bSHarry Wentland 	int i;
14614562236bSHarry Wentland 
14624562236bSHarry Wentland 	if (dc->res_pool->dp_clock_source->funcs->cs_power_down(
14634562236bSHarry Wentland 		dc->res_pool->dp_clock_source) == false)
14644562236bSHarry Wentland 		dm_error("Failed to power down pll! (dp clk src)\n");
14654562236bSHarry Wentland 
14664562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->clk_src_count; i++) {
14674562236bSHarry Wentland 		if (dc->res_pool->clock_sources[i]->funcs->cs_power_down(
14684562236bSHarry Wentland 				dc->res_pool->clock_sources[i]) == false)
14694562236bSHarry Wentland 			dm_error("Failed to power down pll! (clk src index=%d)\n", i);
14704562236bSHarry Wentland 	}
14714562236bSHarry Wentland }
14724562236bSHarry Wentland 
1473fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc)
14744562236bSHarry Wentland {
14754562236bSHarry Wentland 	power_down_encoders(dc);
14764562236bSHarry Wentland 
14774562236bSHarry Wentland 	power_down_controllers(dc);
14784562236bSHarry Wentland 
14794562236bSHarry Wentland 	power_down_clock_sources(dc);
14801663ae1cSBhawanpreet Lakha 
14812f3bfb27SRoman Li 	if (dc->fbc_compressor)
14821663ae1cSBhawanpreet Lakha 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
14834562236bSHarry Wentland }
14844562236bSHarry Wentland 
14854562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers(
1486fb3466a4SBhawanpreet Lakha 		struct dc *dc)
14874562236bSHarry Wentland {
14884562236bSHarry Wentland 	int i;
14894562236bSHarry Wentland 	struct timing_generator *tg;
14904562236bSHarry Wentland 	struct dc_context *ctx = dc->ctx;
14914562236bSHarry Wentland 
14927f93c1deSCharlene Liu 	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
14934562236bSHarry Wentland 		tg = dc->res_pool->timing_generators[i];
14944562236bSHarry Wentland 
14950a87425aSTony Cheng 		if (tg->funcs->disable_vga)
14964562236bSHarry Wentland 			tg->funcs->disable_vga(tg);
14977f93c1deSCharlene Liu 	}
14987f93c1deSCharlene Liu 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
14994562236bSHarry Wentland 		/* Enable CLOCK gating for each pipe BEFORE controller
15004562236bSHarry Wentland 		 * powergating. */
15014562236bSHarry Wentland 		enable_display_pipe_clock_gating(ctx,
15024562236bSHarry Wentland 				true);
15034562236bSHarry Wentland 
1504e6c258cbSYongqiang Sun 		dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i;
15057f914a62SYongqiang Sun 		dc->hwss.disable_plane(dc,
1506e6c258cbSYongqiang Sun 			&dc->current_state->res_ctx.pipe_ctx[i]);
15074562236bSHarry Wentland 	}
15084562236bSHarry Wentland }
15094562236bSHarry Wentland 
15103de5aa81SSivapiriyanKumarasamy 
15113de5aa81SSivapiriyanKumarasamy static struct dc_stream_state *get_edp_stream(struct dc_state *context)
15123de5aa81SSivapiriyanKumarasamy {
15133de5aa81SSivapiriyanKumarasamy 	int i;
15143de5aa81SSivapiriyanKumarasamy 
15153de5aa81SSivapiriyanKumarasamy 	for (i = 0; i < context->stream_count; i++) {
15163de5aa81SSivapiriyanKumarasamy 		if (context->streams[i]->signal == SIGNAL_TYPE_EDP)
15173de5aa81SSivapiriyanKumarasamy 			return context->streams[i];
15183de5aa81SSivapiriyanKumarasamy 	}
15193de5aa81SSivapiriyanKumarasamy 	return NULL;
15203de5aa81SSivapiriyanKumarasamy }
15213de5aa81SSivapiriyanKumarasamy 
1522be4b289fSSivapiriyanKumarasamy static struct dc_link *get_edp_link(struct dc *dc)
1523339cc82aSYongqiang Sun {
1524339cc82aSYongqiang Sun 	int i;
1525339cc82aSYongqiang Sun 
1526be4b289fSSivapiriyanKumarasamy 	// report any eDP links, even unconnected DDI's
1527f0c0761bSYongqiang Sun 	for (i = 0; i < dc->link_count; i++) {
1528f0c0761bSYongqiang Sun 		if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP)
1529f0c0761bSYongqiang Sun 			return dc->links[i];
1530339cc82aSYongqiang Sun 	}
1531f0c0761bSYongqiang Sun 	return NULL;
1532339cc82aSYongqiang Sun }
1533339cc82aSYongqiang Sun 
1534be4b289fSSivapiriyanKumarasamy static struct dc_link *get_edp_link_with_sink(
153525292028SYongqiang Sun 		struct dc *dc,
153625292028SYongqiang Sun 		struct dc_state *context)
153725292028SYongqiang Sun {
153825292028SYongqiang Sun 	int i;
153925292028SYongqiang Sun 	struct dc_link *link = NULL;
154025292028SYongqiang Sun 
154125292028SYongqiang Sun 	/* check if there is an eDP panel not in use */
154225292028SYongqiang Sun 	for (i = 0; i < dc->link_count; i++) {
154325292028SYongqiang Sun 		if (dc->links[i]->local_sink &&
154425292028SYongqiang Sun 			dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
154525292028SYongqiang Sun 			link = dc->links[i];
154625292028SYongqiang Sun 			break;
154725292028SYongqiang Sun 		}
154825292028SYongqiang Sun 	}
154925292028SYongqiang Sun 
155025292028SYongqiang Sun 	return link;
155125292028SYongqiang Sun }
155225292028SYongqiang Sun 
15534562236bSHarry Wentland /**
15544562236bSHarry Wentland  * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
15554562236bSHarry Wentland  *  1. Power down all DC HW blocks
15564562236bSHarry Wentland  *  2. Disable VGA engine on all controllers
15574562236bSHarry Wentland  *  3. Enable power gating for controller
15584562236bSHarry Wentland  *  4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
15594562236bSHarry Wentland  */
156025292028SYongqiang Sun void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
15614562236bSHarry Wentland {
1562d82f9942SAnthony Koo 	int i;
1563be4b289fSSivapiriyanKumarasamy 	struct dc_link *edp_link_with_sink = get_edp_link_with_sink(dc, context);
1564be4b289fSSivapiriyanKumarasamy 	struct dc_link *edp_link = get_edp_link(dc);
15653de5aa81SSivapiriyanKumarasamy 	struct dc_stream_state *edp_stream = NULL;
1566be4b289fSSivapiriyanKumarasamy 	bool can_apply_edp_fast_boot = false;
1567ce72741bSAnthony Koo 	bool can_apply_seamless_boot = false;
15683de5aa81SSivapiriyanKumarasamy 	bool keep_edp_vdd_on = false;
1569ce72741bSAnthony Koo 
1570be4b289fSSivapiriyanKumarasamy 	if (dc->hwss.init_pipes)
1571be4b289fSSivapiriyanKumarasamy 		dc->hwss.init_pipes(dc, context);
1572be4b289fSSivapiriyanKumarasamy 
15733de5aa81SSivapiriyanKumarasamy 	edp_stream = get_edp_stream(context);
15743de5aa81SSivapiriyanKumarasamy 
1575be4b289fSSivapiriyanKumarasamy 	// Check fastboot support, disable on DCE8 because of blank screens
1576be4b289fSSivapiriyanKumarasamy 	if (edp_link && dc->ctx->dce_version != DCE_VERSION_8_0 &&
1577be4b289fSSivapiriyanKumarasamy 		    dc->ctx->dce_version != DCE_VERSION_8_1 &&
1578be4b289fSSivapiriyanKumarasamy 		    dc->ctx->dce_version != DCE_VERSION_8_3) {
1579be4b289fSSivapiriyanKumarasamy 
1580be4b289fSSivapiriyanKumarasamy 		// enable fastboot if backend is enabled on eDP
1581be4b289fSSivapiriyanKumarasamy 		if (edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc)) {
15823de5aa81SSivapiriyanKumarasamy 			/* Set optimization flag on eDP stream*/
15833de5aa81SSivapiriyanKumarasamy 			if (edp_stream) {
15843de5aa81SSivapiriyanKumarasamy 				edp_stream->apply_edp_fast_boot_optimization = true;
1585be4b289fSSivapiriyanKumarasamy 				can_apply_edp_fast_boot = true;
1586be4b289fSSivapiriyanKumarasamy 			}
1587be4b289fSSivapiriyanKumarasamy 		}
15883de5aa81SSivapiriyanKumarasamy 
15893de5aa81SSivapiriyanKumarasamy 		// We are trying to enable eDP, don't power down VDD
15903de5aa81SSivapiriyanKumarasamy 		if (edp_stream)
15913de5aa81SSivapiriyanKumarasamy 			keep_edp_vdd_on = true;
1592be4b289fSSivapiriyanKumarasamy 	}
1593be4b289fSSivapiriyanKumarasamy 
1594be4b289fSSivapiriyanKumarasamy 	// Check seamless boot support
1595ce72741bSAnthony Koo 	for (i = 0; i < context->stream_count; i++) {
1596ce72741bSAnthony Koo 		if (context->streams[i]->apply_seamless_boot_optimization) {
1597ce72741bSAnthony Koo 			can_apply_seamless_boot = true;
1598ce72741bSAnthony Koo 			break;
1599ce72741bSAnthony Koo 		}
1600ce72741bSAnthony Koo 	}
16014cac1e6dSYongqiang Sun 
1602be4b289fSSivapiriyanKumarasamy 	/* eDP should not have stream in resume from S4 and so even with VBios post
1603be4b289fSSivapiriyanKumarasamy 	 * it should get turned off
16042c37e49aSYongqiang Sun 	 */
1605be4b289fSSivapiriyanKumarasamy 	if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) {
16063de5aa81SSivapiriyanKumarasamy 		if (edp_link_with_sink && !keep_edp_vdd_on) {
16074cac1e6dSYongqiang Sun 			/*turn off backlight before DP_blank and encoder powered down*/
1608be4b289fSSivapiriyanKumarasamy 			dc->hwss.edp_backlight_control(edp_link_with_sink, false);
1609c5fc7f59SCharlene Liu 		}
1610c5fc7f59SCharlene Liu 		/*resume from S3, no vbios posting, no need to power down again*/
161125292028SYongqiang Sun 		power_down_all_hw_blocks(dc);
16124562236bSHarry Wentland 		disable_vga_and_power_gate_all_controllers(dc);
16133de5aa81SSivapiriyanKumarasamy 		if (edp_link_with_sink && !keep_edp_vdd_on)
1614be4b289fSSivapiriyanKumarasamy 			dc->hwss.edp_power_control(edp_link_with_sink, false);
1615c5fc7f59SCharlene Liu 	}
16164562236bSHarry Wentland 	bios_set_scratch_acc_mode_change(dc->ctx->dc_bios);
16174562236bSHarry Wentland }
16184562236bSHarry Wentland 
16194562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration(
16204562236bSHarry Wentland 	struct bw_fixed blackout_duration,
16210971c40eSHarry Wentland 	const struct dc_stream_state *stream)
16224562236bSHarry Wentland {
16234562236bSHarry Wentland 	uint32_t total_dest_line_time_ns;
16244562236bSHarry Wentland 	uint32_t pstate_blackout_duration_ns;
16254562236bSHarry Wentland 
16264562236bSHarry Wentland 	pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
16274562236bSHarry Wentland 
16284562236bSHarry Wentland 	total_dest_line_time_ns = 1000000UL *
1629380604e2SKen Chalmers 		(stream->timing.h_total * 10) /
1630380604e2SKen Chalmers 		stream->timing.pix_clk_100hz +
16314562236bSHarry Wentland 		pstate_blackout_duration_ns;
16324562236bSHarry Wentland 
16334562236bSHarry Wentland 	return total_dest_line_time_ns;
16344562236bSHarry Wentland }
16354562236bSHarry Wentland 
1636f774b339SEric Yang static void dce110_set_displaymarks(
1637fb3466a4SBhawanpreet Lakha 	const struct dc *dc,
1638608ac7bbSJerry Zuo 	struct dc_state *context)
16394562236bSHarry Wentland {
16404562236bSHarry Wentland 	uint8_t i, num_pipes;
16414562236bSHarry Wentland 	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
16424562236bSHarry Wentland 
16434562236bSHarry Wentland 	for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) {
16444562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
16454562236bSHarry Wentland 		uint32_t total_dest_line_time_ns;
16464562236bSHarry Wentland 
16474562236bSHarry Wentland 		if (pipe_ctx->stream == NULL)
16484562236bSHarry Wentland 			continue;
16494562236bSHarry Wentland 
16504562236bSHarry Wentland 		total_dest_line_time_ns = compute_pstate_blackout_duration(
165177a4ea53SBhawanpreet Lakha 			dc->bw_vbios->blackout_duration, pipe_ctx->stream);
165286a66c4eSHarry Wentland 		pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
165386a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi,
1654813d20dcSAidan Wood 			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1655813d20dcSAidan Wood 			context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1656813d20dcSAidan Wood 			context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes],
1657813d20dcSAidan Wood 			context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
16584562236bSHarry Wentland 			total_dest_line_time_ns);
16594562236bSHarry Wentland 		if (i == underlay_idx) {
16604562236bSHarry Wentland 			num_pipes++;
166186a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
166286a66c4eSHarry Wentland 				pipe_ctx->plane_res.mi,
1663813d20dcSAidan Wood 				context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1664813d20dcSAidan Wood 				context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1665813d20dcSAidan Wood 				context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
16664562236bSHarry Wentland 				total_dest_line_time_ns);
16674562236bSHarry Wentland 		}
16684562236bSHarry Wentland 		num_pipes++;
16694562236bSHarry Wentland 	}
16704562236bSHarry Wentland }
16714562236bSHarry Wentland 
1672fab55d61SDmytro Laktyushkin void dce110_set_safe_displaymarks(
1673a2b8659dSTony Cheng 		struct resource_context *res_ctx,
1674a2b8659dSTony Cheng 		const struct resource_pool *pool)
16754562236bSHarry Wentland {
16764562236bSHarry Wentland 	int i;
1677a2b8659dSTony Cheng 	int underlay_idx = pool->underlay_pipe_index;
16789037d802SDmytro Laktyushkin 	struct dce_watermarks max_marks = {
16794562236bSHarry Wentland 		MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK };
16809037d802SDmytro Laktyushkin 	struct dce_watermarks nbp_marks = {
16814562236bSHarry Wentland 		SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
16823722c794SMikita Lipski 	struct dce_watermarks min_marks = { 0, 0, 0, 0};
16834562236bSHarry Wentland 
16844562236bSHarry Wentland 	for (i = 0; i < MAX_PIPES; i++) {
16858feabd03SYue Hin Lau 		if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
16864562236bSHarry Wentland 			continue;
16874562236bSHarry Wentland 
168886a66c4eSHarry Wentland 		res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
168986a66c4eSHarry Wentland 				res_ctx->pipe_ctx[i].plane_res.mi,
16904562236bSHarry Wentland 				nbp_marks,
16914562236bSHarry Wentland 				max_marks,
16923722c794SMikita Lipski 				min_marks,
16934562236bSHarry Wentland 				max_marks,
16944562236bSHarry Wentland 				MAX_WATERMARK);
16958feabd03SYue Hin Lau 
16964562236bSHarry Wentland 		if (i == underlay_idx)
169786a66c4eSHarry Wentland 			res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
169886a66c4eSHarry Wentland 				res_ctx->pipe_ctx[i].plane_res.mi,
16994562236bSHarry Wentland 				nbp_marks,
17004562236bSHarry Wentland 				max_marks,
17014562236bSHarry Wentland 				max_marks,
17024562236bSHarry Wentland 				MAX_WATERMARK);
17038feabd03SYue Hin Lau 
17044562236bSHarry Wentland 	}
17054562236bSHarry Wentland }
17064562236bSHarry Wentland 
17074562236bSHarry Wentland /*******************************************************************************
17084562236bSHarry Wentland  * Public functions
17094562236bSHarry Wentland  ******************************************************************************/
17104562236bSHarry Wentland 
17114562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx,
17124562236bSHarry Wentland 		int num_pipes, int vmin, int vmax)
17134562236bSHarry Wentland {
17144562236bSHarry Wentland 	int i = 0;
17154562236bSHarry Wentland 	struct drr_params params = {0};
171698e6436dSAnthony Koo 	// DRR should set trigger event to monitor surface update event
171798e6436dSAnthony Koo 	unsigned int event_triggers = 0x80;
17184562236bSHarry Wentland 
17194562236bSHarry Wentland 	params.vertical_total_max = vmax;
17204562236bSHarry Wentland 	params.vertical_total_min = vmin;
17214562236bSHarry Wentland 
17224562236bSHarry Wentland 	/* TODO: If multiple pipes are to be supported, you need
172398e6436dSAnthony Koo 	 * some GSL stuff. Static screen triggers may be programmed differently
172498e6436dSAnthony Koo 	 * as well.
17254562236bSHarry Wentland 	 */
17264562236bSHarry Wentland 	for (i = 0; i < num_pipes; i++) {
172798e6436dSAnthony Koo 		pipe_ctx[i]->stream_res.tg->funcs->set_drr(
172898e6436dSAnthony Koo 			pipe_ctx[i]->stream_res.tg, &params);
172998e6436dSAnthony Koo 
173098e6436dSAnthony Koo 		if (vmax != 0 && vmin != 0)
173198e6436dSAnthony Koo 			pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
173298e6436dSAnthony Koo 					pipe_ctx[i]->stream_res.tg,
173398e6436dSAnthony Koo 					event_triggers);
17344562236bSHarry Wentland 	}
17354562236bSHarry Wentland }
17364562236bSHarry Wentland 
173772ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx,
173872ada5f7SEric Cook 		int num_pipes,
173972ada5f7SEric Cook 		struct crtc_position *position)
174072ada5f7SEric Cook {
174172ada5f7SEric Cook 	int i = 0;
174272ada5f7SEric Cook 
174372ada5f7SEric Cook 	/* TODO: handle pipes > 1
174472ada5f7SEric Cook 	 */
174572ada5f7SEric Cook 	for (i = 0; i < num_pipes; i++)
17466b670fa9SHarry Wentland 		pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
174772ada5f7SEric Cook }
174872ada5f7SEric Cook 
17494562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
175094267b3dSSylvia Tsai 		int num_pipes, const struct dc_static_screen_events *events)
17514562236bSHarry Wentland {
17524562236bSHarry Wentland 	unsigned int i;
175394267b3dSSylvia Tsai 	unsigned int value = 0;
175494267b3dSSylvia Tsai 
175594267b3dSSylvia Tsai 	if (events->overlay_update)
175694267b3dSSylvia Tsai 		value |= 0x100;
175794267b3dSSylvia Tsai 	if (events->surface_update)
175894267b3dSSylvia Tsai 		value |= 0x80;
175994267b3dSSylvia Tsai 	if (events->cursor_update)
176094267b3dSSylvia Tsai 		value |= 0x2;
1761ed8462acSCharlene Liu 	if (events->force_trigger)
1762ed8462acSCharlene Liu 		value |= 0x1;
17634562236bSHarry Wentland 
1764593f79a2SAlex Deucher 	if (num_pipes) {
1765593f79a2SAlex Deucher 		struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
1766593f79a2SAlex Deucher 
1767593f79a2SAlex Deucher 		if (dc->fbc_compressor)
1768c3aa1d67SBhawanpreet Lakha 			value |= 0x84;
1769593f79a2SAlex Deucher 	}
1770c3aa1d67SBhawanpreet Lakha 
17714562236bSHarry Wentland 	for (i = 0; i < num_pipes; i++)
17726b670fa9SHarry Wentland 		pipe_ctx[i]->stream_res.tg->funcs->
17736b670fa9SHarry Wentland 			set_static_screen_control(pipe_ctx[i]->stream_res.tg, value);
17744562236bSHarry Wentland }
17754562236bSHarry Wentland 
1776f6baff4dSHarry Wentland /*
1777690b5e39SRoman Li  *  Check if FBC can be enabled
1778690b5e39SRoman Li  */
17799c6569deSHarry Wentland static bool should_enable_fbc(struct dc *dc,
17803bc4aaa9SRoman Li 		struct dc_state *context,
17813bc4aaa9SRoman Li 		uint32_t *pipe_idx)
1782690b5e39SRoman Li {
17833bc4aaa9SRoman Li 	uint32_t i;
17843bc4aaa9SRoman Li 	struct pipe_ctx *pipe_ctx = NULL;
17853bc4aaa9SRoman Li 	struct resource_context *res_ctx = &context->res_ctx;
178665d38262Shersen wu 	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
17873bc4aaa9SRoman Li 
1788690b5e39SRoman Li 
1789690b5e39SRoman Li 	ASSERT(dc->fbc_compressor);
1790690b5e39SRoman Li 
1791690b5e39SRoman Li 	/* FBC memory should be allocated */
1792690b5e39SRoman Li 	if (!dc->ctx->fbc_gpu_addr)
17939c6569deSHarry Wentland 		return false;
1794690b5e39SRoman Li 
1795690b5e39SRoman Li 	/* Only supports single display */
1796690b5e39SRoman Li 	if (context->stream_count != 1)
17979c6569deSHarry Wentland 		return false;
1798690b5e39SRoman Li 
17993bc4aaa9SRoman Li 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
18003bc4aaa9SRoman Li 		if (res_ctx->pipe_ctx[i].stream) {
180165d38262Shersen wu 
18023bc4aaa9SRoman Li 			pipe_ctx = &res_ctx->pipe_ctx[i];
180365d38262Shersen wu 
180465d38262Shersen wu 			if (!pipe_ctx)
180565d38262Shersen wu 				continue;
180665d38262Shersen wu 
180765d38262Shersen wu 			/* fbc not applicable on underlay pipe */
180865d38262Shersen wu 			if (pipe_ctx->pipe_idx != underlay_idx) {
18093bc4aaa9SRoman Li 				*pipe_idx = i;
18103bc4aaa9SRoman Li 				break;
18113bc4aaa9SRoman Li 			}
18123bc4aaa9SRoman Li 		}
181365d38262Shersen wu 	}
18143bc4aaa9SRoman Li 
181565d38262Shersen wu 	if (i == dc->res_pool->pipe_count)
181665d38262Shersen wu 		return false;
181765d38262Shersen wu 
1818ceb3dbb4SJun Lei 	if (!pipe_ctx->stream->link)
181965d38262Shersen wu 		return false;
18207a840773SRoman Li 
1821690b5e39SRoman Li 	/* Only supports eDP */
1822ceb3dbb4SJun Lei 	if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
18239c6569deSHarry Wentland 		return false;
1824690b5e39SRoman Li 
1825690b5e39SRoman Li 	/* PSR should not be enabled */
1826ceb3dbb4SJun Lei 	if (pipe_ctx->stream->link->psr_enabled)
18279c6569deSHarry Wentland 		return false;
1828690b5e39SRoman Li 
182993984bbcSShirish S 	/* Nothing to compress */
183093984bbcSShirish S 	if (!pipe_ctx->plane_state)
18319c6569deSHarry Wentland 		return false;
183293984bbcSShirish S 
183305230fa9SRoman Li 	/* Only for non-linear tiling */
183405230fa9SRoman Li 	if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
18359c6569deSHarry Wentland 		return false;
183605230fa9SRoman Li 
18379c6569deSHarry Wentland 	return true;
1838690b5e39SRoman Li }
1839690b5e39SRoman Li 
1840690b5e39SRoman Li /*
1841690b5e39SRoman Li  *  Enable FBC
1842690b5e39SRoman Li  */
184365d38262Shersen wu static void enable_fbc(
184465d38262Shersen wu 		struct dc *dc,
1845608ac7bbSJerry Zuo 		struct dc_state *context)
1846690b5e39SRoman Li {
18473bc4aaa9SRoman Li 	uint32_t pipe_idx = 0;
18483bc4aaa9SRoman Li 
18493bc4aaa9SRoman Li 	if (should_enable_fbc(dc, context, &pipe_idx)) {
1850690b5e39SRoman Li 		/* Program GRPH COMPRESSED ADDRESS and PITCH */
1851690b5e39SRoman Li 		struct compr_addr_and_pitch_params params = {0, 0, 0};
1852690b5e39SRoman Li 		struct compressor *compr = dc->fbc_compressor;
18533bc4aaa9SRoman Li 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
18543bc4aaa9SRoman Li 
18559c6569deSHarry Wentland 		params.source_view_width = pipe_ctx->stream->timing.h_addressable;
18569c6569deSHarry Wentland 		params.source_view_height = pipe_ctx->stream->timing.v_addressable;
185765d38262Shersen wu 		params.inst = pipe_ctx->stream_res.tg->inst;
1858690b5e39SRoman Li 		compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
1859690b5e39SRoman Li 
1860690b5e39SRoman Li 		compr->funcs->surface_address_and_pitch(compr, &params);
1861690b5e39SRoman Li 		compr->funcs->set_fbc_invalidation_triggers(compr, 1);
1862690b5e39SRoman Li 
1863690b5e39SRoman Li 		compr->funcs->enable_fbc(compr, &params);
1864690b5e39SRoman Li 	}
1865690b5e39SRoman Li }
1866690b5e39SRoman Li 
186754e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap(
1868fb3466a4SBhawanpreet Lakha 		struct dc *dc,
1869608ac7bbSJerry Zuo 		struct dc_state *context)
18704562236bSHarry Wentland {
18714562236bSHarry Wentland 	int i;
18724562236bSHarry Wentland 
18734562236bSHarry Wentland 	/* Reset old context */
18744562236bSHarry Wentland 	/* look up the targets that have been removed since last commit */
1875a2b8659dSTony Cheng 	for (i = 0; i < MAX_PIPES; i++) {
18764562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx_old =
1877608ac7bbSJerry Zuo 			&dc->current_state->res_ctx.pipe_ctx[i];
18784562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
18794562236bSHarry Wentland 
18804562236bSHarry Wentland 		/* Note: We need to disable output if clock sources change,
18814562236bSHarry Wentland 		 * since bios does optimization and doesn't apply if changing
18824562236bSHarry Wentland 		 * PHY when not already disabled.
18834562236bSHarry Wentland 		 */
18844562236bSHarry Wentland 
18854562236bSHarry Wentland 		/* Skip underlay pipe since it will be handled in commit surface*/
18864562236bSHarry Wentland 		if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe)
18874562236bSHarry Wentland 			continue;
18884562236bSHarry Wentland 
18894562236bSHarry Wentland 		if (!pipe_ctx->stream ||
189054e8695eSDmytro Laktyushkin 				pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
189121e67d4dSHarry Wentland 			struct clock_source *old_clk = pipe_ctx_old->clock_source;
189221e67d4dSHarry Wentland 
1893827f11e9SLeo (Sunpeng) Li 			/* Disable if new stream is null. O/w, if stream is
1894827f11e9SLeo (Sunpeng) Li 			 * disabled already, no need to disable again.
1895827f11e9SLeo (Sunpeng) Li 			 */
1896827f11e9SLeo (Sunpeng) Li 			if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off)
18974176664bSCharlene Liu 				core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
1898d050f8edSHersen Wu 
18996b670fa9SHarry Wentland 			pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
19006b670fa9SHarry Wentland 			if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
190154e8695eSDmytro Laktyushkin 				dm_error("DC: failed to blank crtc!\n");
190254e8695eSDmytro Laktyushkin 				BREAK_TO_DEBUGGER();
190354e8695eSDmytro Laktyushkin 			}
19046b670fa9SHarry Wentland 			pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg);
190586a66c4eSHarry Wentland 			pipe_ctx_old->plane_res.mi->funcs->free_mem_input(
1906608ac7bbSJerry Zuo 					pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
190754e8695eSDmytro Laktyushkin 
1908ad8960a6SMikita Lipski 			if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx,
1909ad8960a6SMikita Lipski 										dc->res_pool,
1910ad8960a6SMikita Lipski 										old_clk))
191121e67d4dSHarry Wentland 				old_clk->funcs->cs_power_down(old_clk);
191221e67d4dSHarry Wentland 
19137f914a62SYongqiang Sun 			dc->hwss.disable_plane(dc, pipe_ctx_old);
191454e8695eSDmytro Laktyushkin 
191554e8695eSDmytro Laktyushkin 			pipe_ctx_old->stream = NULL;
191654e8695eSDmytro Laktyushkin 		}
19174562236bSHarry Wentland 	}
19184562236bSHarry Wentland }
19194562236bSHarry Wentland 
19201a05873fSAnthony Koo static void dce110_setup_audio_dto(
19211a05873fSAnthony Koo 		struct dc *dc,
19221a05873fSAnthony Koo 		struct dc_state *context)
19231a05873fSAnthony Koo {
19241a05873fSAnthony Koo 	int i;
19251a05873fSAnthony Koo 
19261a05873fSAnthony Koo 	/* program audio wall clock. use HDMI as clock source if HDMI
19271a05873fSAnthony Koo 	 * audio active. Otherwise, use DP as clock source
19281a05873fSAnthony Koo 	 * first, loop to find any HDMI audio, if not, loop find DP audio
19291a05873fSAnthony Koo 	 */
19301a05873fSAnthony Koo 	/* Setup audio rate clock source */
19311a05873fSAnthony Koo 	/* Issue:
19321a05873fSAnthony Koo 	* Audio lag happened on DP monitor when unplug a HDMI monitor
19331a05873fSAnthony Koo 	*
19341a05873fSAnthony Koo 	* Cause:
19351a05873fSAnthony Koo 	* In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL
19361a05873fSAnthony Koo 	* is set to either dto0 or dto1, audio should work fine.
19371a05873fSAnthony Koo 	* In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1,
19381a05873fSAnthony Koo 	* set to dto0 will cause audio lag.
19391a05873fSAnthony Koo 	*
19401a05873fSAnthony Koo 	* Solution:
19411a05873fSAnthony Koo 	* Not optimized audio wall dto setup. When mode set, iterate pipe_ctx,
19421a05873fSAnthony Koo 	* find first available pipe with audio, setup audio wall DTO per topology
19431a05873fSAnthony Koo 	* instead of per pipe.
19441a05873fSAnthony Koo 	*/
19451a05873fSAnthony Koo 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
19461a05873fSAnthony Koo 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
19471a05873fSAnthony Koo 
19481a05873fSAnthony Koo 		if (pipe_ctx->stream == NULL)
19491a05873fSAnthony Koo 			continue;
19501a05873fSAnthony Koo 
19511a05873fSAnthony Koo 		if (pipe_ctx->top_pipe)
19521a05873fSAnthony Koo 			continue;
19531a05873fSAnthony Koo 
19541a05873fSAnthony Koo 		if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
19551a05873fSAnthony Koo 			continue;
19561a05873fSAnthony Koo 
19571a05873fSAnthony Koo 		if (pipe_ctx->stream_res.audio != NULL) {
19581a05873fSAnthony Koo 			struct audio_output audio_output;
19591a05873fSAnthony Koo 
19601a05873fSAnthony Koo 			build_audio_output(context, pipe_ctx, &audio_output);
19611a05873fSAnthony Koo 
19621a05873fSAnthony Koo 			pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
19631a05873fSAnthony Koo 				pipe_ctx->stream_res.audio,
19641a05873fSAnthony Koo 				pipe_ctx->stream->signal,
19651a05873fSAnthony Koo 				&audio_output.crtc_info,
19661a05873fSAnthony Koo 				&audio_output.pll_info);
19671a05873fSAnthony Koo 			break;
19681a05873fSAnthony Koo 		}
19691a05873fSAnthony Koo 	}
19701a05873fSAnthony Koo 
19711a05873fSAnthony Koo 	/* no HDMI audio is found, try DP audio */
19721a05873fSAnthony Koo 	if (i == dc->res_pool->pipe_count) {
19731a05873fSAnthony Koo 		for (i = 0; i < dc->res_pool->pipe_count; i++) {
19741a05873fSAnthony Koo 			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
19751a05873fSAnthony Koo 
19761a05873fSAnthony Koo 			if (pipe_ctx->stream == NULL)
19771a05873fSAnthony Koo 				continue;
19781a05873fSAnthony Koo 
19791a05873fSAnthony Koo 			if (pipe_ctx->top_pipe)
19801a05873fSAnthony Koo 				continue;
19811a05873fSAnthony Koo 
19821a05873fSAnthony Koo 			if (!dc_is_dp_signal(pipe_ctx->stream->signal))
19831a05873fSAnthony Koo 				continue;
19841a05873fSAnthony Koo 
19851a05873fSAnthony Koo 			if (pipe_ctx->stream_res.audio != NULL) {
19861a05873fSAnthony Koo 				struct audio_output audio_output;
19871a05873fSAnthony Koo 
19881a05873fSAnthony Koo 				build_audio_output(context, pipe_ctx, &audio_output);
19891a05873fSAnthony Koo 
19901a05873fSAnthony Koo 				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
19911a05873fSAnthony Koo 					pipe_ctx->stream_res.audio,
19921a05873fSAnthony Koo 					pipe_ctx->stream->signal,
19931a05873fSAnthony Koo 					&audio_output.crtc_info,
19941a05873fSAnthony Koo 					&audio_output.pll_info);
19951a05873fSAnthony Koo 				break;
19961a05873fSAnthony Koo 			}
19971a05873fSAnthony Koo 		}
19981a05873fSAnthony Koo 	}
19991a05873fSAnthony Koo }
2000cf437593SDmytro Laktyushkin 
20014562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw(
2002fb3466a4SBhawanpreet Lakha 		struct dc *dc,
2003608ac7bbSJerry Zuo 		struct dc_state *context)
20044562236bSHarry Wentland {
20054562236bSHarry Wentland 	struct dc_bios *dcb = dc->ctx->dc_bios;
20064562236bSHarry Wentland 	enum dc_status status;
20074562236bSHarry Wentland 	int i;
20084562236bSHarry Wentland 
20094562236bSHarry Wentland 	/* Reset old context */
20104562236bSHarry Wentland 	/* look up the targets that have been removed since last commit */
20114562236bSHarry Wentland 	dc->hwss.reset_hw_ctx_wrap(dc, context);
20124562236bSHarry Wentland 
20134562236bSHarry Wentland 	/* Skip applying if no targets */
2014ab2541b6SAric Cyr 	if (context->stream_count <= 0)
20154562236bSHarry Wentland 		return DC_OK;
20164562236bSHarry Wentland 
20174562236bSHarry Wentland 	/* Apply new context */
20184562236bSHarry Wentland 	dcb->funcs->set_scratch_critical_state(dcb, true);
20194562236bSHarry Wentland 
20204562236bSHarry Wentland 	/* below is for real asic only */
2021a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
20224562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx_old =
2023608ac7bbSJerry Zuo 					&dc->current_state->res_ctx.pipe_ctx[i];
20244562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
20254562236bSHarry Wentland 
20264562236bSHarry Wentland 		if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe)
20274562236bSHarry Wentland 			continue;
20284562236bSHarry Wentland 
20294562236bSHarry Wentland 		if (pipe_ctx->stream == pipe_ctx_old->stream) {
20304562236bSHarry Wentland 			if (pipe_ctx_old->clock_source != pipe_ctx->clock_source)
20314562236bSHarry Wentland 				dce_crtc_switch_to_clk_src(dc->hwseq,
20324562236bSHarry Wentland 						pipe_ctx->clock_source, i);
20334562236bSHarry Wentland 			continue;
20344562236bSHarry Wentland 		}
20354562236bSHarry Wentland 
20364562236bSHarry Wentland 		dc->hwss.enable_display_power_gating(
20374562236bSHarry Wentland 				dc, i, dc->ctx->dc_bios,
20384562236bSHarry Wentland 				PIPE_GATING_CONTROL_DISABLE);
20394562236bSHarry Wentland 	}
20404562236bSHarry Wentland 
20412f3bfb27SRoman Li 	if (dc->fbc_compressor)
20421663ae1cSBhawanpreet Lakha 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
20435099114bSAlex Deucher 
20441a05873fSAnthony Koo 	dce110_setup_audio_dto(dc, context);
2045ab8812a3SHersen Wu 
2046a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
2047ab8812a3SHersen Wu 		struct pipe_ctx *pipe_ctx_old =
2048608ac7bbSJerry Zuo 					&dc->current_state->res_ctx.pipe_ctx[i];
2049ab8812a3SHersen Wu 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2050ab8812a3SHersen Wu 
2051ab8812a3SHersen Wu 		if (pipe_ctx->stream == NULL)
2052ab8812a3SHersen Wu 			continue;
2053ab8812a3SHersen Wu 
2054eed928dcSCharlene Liu 		if (pipe_ctx->stream == pipe_ctx_old->stream &&
2055eed928dcSCharlene Liu 			pipe_ctx->stream->link->link_state_valid) {
2056ab8812a3SHersen Wu 			continue;
2057eed928dcSCharlene Liu 		}
2058ab8812a3SHersen Wu 
20595b92d9d4SHarry Wentland 		if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
2060313bf4ffSYongqiang Sun 			continue;
2061313bf4ffSYongqiang Sun 
2062ab8812a3SHersen Wu 		if (pipe_ctx->top_pipe)
2063ab8812a3SHersen Wu 			continue;
2064ab8812a3SHersen Wu 
20654562236bSHarry Wentland 		status = apply_single_controller_ctx_to_hw(
20664562236bSHarry Wentland 				pipe_ctx,
20674562236bSHarry Wentland 				context,
20684562236bSHarry Wentland 				dc);
20694562236bSHarry Wentland 
20704562236bSHarry Wentland 		if (DC_OK != status)
20714562236bSHarry Wentland 			return status;
20724562236bSHarry Wentland 	}
20734562236bSHarry Wentland 
2074690b5e39SRoman Li 	if (dc->fbc_compressor)
207565d38262Shersen wu 		enable_fbc(dc, dc->current_state);
207665d38262Shersen wu 
207765d38262Shersen wu 	dcb->funcs->set_scratch_critical_state(dcb, false);
2078690b5e39SRoman Li 
20794562236bSHarry Wentland 	return DC_OK;
20804562236bSHarry Wentland }
20814562236bSHarry Wentland 
20824562236bSHarry Wentland /*******************************************************************************
20834562236bSHarry Wentland  * Front End programming
20844562236bSHarry Wentland  ******************************************************************************/
20854562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx)
20864562236bSHarry Wentland {
20874562236bSHarry Wentland 	struct default_adjustment default_adjust = { 0 };
20884562236bSHarry Wentland 
20894562236bSHarry Wentland 	default_adjust.force_hw_default = false;
209034996173SHarry Wentland 	default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
209134996173SHarry Wentland 	default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
20924562236bSHarry Wentland 	default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
20936702a9acSHarry Wentland 	default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
20944562236bSHarry Wentland 
20954562236bSHarry Wentland 	/* display color depth */
20964562236bSHarry Wentland 	default_adjust.color_depth =
20974fa086b9SLeo (Sunpeng) Li 		pipe_ctx->stream->timing.display_color_depth;
20984562236bSHarry Wentland 
20994562236bSHarry Wentland 	/* Lb color depth */
21006702a9acSHarry Wentland 	default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
21014562236bSHarry Wentland 
210286a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
210386a66c4eSHarry Wentland 					pipe_ctx->plane_res.xfm, &default_adjust);
21044562236bSHarry Wentland }
21054562236bSHarry Wentland 
2106b06b7680SLeon Elazar 
2107b06b7680SLeon Elazar /*******************************************************************************
2108b06b7680SLeon Elazar  * In order to turn on/off specific surface we will program
2109b06b7680SLeon Elazar  * Blender + CRTC
2110b06b7680SLeon Elazar  *
2111b06b7680SLeon Elazar  * In case that we have two surfaces and they have a different visibility
2112b06b7680SLeon Elazar  * we can't turn off the CRTC since it will turn off the entire display
2113b06b7680SLeon Elazar  *
2114b06b7680SLeon Elazar  * |----------------------------------------------- |
2115b06b7680SLeon Elazar  * |bottom pipe|curr pipe  |              |         |
2116b06b7680SLeon Elazar  * |Surface    |Surface    | Blender      |  CRCT   |
2117b06b7680SLeon Elazar  * |visibility |visibility | Configuration|         |
2118b06b7680SLeon Elazar  * |------------------------------------------------|
2119b06b7680SLeon Elazar  * |   off     |    off    | CURRENT_PIPE | blank   |
2120b06b7680SLeon Elazar  * |   off     |    on     | CURRENT_PIPE | unblank |
2121b06b7680SLeon Elazar  * |   on      |    off    | OTHER_PIPE   | unblank |
2122b06b7680SLeon Elazar  * |   on      |    on     | BLENDING     | unblank |
2123b06b7680SLeon Elazar  * -------------------------------------------------|
2124b06b7680SLeon Elazar  *
2125b06b7680SLeon Elazar  ******************************************************************************/
2126fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc,
21274562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx)
21284562236bSHarry Wentland {
21294562236bSHarry Wentland 	enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE;
2130b06b7680SLeon Elazar 	bool blank_target = false;
21314562236bSHarry Wentland 
21324562236bSHarry Wentland 	if (pipe_ctx->bottom_pipe) {
2133b06b7680SLeon Elazar 
2134b06b7680SLeon Elazar 		/* For now we are supporting only two pipes */
2135b06b7680SLeon Elazar 		ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL);
2136b06b7680SLeon Elazar 
21373be5262eSHarry Wentland 		if (pipe_ctx->bottom_pipe->plane_state->visible) {
21383be5262eSHarry Wentland 			if (pipe_ctx->plane_state->visible)
21394562236bSHarry Wentland 				blender_mode = BLND_MODE_BLENDING;
21404562236bSHarry Wentland 			else
21414562236bSHarry Wentland 				blender_mode = BLND_MODE_OTHER_PIPE;
2142b06b7680SLeon Elazar 
21433be5262eSHarry Wentland 		} else if (!pipe_ctx->plane_state->visible)
2144b06b7680SLeon Elazar 			blank_target = true;
2145b06b7680SLeon Elazar 
21463be5262eSHarry Wentland 	} else if (!pipe_ctx->plane_state->visible)
2147b06b7680SLeon Elazar 		blank_target = true;
2148b06b7680SLeon Elazar 
2149e07f541fSYongqiang Sun 	dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
21506b670fa9SHarry Wentland 	pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
2151b06b7680SLeon Elazar 
21524562236bSHarry Wentland }
21534562236bSHarry Wentland 
21541bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
21551bf56e62SZeyu Fan {
2156146a9f63SKrunoslav Kovac 	int i = 0;
21571bf56e62SZeyu Fan 	struct xfm_grph_csc_adjustment adjust;
21581bf56e62SZeyu Fan 	memset(&adjust, 0, sizeof(adjust));
21591bf56e62SZeyu Fan 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
21601bf56e62SZeyu Fan 
21611bf56e62SZeyu Fan 
21624fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
21631bf56e62SZeyu Fan 		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
2164146a9f63SKrunoslav Kovac 
2165146a9f63SKrunoslav Kovac 		for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
2166146a9f63SKrunoslav Kovac 			adjust.temperature_matrix[i] =
2167146a9f63SKrunoslav Kovac 				pipe_ctx->stream->gamut_remap_matrix.matrix[i];
21681bf56e62SZeyu Fan 	}
21691bf56e62SZeyu Fan 
217086a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
21711bf56e62SZeyu Fan }
2172fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc,
21734562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx)
21744562236bSHarry Wentland {
21753be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
21764562236bSHarry Wentland 
21773be5262eSHarry Wentland 	if (plane_state == NULL)
21784562236bSHarry Wentland 		return;
21794562236bSHarry Wentland 
218086a66c4eSHarry Wentland 	pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
218186a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi,
21823be5262eSHarry Wentland 			&plane_state->address,
21833be5262eSHarry Wentland 			plane_state->flip_immediate);
21844562236bSHarry Wentland 
21853be5262eSHarry Wentland 	plane_state->status.requested_address = plane_state->address;
21864562236bSHarry Wentland }
21874562236bSHarry Wentland 
2188f774b339SEric Yang static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
21894562236bSHarry Wentland {
21903be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
21914562236bSHarry Wentland 
21923be5262eSHarry Wentland 	if (plane_state == NULL)
21934562236bSHarry Wentland 		return;
21944562236bSHarry Wentland 
21953be5262eSHarry Wentland 	plane_state->status.is_flip_pending =
219686a66c4eSHarry Wentland 			pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
219786a66c4eSHarry Wentland 					pipe_ctx->plane_res.mi);
21984562236bSHarry Wentland 
21993be5262eSHarry Wentland 	if (plane_state->status.is_flip_pending && !plane_state->visible)
220086a66c4eSHarry Wentland 		pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address;
22014562236bSHarry Wentland 
220286a66c4eSHarry Wentland 	plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
220386a66c4eSHarry Wentland 	if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
22046b670fa9SHarry Wentland 			pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) {
22053be5262eSHarry Wentland 		plane_state->status.is_right_eye =\
22066b670fa9SHarry Wentland 				!pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
22077f5c22d1SVitaly Prosyak 	}
22084562236bSHarry Wentland }
22094562236bSHarry Wentland 
2210fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc)
22114562236bSHarry Wentland {
22124562236bSHarry Wentland 	power_down_all_hw_blocks(dc);
22134562236bSHarry Wentland 	disable_vga_and_power_gate_all_controllers(dc);
22144562236bSHarry Wentland }
22154562236bSHarry Wentland 
22164562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur(
22174562236bSHarry Wentland 	struct dc_context *dc_ctx,
22184562236bSHarry Wentland 	struct timing_generator *tg)
22194562236bSHarry Wentland {
22204562236bSHarry Wentland 	bool rc = false;
22214562236bSHarry Wentland 
22224562236bSHarry Wentland 	/* To avoid endless loop we wait at most
22234562236bSHarry Wentland 	 * frames_to_wait_on_triggered_reset frames for the reset to occur. */
22244562236bSHarry Wentland 	const uint32_t frames_to_wait_on_triggered_reset = 10;
22254562236bSHarry Wentland 	uint32_t i;
22264562236bSHarry Wentland 
22274562236bSHarry Wentland 	for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
22284562236bSHarry Wentland 
22294562236bSHarry Wentland 		if (!tg->funcs->is_counter_moving(tg)) {
22304562236bSHarry Wentland 			DC_ERROR("TG counter is not moving!\n");
22314562236bSHarry Wentland 			break;
22324562236bSHarry Wentland 		}
22334562236bSHarry Wentland 
22344562236bSHarry Wentland 		if (tg->funcs->did_triggered_reset_occur(tg)) {
22354562236bSHarry Wentland 			rc = true;
22364562236bSHarry Wentland 			/* usually occurs at i=1 */
22374562236bSHarry Wentland 			DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
22384562236bSHarry Wentland 					i);
22394562236bSHarry Wentland 			break;
22404562236bSHarry Wentland 		}
22414562236bSHarry Wentland 
22424562236bSHarry Wentland 		/* Wait for one frame. */
22434562236bSHarry Wentland 		tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
22444562236bSHarry Wentland 		tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
22454562236bSHarry Wentland 	}
22464562236bSHarry Wentland 
22474562236bSHarry Wentland 	if (false == rc)
22484562236bSHarry Wentland 		DC_ERROR("GSL: Timeout on reset trigger!\n");
22494562236bSHarry Wentland 
22504562236bSHarry Wentland 	return rc;
22514562236bSHarry Wentland }
22524562236bSHarry Wentland 
22534562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */
22544562236bSHarry Wentland static void dce110_enable_timing_synchronization(
2255fb3466a4SBhawanpreet Lakha 		struct dc *dc,
22564562236bSHarry Wentland 		int group_index,
22574562236bSHarry Wentland 		int group_size,
22584562236bSHarry Wentland 		struct pipe_ctx *grouped_pipes[])
22594562236bSHarry Wentland {
22604562236bSHarry Wentland 	struct dc_context *dc_ctx = dc->ctx;
22614562236bSHarry Wentland 	struct dcp_gsl_params gsl_params = { 0 };
22624562236bSHarry Wentland 	int i;
22634562236bSHarry Wentland 
22644562236bSHarry Wentland 	DC_SYNC_INFO("GSL: Setting-up...\n");
22654562236bSHarry Wentland 
22664562236bSHarry Wentland 	/* Designate a single TG in the group as a master.
22674562236bSHarry Wentland 	 * Since HW doesn't care which one, we always assign
22684562236bSHarry Wentland 	 * the 1st one in the group. */
22694562236bSHarry Wentland 	gsl_params.gsl_group = 0;
22706b670fa9SHarry Wentland 	gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst;
22714562236bSHarry Wentland 
22724562236bSHarry Wentland 	for (i = 0; i < group_size; i++)
22736b670fa9SHarry Wentland 		grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
22746b670fa9SHarry Wentland 					grouped_pipes[i]->stream_res.tg, &gsl_params);
22754562236bSHarry Wentland 
22764562236bSHarry Wentland 	/* Reset slave controllers on master VSync */
22774562236bSHarry Wentland 	DC_SYNC_INFO("GSL: enabling trigger-reset\n");
22784562236bSHarry Wentland 
22794562236bSHarry Wentland 	for (i = 1 /* skip the master */; i < group_size; i++)
22806b670fa9SHarry Wentland 		grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
2281fa2123dbSMikita Lipski 				grouped_pipes[i]->stream_res.tg,
2282fa2123dbSMikita Lipski 				gsl_params.gsl_group);
22834562236bSHarry Wentland 
22844562236bSHarry Wentland 	for (i = 1 /* skip the master */; i < group_size; i++) {
22854562236bSHarry Wentland 		DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
22866b670fa9SHarry Wentland 		wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
2287fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
2288fa2123dbSMikita Lipski 				grouped_pipes[i]->stream_res.tg);
22894562236bSHarry Wentland 	}
22904562236bSHarry Wentland 
22914562236bSHarry Wentland 	/* GSL Vblank synchronization is a one time sync mechanism, assumption
22924562236bSHarry Wentland 	 * is that the sync'ed displays will not drift out of sync over time*/
22934562236bSHarry Wentland 	DC_SYNC_INFO("GSL: Restoring register states.\n");
22944562236bSHarry Wentland 	for (i = 0; i < group_size; i++)
22956b670fa9SHarry Wentland 		grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
22964562236bSHarry Wentland 
22974562236bSHarry Wentland 	DC_SYNC_INFO("GSL: Set-up complete.\n");
22984562236bSHarry Wentland }
22994562236bSHarry Wentland 
2300fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset(
2301fa2123dbSMikita Lipski 		struct dc *dc,
2302fa2123dbSMikita Lipski 		int group_size,
2303fa2123dbSMikita Lipski 		struct pipe_ctx *grouped_pipes[])
2304fa2123dbSMikita Lipski {
2305fa2123dbSMikita Lipski 	struct dc_context *dc_ctx = dc->ctx;
2306fa2123dbSMikita Lipski 	struct dcp_gsl_params gsl_params = { 0 };
2307fa2123dbSMikita Lipski 	int i;
2308fa2123dbSMikita Lipski 
2309fa2123dbSMikita Lipski 	gsl_params.gsl_group = 0;
231037cd85ceSDavid Francis 	gsl_params.gsl_master = 0;
2311fa2123dbSMikita Lipski 
2312fa2123dbSMikita Lipski 	for (i = 0; i < group_size; i++)
2313fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
2314fa2123dbSMikita Lipski 					grouped_pipes[i]->stream_res.tg, &gsl_params);
2315fa2123dbSMikita Lipski 
2316fa2123dbSMikita Lipski 	DC_SYNC_INFO("GSL: enabling trigger-reset\n");
2317fa2123dbSMikita Lipski 
2318fa2123dbSMikita Lipski 	for (i = 1; i < group_size; i++)
2319fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
2320fa2123dbSMikita Lipski 				grouped_pipes[i]->stream_res.tg,
2321fa2123dbSMikita Lipski 				gsl_params.gsl_master,
2322fa2123dbSMikita Lipski 				&grouped_pipes[i]->stream->triggered_crtc_reset);
2323fa2123dbSMikita Lipski 
2324fa2123dbSMikita Lipski 	DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
2325fa2123dbSMikita Lipski 	for (i = 1; i < group_size; i++)
2326fa2123dbSMikita Lipski 		wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
2327fa2123dbSMikita Lipski 
2328fa2123dbSMikita Lipski 	for (i = 0; i < group_size; i++)
2329fa2123dbSMikita Lipski 		grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
2330fa2123dbSMikita Lipski 
2331fa2123dbSMikita Lipski }
2332fa2123dbSMikita Lipski 
2333fb55546eSAnthony Koo static void init_pipes(struct dc *dc, struct dc_state *context)
2334fb55546eSAnthony Koo {
2335fb55546eSAnthony Koo 	// Do nothing
2336fb55546eSAnthony Koo }
2337fb55546eSAnthony Koo 
2338fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc)
23394562236bSHarry Wentland {
23404562236bSHarry Wentland 	int i;
23414562236bSHarry Wentland 	struct dc_bios *bp;
23424562236bSHarry Wentland 	struct transform *xfm;
23435e7773a2SAnthony Koo 	struct abm *abm;
234470d9e8cbSPaul Hsieh 	struct dmcu *dmcu;
23454562236bSHarry Wentland 
23464562236bSHarry Wentland 	bp = dc->ctx->dc_bios;
23474562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
23484562236bSHarry Wentland 		xfm = dc->res_pool->transforms[i];
23494562236bSHarry Wentland 		xfm->funcs->transform_reset(xfm);
23504562236bSHarry Wentland 
23514562236bSHarry Wentland 		dc->hwss.enable_display_power_gating(
23524562236bSHarry Wentland 				dc, i, bp,
23534562236bSHarry Wentland 				PIPE_GATING_CONTROL_INIT);
23544562236bSHarry Wentland 		dc->hwss.enable_display_power_gating(
23554562236bSHarry Wentland 				dc, i, bp,
23564562236bSHarry Wentland 				PIPE_GATING_CONTROL_DISABLE);
23574562236bSHarry Wentland 		dc->hwss.enable_display_pipe_clock_gating(
23584562236bSHarry Wentland 			dc->ctx,
23594562236bSHarry Wentland 			true);
23604562236bSHarry Wentland 	}
23614562236bSHarry Wentland 
2362e166ad43SJulia Lawall 	dce_clock_gating_power_up(dc->hwseq, false);
23634562236bSHarry Wentland 	/***************************************/
23644562236bSHarry Wentland 
23654562236bSHarry Wentland 	for (i = 0; i < dc->link_count; i++) {
23664562236bSHarry Wentland 		/****************************************/
23674562236bSHarry Wentland 		/* Power up AND update implementation according to the
23684562236bSHarry Wentland 		 * required signal (which may be different from the
23694562236bSHarry Wentland 		 * default signal on connector). */
2370d0778ebfSHarry Wentland 		struct dc_link *link = dc->links[i];
2371069d418fSAndrew Jiang 
23724562236bSHarry Wentland 		link->link_enc->funcs->hw_init(link->link_enc);
23734562236bSHarry Wentland 	}
23744562236bSHarry Wentland 
23754562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
23764562236bSHarry Wentland 		struct timing_generator *tg = dc->res_pool->timing_generators[i];
23774562236bSHarry Wentland 
23784562236bSHarry Wentland 		tg->funcs->disable_vga(tg);
23794562236bSHarry Wentland 
23804562236bSHarry Wentland 		/* Blank controller using driver code instead of
23814562236bSHarry Wentland 		 * command table. */
23824562236bSHarry Wentland 		tg->funcs->set_blank(tg, true);
23834b5e7d62SHersen Wu 		hwss_wait_for_blank_complete(tg);
23844562236bSHarry Wentland 	}
23854562236bSHarry Wentland 
23864562236bSHarry Wentland 	for (i = 0; i < dc->res_pool->audio_count; i++) {
23874562236bSHarry Wentland 		struct audio *audio = dc->res_pool->audios[i];
23884562236bSHarry Wentland 		audio->funcs->hw_init(audio);
23894562236bSHarry Wentland 	}
23905e7773a2SAnthony Koo 
23915e7773a2SAnthony Koo 	abm = dc->res_pool->abm;
23926728b30cSAnthony Koo 	if (abm != NULL) {
23936728b30cSAnthony Koo 		abm->funcs->init_backlight(abm);
23945e7773a2SAnthony Koo 		abm->funcs->abm_init(abm);
23954562236bSHarry Wentland 	}
23965099114bSAlex Deucher 
239770d9e8cbSPaul Hsieh 	dmcu = dc->res_pool->dmcu;
239870d9e8cbSPaul Hsieh 	if (dmcu != NULL && abm != NULL)
239970d9e8cbSPaul Hsieh 		abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
240070d9e8cbSPaul Hsieh 
24012f3bfb27SRoman Li 	if (dc->fbc_compressor)
24021663ae1cSBhawanpreet Lakha 		dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
2403690b5e39SRoman Li 
24046728b30cSAnthony Koo }
24054562236bSHarry Wentland 
24069566b675SDmytro Laktyushkin 
24079566b675SDmytro Laktyushkin void dce110_prepare_bandwidth(
2408fb3466a4SBhawanpreet Lakha 		struct dc *dc,
24099566b675SDmytro Laktyushkin 		struct dc_state *context)
2410cf437593SDmytro Laktyushkin {
2411dc88b4a6SEric Yang 	struct clk_mgr *dccg = dc->clk_mgr;
2412fab55d61SDmytro Laktyushkin 
2413fab55d61SDmytro Laktyushkin 	dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
2414cf437593SDmytro Laktyushkin 
24155a83c932SNicholas Kazlauskas 	dccg->funcs->update_clocks(
24165a83c932SNicholas Kazlauskas 			dccg,
241724f7dd7eSDmytro Laktyushkin 			context,
24189566b675SDmytro Laktyushkin 			false);
24199566b675SDmytro Laktyushkin }
24209566b675SDmytro Laktyushkin 
24219566b675SDmytro Laktyushkin void dce110_optimize_bandwidth(
24229566b675SDmytro Laktyushkin 		struct dc *dc,
24239566b675SDmytro Laktyushkin 		struct dc_state *context)
24249566b675SDmytro Laktyushkin {
2425dc88b4a6SEric Yang 	struct clk_mgr *dccg = dc->clk_mgr;
24269566b675SDmytro Laktyushkin 
24279566b675SDmytro Laktyushkin 	dce110_set_displaymarks(dc, context);
24289566b675SDmytro Laktyushkin 
24299566b675SDmytro Laktyushkin 	dccg->funcs->update_clocks(
24309566b675SDmytro Laktyushkin 			dccg,
24319566b675SDmytro Laktyushkin 			context,
24329566b675SDmytro Laktyushkin 			true);
24334562236bSHarry Wentland }
24344562236bSHarry Wentland 
24354562236bSHarry Wentland static void dce110_program_front_end_for_pipe(
2436fb3466a4SBhawanpreet Lakha 		struct dc *dc, struct pipe_ctx *pipe_ctx)
24374562236bSHarry Wentland {
243886a66c4eSHarry Wentland 	struct mem_input *mi = pipe_ctx->plane_res.mi;
24394562236bSHarry Wentland 	struct pipe_ctx *old_pipe = NULL;
24403be5262eSHarry Wentland 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
24414562236bSHarry Wentland 	struct xfm_grph_csc_adjustment adjust;
24424562236bSHarry Wentland 	struct out_csc_color_matrix tbl_entry;
24434562236bSHarry Wentland 	unsigned int i;
24445d4b05ddSBhawanpreet Lakha 	DC_LOGGER_INIT();
24454562236bSHarry Wentland 	memset(&tbl_entry, 0, sizeof(tbl_entry));
24464562236bSHarry Wentland 
2447608ac7bbSJerry Zuo 	if (dc->current_state)
2448608ac7bbSJerry Zuo 		old_pipe = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
24494562236bSHarry Wentland 
24504562236bSHarry Wentland 	memset(&adjust, 0, sizeof(adjust));
24514562236bSHarry Wentland 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
24524562236bSHarry Wentland 
2453e07f541fSYongqiang Sun 	dce_enable_fe_clock(dc->hwseq, mi->inst, true);
24544562236bSHarry Wentland 
24554562236bSHarry Wentland 	set_default_colors(pipe_ctx);
24564fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
24574562236bSHarry Wentland 			== true) {
24584562236bSHarry Wentland 		tbl_entry.color_space =
24594fa086b9SLeo (Sunpeng) Li 			pipe_ctx->stream->output_color_space;
24604562236bSHarry Wentland 
24614562236bSHarry Wentland 		for (i = 0; i < 12; i++)
24624562236bSHarry Wentland 			tbl_entry.regval[i] =
24634fa086b9SLeo (Sunpeng) Li 			pipe_ctx->stream->csc_color_matrix.matrix[i];
24644562236bSHarry Wentland 
246586a66c4eSHarry Wentland 		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
246686a66c4eSHarry Wentland 				(pipe_ctx->plane_res.xfm, &tbl_entry);
24674562236bSHarry Wentland 	}
24684562236bSHarry Wentland 
24694fa086b9SLeo (Sunpeng) Li 	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
24704562236bSHarry Wentland 		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
2471146a9f63SKrunoslav Kovac 
2472146a9f63SKrunoslav Kovac 		for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
2473146a9f63SKrunoslav Kovac 			adjust.temperature_matrix[i] =
2474146a9f63SKrunoslav Kovac 				pipe_ctx->stream->gamut_remap_matrix.matrix[i];
24754562236bSHarry Wentland 	}
24764562236bSHarry Wentland 
247786a66c4eSHarry Wentland 	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
24784562236bSHarry Wentland 
24796702a9acSHarry Wentland 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
2480c1473558SAndrey Grodzovsky 
24814562236bSHarry Wentland 	program_scaler(dc, pipe_ctx);
24824562236bSHarry Wentland 
24834562236bSHarry Wentland 	mi->funcs->mem_input_program_surface_config(
24844562236bSHarry Wentland 			mi,
24853be5262eSHarry Wentland 			plane_state->format,
24863be5262eSHarry Wentland 			&plane_state->tiling_info,
24873be5262eSHarry Wentland 			&plane_state->plane_size,
24883be5262eSHarry Wentland 			plane_state->rotation,
2489624d7c47SYongqiang Sun 			NULL,
24904b28b76bSDmytro Laktyushkin 			false);
24914b28b76bSDmytro Laktyushkin 	if (mi->funcs->set_blank)
24923be5262eSHarry Wentland 		mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
24934562236bSHarry Wentland 
2494fb3466a4SBhawanpreet Lakha 	if (dc->config.gpu_vm_support)
24954562236bSHarry Wentland 		mi->funcs->mem_input_program_pte_vm(
249686a66c4eSHarry Wentland 				pipe_ctx->plane_res.mi,
24973be5262eSHarry Wentland 				plane_state->format,
24983be5262eSHarry Wentland 				&plane_state->tiling_info,
24993be5262eSHarry Wentland 				plane_state->rotation);
25004562236bSHarry Wentland 
2501067c878aSYongqiang Sun 	/* Moved programming gamma from dc to hwss */
2502405c50a0SAndrew Jiang 	if (pipe_ctx->plane_state->update_flags.bits.full_update ||
2503405c50a0SAndrew Jiang 			pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
2504405c50a0SAndrew Jiang 			pipe_ctx->plane_state->update_flags.bits.gamma_change)
2505a6114e85SHarry Wentland 		dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state);
2506405c50a0SAndrew Jiang 
2507405c50a0SAndrew Jiang 	if (pipe_ctx->plane_state->update_flags.bits.full_update)
2508a6114e85SHarry Wentland 		dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream);
2509067c878aSYongqiang Sun 
25101296423bSBhawanpreet Lakha 	DC_LOG_SURFACE(
25113032deb5SBhawanpreet Lakha 			"Pipe:%d %p: addr hi:0x%x, "
25124562236bSHarry Wentland 			"addr low:0x%x, "
25134562236bSHarry Wentland 			"src: %d, %d, %d,"
25144562236bSHarry Wentland 			" %d; dst: %d, %d, %d, %d;"
25154562236bSHarry Wentland 			"clip: %d, %d, %d, %d\n",
25164562236bSHarry Wentland 			pipe_ctx->pipe_idx,
25173032deb5SBhawanpreet Lakha 			(void *) pipe_ctx->plane_state,
25183be5262eSHarry Wentland 			pipe_ctx->plane_state->address.grph.addr.high_part,
25193be5262eSHarry Wentland 			pipe_ctx->plane_state->address.grph.addr.low_part,
25203be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.x,
25213be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.y,
25223be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.width,
25233be5262eSHarry Wentland 			pipe_ctx->plane_state->src_rect.height,
25243be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.x,
25253be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.y,
25263be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.width,
25273be5262eSHarry Wentland 			pipe_ctx->plane_state->dst_rect.height,
25283be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.x,
25293be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.y,
25303be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.width,
25313be5262eSHarry Wentland 			pipe_ctx->plane_state->clip_rect.height);
25324562236bSHarry Wentland 
25331296423bSBhawanpreet Lakha 	DC_LOG_SURFACE(
25344562236bSHarry Wentland 			"Pipe %d: width, height, x, y\n"
25354562236bSHarry Wentland 			"viewport:%d, %d, %d, %d\n"
25364562236bSHarry Wentland 			"recout:  %d, %d, %d, %d\n",
25374562236bSHarry Wentland 			pipe_ctx->pipe_idx,
25386702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.width,
25396702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.height,
25406702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.x,
25416702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.viewport.y,
25426702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.width,
25436702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.height,
25446702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.x,
25456702a9acSHarry Wentland 			pipe_ctx->plane_res.scl_data.recout.y);
25464562236bSHarry Wentland }
25474562236bSHarry Wentland 
25484562236bSHarry Wentland static void dce110_apply_ctx_for_surface(
2549fb3466a4SBhawanpreet Lakha 		struct dc *dc,
25503e9ad616SEric Yang 		const struct dc_stream_state *stream,
25513e9ad616SEric Yang 		int num_planes,
2552608ac7bbSJerry Zuo 		struct dc_state *context)
25534562236bSHarry Wentland {
25542194e3aeSRoman Li 	int i;
25554562236bSHarry Wentland 
25563e9ad616SEric Yang 	if (num_planes == 0)
25574562236bSHarry Wentland 		return;
25584562236bSHarry Wentland 
255965d38262Shersen wu 	if (dc->fbc_compressor)
256065d38262Shersen wu 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
256165d38262Shersen wu 
25623e9ad616SEric Yang 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
25633dc780ecSYongqiang Sun 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
25643dc780ecSYongqiang Sun 		struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
25653dc780ecSYongqiang Sun 
25662194e3aeSRoman Li 		if (stream == pipe_ctx->stream) {
25673dc780ecSYongqiang Sun 			if (!pipe_ctx->top_pipe &&
25683dc780ecSYongqiang Sun 				(pipe_ctx->plane_state || old_pipe_ctx->plane_state))
25693dc780ecSYongqiang Sun 				dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
25703e9ad616SEric Yang 		}
25713e9ad616SEric Yang 	}
25723e9ad616SEric Yang 
2573a2b8659dSTony Cheng 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
25744562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
25754562236bSHarry Wentland 
2576a2607aefSHarry Wentland 		if (pipe_ctx->stream != stream)
25774562236bSHarry Wentland 			continue;
25784562236bSHarry Wentland 
25793b21b6d2SJerry Zuo 		/* Need to allocate mem before program front end for Fiji */
25803b21b6d2SJerry Zuo 		pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
25813b21b6d2SJerry Zuo 				pipe_ctx->plane_res.mi,
25823b21b6d2SJerry Zuo 				pipe_ctx->stream->timing.h_total,
25833b21b6d2SJerry Zuo 				pipe_ctx->stream->timing.v_total,
2584380604e2SKen Chalmers 				pipe_ctx->stream->timing.pix_clk_100hz / 10,
25853b21b6d2SJerry Zuo 				context->stream_count);
25863b21b6d2SJerry Zuo 
25874562236bSHarry Wentland 		dce110_program_front_end_for_pipe(dc, pipe_ctx);
25884f804817SYongqiang Sun 
25894f804817SYongqiang Sun 		dc->hwss.update_plane_addr(dc, pipe_ctx);
25904f804817SYongqiang Sun 
2591b06b7680SLeon Elazar 		program_surface_visibility(dc, pipe_ctx);
25924562236bSHarry Wentland 
25934562236bSHarry Wentland 	}
25943dc780ecSYongqiang Sun 
25953dc780ecSYongqiang Sun 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
25963dc780ecSYongqiang Sun 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
25973dc780ecSYongqiang Sun 		struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
25983dc780ecSYongqiang Sun 
25993dc780ecSYongqiang Sun 		if ((stream == pipe_ctx->stream) &&
26003dc780ecSYongqiang Sun 			(!pipe_ctx->top_pipe) &&
26013dc780ecSYongqiang Sun 			(pipe_ctx->plane_state || old_pipe_ctx->plane_state))
26023dc780ecSYongqiang Sun 			dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
26033dc780ecSYongqiang Sun 	}
260465d38262Shersen wu 
260565d38262Shersen wu 	if (dc->fbc_compressor)
260612a8bd88SShirish S 		enable_fbc(dc, context);
26074562236bSHarry Wentland }
26084562236bSHarry Wentland 
2609e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
26104562236bSHarry Wentland {
2611bc373a89SRoman Li 	int fe_idx = pipe_ctx->plane_res.mi ?
2612bc373a89SRoman Li 		pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
2613e6c258cbSYongqiang Sun 
26147950f0f9SDmytro Laktyushkin 	/* Do not power down fe when stream is active on dce*/
2615608ac7bbSJerry Zuo 	if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
26164562236bSHarry Wentland 		return;
26174562236bSHarry Wentland 
26184562236bSHarry Wentland 	dc->hwss.enable_display_power_gating(
2619cfe4645eSDmytro Laktyushkin 		dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
2620cfe4645eSDmytro Laktyushkin 
2621cfe4645eSDmytro Laktyushkin 	dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
2622cfe4645eSDmytro Laktyushkin 				dc->res_pool->transforms[fe_idx]);
26234562236bSHarry Wentland }
26244562236bSHarry Wentland 
26256be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect(
2626fb3466a4SBhawanpreet Lakha 		struct dc *dc,
26276be425f3SEric Yang 		struct resource_pool *res_pool,
26286be425f3SEric Yang 		struct pipe_ctx *pipe_ctx)
2629b6762f0cSEric Yang {
2630b6762f0cSEric Yang 	/* do nothing*/
2631b6762f0cSEric Yang }
2632b6762f0cSEric Yang 
26334bd0dc68SJoshua Aberback static void program_output_csc(struct dc *dc,
26344bd0dc68SJoshua Aberback 		struct pipe_ctx *pipe_ctx,
26354bd0dc68SJoshua Aberback 		enum dc_color_space colorspace,
26364bd0dc68SJoshua Aberback 		uint16_t *matrix,
26374bd0dc68SJoshua Aberback 		int opp_id)
26384bd0dc68SJoshua Aberback {
26394bd0dc68SJoshua Aberback 	int i;
26404bd0dc68SJoshua Aberback 	struct out_csc_color_matrix tbl_entry;
26414bd0dc68SJoshua Aberback 
26424bd0dc68SJoshua Aberback 	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
26434bd0dc68SJoshua Aberback 		enum dc_color_space color_space = pipe_ctx->stream->output_color_space;
26444bd0dc68SJoshua Aberback 
26454bd0dc68SJoshua Aberback 		for (i = 0; i < 12; i++)
26464bd0dc68SJoshua Aberback 			tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
26474bd0dc68SJoshua Aberback 
26484bd0dc68SJoshua Aberback 		tbl_entry.color_space = color_space;
26494bd0dc68SJoshua Aberback 
26504bd0dc68SJoshua Aberback 		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
26514bd0dc68SJoshua Aberback 				pipe_ctx->plane_res.xfm, &tbl_entry);
26524bd0dc68SJoshua Aberback 	}
26534bd0dc68SJoshua Aberback }
26544bd0dc68SJoshua Aberback 
265533fd17d9SEric Yang void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
265633fd17d9SEric Yang {
265733fd17d9SEric Yang 	struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
265833fd17d9SEric Yang 	struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
265933fd17d9SEric Yang 	struct mem_input *mi = pipe_ctx->plane_res.mi;
266033fd17d9SEric Yang 	struct dc_cursor_mi_param param = {
2661380604e2SKen Chalmers 		.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
266233d7598dSJun Lei 		.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz,
266339a9f4d8SDmytro Laktyushkin 		.viewport = pipe_ctx->plane_res.scl_data.viewport,
266439a9f4d8SDmytro Laktyushkin 		.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
266539a9f4d8SDmytro Laktyushkin 		.v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
266608ed681cSDmytro Laktyushkin 		.rotation = pipe_ctx->plane_state->rotation,
266708ed681cSDmytro Laktyushkin 		.mirror = pipe_ctx->plane_state->horizontal_mirror
266833fd17d9SEric Yang 	};
266933fd17d9SEric Yang 
267033fd17d9SEric Yang 	if (pipe_ctx->plane_state->address.type
267133fd17d9SEric Yang 			== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
267233fd17d9SEric Yang 		pos_cpy.enable = false;
267333fd17d9SEric Yang 
267433fd17d9SEric Yang 	if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
267533fd17d9SEric Yang 		pos_cpy.enable = false;
267633fd17d9SEric Yang 
2677dc75dd70SRoman Li 	if (ipp->funcs->ipp_cursor_set_position)
267833fd17d9SEric Yang 		ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
2679dc75dd70SRoman Li 	if (mi->funcs->set_cursor_position)
268033fd17d9SEric Yang 		mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
268133fd17d9SEric Yang }
268233fd17d9SEric Yang 
268333fd17d9SEric Yang void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
268433fd17d9SEric Yang {
268533fd17d9SEric Yang 	struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
268633fd17d9SEric Yang 
2687d1aaad05SHarry Wentland 	if (pipe_ctx->plane_res.ipp &&
2688d1aaad05SHarry Wentland 	    pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
268933fd17d9SEric Yang 		pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
269033fd17d9SEric Yang 				pipe_ctx->plane_res.ipp, attributes);
269133fd17d9SEric Yang 
2692d1aaad05SHarry Wentland 	if (pipe_ctx->plane_res.mi &&
2693d1aaad05SHarry Wentland 	    pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
269433fd17d9SEric Yang 		pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
269533fd17d9SEric Yang 				pipe_ctx->plane_res.mi, attributes);
269633fd17d9SEric Yang 
2697d1aaad05SHarry Wentland 	if (pipe_ctx->plane_res.xfm &&
2698d1aaad05SHarry Wentland 	    pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
269933fd17d9SEric Yang 		pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
270033fd17d9SEric Yang 				pipe_ctx->plane_res.xfm, attributes);
270133fd17d9SEric Yang }
270233fd17d9SEric Yang 
27034562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = {
27041bf56e62SZeyu Fan 	.program_gamut_remap = program_gamut_remap,
27054bd0dc68SJoshua Aberback 	.program_output_csc = program_output_csc,
27064562236bSHarry Wentland 	.init_hw = init_hw,
2707fb55546eSAnthony Koo 	.init_pipes = init_pipes,
27084562236bSHarry Wentland 	.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
27094562236bSHarry Wentland 	.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
27104562236bSHarry Wentland 	.update_plane_addr = update_plane_addr,
27114562236bSHarry Wentland 	.update_pending_status = dce110_update_pending_status,
2712d7194cf6SAric Cyr 	.set_input_transfer_func = dce110_set_input_transfer_func,
271390e508baSAnthony Koo 	.set_output_transfer_func = dce110_set_output_transfer_func,
27144562236bSHarry Wentland 	.power_down = dce110_power_down,
27154562236bSHarry Wentland 	.enable_accelerated_mode = dce110_enable_accelerated_mode,
27164562236bSHarry Wentland 	.enable_timing_synchronization = dce110_enable_timing_synchronization,
2717fa2123dbSMikita Lipski 	.enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
27184562236bSHarry Wentland 	.update_info_frame = dce110_update_info_frame,
27194562236bSHarry Wentland 	.enable_stream = dce110_enable_stream,
27204562236bSHarry Wentland 	.disable_stream = dce110_disable_stream,
27214562236bSHarry Wentland 	.unblank_stream = dce110_unblank_stream,
272241b49742SCharlene Liu 	.blank_stream = dce110_blank_stream,
27231a05873fSAnthony Koo 	.enable_audio_stream = dce110_enable_audio_stream,
27241a05873fSAnthony Koo 	.disable_audio_stream = dce110_disable_audio_stream,
27254562236bSHarry Wentland 	.enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
27264562236bSHarry Wentland 	.enable_display_power_gating = dce110_enable_display_power_gating,
27277f914a62SYongqiang Sun 	.disable_plane = dce110_power_down_fe,
27284562236bSHarry Wentland 	.pipe_control_lock = dce_pipe_control_lock,
27299566b675SDmytro Laktyushkin 	.prepare_bandwidth = dce110_prepare_bandwidth,
27309566b675SDmytro Laktyushkin 	.optimize_bandwidth = dce110_optimize_bandwidth,
27314562236bSHarry Wentland 	.set_drr = set_drr,
273272ada5f7SEric Cook 	.get_position = get_position,
27334562236bSHarry Wentland 	.set_static_screen_control = set_static_screen_control,
273454e8695eSDmytro Laktyushkin 	.reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
27353158223eSEric Bernstein 	.enable_stream_timing = dce110_enable_stream_timing,
2736240d09d0SGary Kattan 	.disable_stream_gating = NULL,
2737240d09d0SGary Kattan 	.enable_stream_gating = NULL,
273815e17335SCharlene Liu 	.setup_stereo = NULL,
273915e17335SCharlene Liu 	.set_avmute = dce110_set_avmute,
274041f97c07SHersen Wu 	.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
274187401969SAndrew Jiang 	.edp_backlight_control = hwss_edp_backlight_control,
274287401969SAndrew Jiang 	.edp_power_control = hwss_edp_power_control,
2743904623eeSYongqiang Sun 	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
274433fd17d9SEric Yang 	.set_cursor_position = dce110_set_cursor_position,
274533fd17d9SEric Yang 	.set_cursor_attribute = dce110_set_cursor_attribute
27464562236bSHarry Wentland };
27474562236bSHarry Wentland 
2748c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc)
27494562236bSHarry Wentland {
27504562236bSHarry Wentland 	dc->hwss = dce110_funcs;
27514562236bSHarry Wentland }
27524562236bSHarry Wentland 
2753