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