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