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 "dm_services.h"
27 #include "core_types.h"
28 #include "timing_generator.h"
29 #include "hw_sequencer.h"
30 #include "hw_sequencer_private.h"
31 #include "basics/dc_common.h"
32 
33 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
34 
35 /* used as index in array of black_color_format */
36 enum black_color_format {
37 	BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0,
38 	BLACK_COLOR_FORMAT_RGB_LIMITED,
39 	BLACK_COLOR_FORMAT_YUV_TV,
40 	BLACK_COLOR_FORMAT_YUV_CV,
41 	BLACK_COLOR_FORMAT_YUV_SUPER_AA,
42 	BLACK_COLOR_FORMAT_DEBUG,
43 };
44 
45 enum dc_color_space_type {
46 	COLOR_SPACE_RGB_TYPE,
47 	COLOR_SPACE_RGB_LIMITED_TYPE,
48 	COLOR_SPACE_YCBCR601_TYPE,
49 	COLOR_SPACE_YCBCR709_TYPE,
50 	COLOR_SPACE_YCBCR2020_TYPE,
51 	COLOR_SPACE_YCBCR601_LIMITED_TYPE,
52 	COLOR_SPACE_YCBCR709_LIMITED_TYPE,
53 	COLOR_SPACE_YCBCR709_BLACK_TYPE,
54 };
55 
56 static const struct tg_color black_color_format[] = {
57 	/* BlackColorFormat_RGB_FullRange */
58 	{0, 0, 0},
59 	/* BlackColorFormat_RGB_Limited */
60 	{0x40, 0x40, 0x40},
61 	/* BlackColorFormat_YUV_TV */
62 	{0x200, 0x40, 0x200},
63 	/* BlackColorFormat_YUV_CV */
64 	{0x1f4, 0x40, 0x1f4},
65 	/* BlackColorFormat_YUV_SuperAA */
66 	{0x1a2, 0x20, 0x1a2},
67 	/* visual confirm debug */
68 	{0xff, 0xff, 0},
69 };
70 
71 struct out_csc_color_matrix_type {
72 	enum dc_color_space_type color_space_type;
73 	uint16_t regval[12];
74 };
75 
76 static const struct out_csc_color_matrix_type output_csc_matrix[] = {
77 	{ COLOR_SPACE_RGB_TYPE,
78 		{ 0x2000, 0,      0,      0,
79 		  0,      0x2000, 0,      0,
80 		  0,      0,      0x2000, 0} },
81 	{ COLOR_SPACE_RGB_LIMITED_TYPE,
82 		{ 0x1B67, 0,      0,      0x201,
83 		  0,      0x1B67, 0,      0x201,
84 		  0,      0,      0x1B67, 0x201} },
85 	{ COLOR_SPACE_YCBCR601_TYPE,
86 		{ 0xE04,  0xF444, 0xFDB9, 0x1004,
87 		  0x831,  0x1016, 0x320,  0x201,
88 		  0xFB45, 0xF6B7, 0xE04,  0x1004} },
89 	{ COLOR_SPACE_YCBCR709_TYPE,
90 		{ 0xE04,  0xF345, 0xFEB7, 0x1004,
91 		  0x5D3,  0x1399, 0x1FA,  0x201,
92 		  0xFCCA, 0xF533, 0xE04,  0x1004} },
93 	/* TODO: correct values below */
94 	{ COLOR_SPACE_YCBCR601_LIMITED_TYPE,
95 		{ 0xE00,  0xF447, 0xFDB9, 0x1000,
96 		  0x991,  0x12C9, 0x3A6,  0x200,
97 		  0xFB47, 0xF6B9, 0xE00,  0x1000} },
98 	{ COLOR_SPACE_YCBCR709_LIMITED_TYPE,
99 		{ 0xE00, 0xF349, 0xFEB7, 0x1000,
100 		  0x6CE, 0x16E3, 0x24F,  0x200,
101 		  0xFCCB, 0xF535, 0xE00, 0x1000} },
102 	{ COLOR_SPACE_YCBCR2020_TYPE,
103 		{ 0x1000, 0xF149, 0xFEB7, 0x1004,
104 		  0x0868, 0x15B2, 0x01E6, 0x201,
105 		  0xFB88, 0xF478, 0x1000, 0x1004} },
106 	{ COLOR_SPACE_YCBCR709_BLACK_TYPE,
107 		{ 0x0000, 0x0000, 0x0000, 0x1000,
108 		  0x0000, 0x0000, 0x0000, 0x0200,
109 		  0x0000, 0x0000, 0x0000, 0x1000} },
110 };
111 
is_rgb_type(enum dc_color_space color_space)112 static bool is_rgb_type(
113 		enum dc_color_space color_space)
114 {
115 	bool ret = false;
116 
117 	if (color_space == COLOR_SPACE_SRGB			||
118 		color_space == COLOR_SPACE_XR_RGB		||
119 		color_space == COLOR_SPACE_MSREF_SCRGB		||
120 		color_space == COLOR_SPACE_2020_RGB_FULLRANGE	||
121 		color_space == COLOR_SPACE_ADOBERGB		||
122 		color_space == COLOR_SPACE_DCIP3	||
123 		color_space == COLOR_SPACE_DOLBYVISION)
124 		ret = true;
125 	return ret;
126 }
127 
is_rgb_limited_type(enum dc_color_space color_space)128 static bool is_rgb_limited_type(
129 		enum dc_color_space color_space)
130 {
131 	bool ret = false;
132 
133 	if (color_space == COLOR_SPACE_SRGB_LIMITED		||
134 		color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
135 		ret = true;
136 	return ret;
137 }
138 
is_ycbcr601_type(enum dc_color_space color_space)139 static bool is_ycbcr601_type(
140 		enum dc_color_space color_space)
141 {
142 	bool ret = false;
143 
144 	if (color_space == COLOR_SPACE_YCBCR601	||
145 		color_space == COLOR_SPACE_XV_YCC_601)
146 		ret = true;
147 	return ret;
148 }
149 
is_ycbcr601_limited_type(enum dc_color_space color_space)150 static bool is_ycbcr601_limited_type(
151 		enum dc_color_space color_space)
152 {
153 	bool ret = false;
154 
155 	if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
156 		ret = true;
157 	return ret;
158 }
159 
is_ycbcr709_type(enum dc_color_space color_space)160 static bool is_ycbcr709_type(
161 		enum dc_color_space color_space)
162 {
163 	bool ret = false;
164 
165 	if (color_space == COLOR_SPACE_YCBCR709	||
166 		color_space == COLOR_SPACE_XV_YCC_709)
167 		ret = true;
168 	return ret;
169 }
170 
is_ycbcr2020_type(enum dc_color_space color_space)171 static bool is_ycbcr2020_type(
172 	enum dc_color_space color_space)
173 {
174 	bool ret = false;
175 
176 	if (color_space == COLOR_SPACE_2020_YCBCR)
177 		ret = true;
178 	return ret;
179 }
180 
is_ycbcr709_limited_type(enum dc_color_space color_space)181 static bool is_ycbcr709_limited_type(
182 		enum dc_color_space color_space)
183 {
184 	bool ret = false;
185 
186 	if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
187 		ret = true;
188 	return ret;
189 }
190 
get_color_space_type(enum dc_color_space color_space)191 static enum dc_color_space_type get_color_space_type(enum dc_color_space color_space)
192 {
193 	enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE;
194 
195 	if (is_rgb_type(color_space))
196 		type = COLOR_SPACE_RGB_TYPE;
197 	else if (is_rgb_limited_type(color_space))
198 		type = COLOR_SPACE_RGB_LIMITED_TYPE;
199 	else if (is_ycbcr601_type(color_space))
200 		type = COLOR_SPACE_YCBCR601_TYPE;
201 	else if (is_ycbcr709_type(color_space))
202 		type = COLOR_SPACE_YCBCR709_TYPE;
203 	else if (is_ycbcr601_limited_type(color_space))
204 		type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
205 	else if (is_ycbcr709_limited_type(color_space))
206 		type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
207 	else if (is_ycbcr2020_type(color_space))
208 		type = COLOR_SPACE_YCBCR2020_TYPE;
209 	else if (color_space == COLOR_SPACE_YCBCR709)
210 		type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
211 	else if (color_space == COLOR_SPACE_YCBCR709_BLACK)
212 		type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
213 	return type;
214 }
215 
find_color_matrix(enum dc_color_space color_space,uint32_t * array_size)216 const uint16_t *find_color_matrix(enum dc_color_space color_space,
217 							uint32_t *array_size)
218 {
219 	int i;
220 	enum dc_color_space_type type;
221 	const uint16_t *val = NULL;
222 	int arr_size = NUM_ELEMENTS(output_csc_matrix);
223 
224 	type = get_color_space_type(color_space);
225 	for (i = 0; i < arr_size; i++)
226 		if (output_csc_matrix[i].color_space_type == type) {
227 			val = output_csc_matrix[i].regval;
228 			*array_size = 12;
229 			break;
230 		}
231 
232 	return val;
233 }
234 
235 
color_space_to_black_color(const struct dc * dc,enum dc_color_space colorspace,struct tg_color * black_color)236 void color_space_to_black_color(
237 	const struct dc *dc,
238 	enum dc_color_space colorspace,
239 	struct tg_color *black_color)
240 {
241 	switch (colorspace) {
242 	case COLOR_SPACE_YCBCR601:
243 	case COLOR_SPACE_YCBCR709:
244 	case COLOR_SPACE_YCBCR709_BLACK:
245 	case COLOR_SPACE_YCBCR601_LIMITED:
246 	case COLOR_SPACE_YCBCR709_LIMITED:
247 	case COLOR_SPACE_2020_YCBCR:
248 		*black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
249 		break;
250 
251 	case COLOR_SPACE_SRGB_LIMITED:
252 		*black_color =
253 			black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
254 		break;
255 
256 	/**
257 	 * Remove default and add case for all color space
258 	 * so when we forget to add new color space
259 	 * compiler will give a warning
260 	 */
261 	case COLOR_SPACE_UNKNOWN:
262 	case COLOR_SPACE_SRGB:
263 	case COLOR_SPACE_XR_RGB:
264 	case COLOR_SPACE_MSREF_SCRGB:
265 	case COLOR_SPACE_XV_YCC_709:
266 	case COLOR_SPACE_XV_YCC_601:
267 	case COLOR_SPACE_2020_RGB_FULLRANGE:
268 	case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
269 	case COLOR_SPACE_ADOBERGB:
270 	case COLOR_SPACE_DCIP3:
271 	case COLOR_SPACE_DISPLAYNATIVE:
272 	case COLOR_SPACE_DOLBYVISION:
273 	case COLOR_SPACE_APPCTRL:
274 	case COLOR_SPACE_CUSTOMPOINTS:
275 		/* fefault is sRGB black (full range). */
276 		*black_color =
277 			black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
278 		/* default is sRGB black 0. */
279 		break;
280 	}
281 }
282 
hwss_wait_for_blank_complete(struct timing_generator * tg)283 bool hwss_wait_for_blank_complete(
284 		struct timing_generator *tg)
285 {
286 	int counter;
287 
288 	/* Not applicable if the pipe is not primary, save 300ms of boot time */
289 	if (!tg->funcs->is_blanked)
290 		return true;
291 	for (counter = 0; counter < 100; counter++) {
292 		if (tg->funcs->is_blanked(tg))
293 			break;
294 
295 		drm_msleep(1);
296 	}
297 
298 	if (counter == 100) {
299 		dm_error("DC: failed to blank crtc!\n");
300 		return false;
301 	}
302 
303 	return true;
304 }
305 
get_mpctree_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)306 void get_mpctree_visual_confirm_color(
307 		struct pipe_ctx *pipe_ctx,
308 		struct tg_color *color)
309 {
310 	const struct tg_color pipe_colors[6] = {
311 			{MAX_TG_COLOR_VALUE, 0, 0}, /* red */
312 			{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE / 4, 0}, /* orange */
313 			{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */
314 			{0, MAX_TG_COLOR_VALUE, 0}, /* green */
315 			{0, 0, MAX_TG_COLOR_VALUE}, /* blue */
316 			{MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, /* purple */
317 	};
318 
319 	struct pipe_ctx *top_pipe = pipe_ctx;
320 
321 	while (top_pipe->top_pipe)
322 		top_pipe = top_pipe->top_pipe;
323 
324 	*color = pipe_colors[top_pipe->pipe_idx];
325 }
326 
get_surface_visual_confirm_color(const struct pipe_ctx * pipe_ctx,struct tg_color * color)327 void get_surface_visual_confirm_color(
328 		const struct pipe_ctx *pipe_ctx,
329 		struct tg_color *color)
330 {
331 	uint32_t color_value = MAX_TG_COLOR_VALUE;
332 
333 	switch (pipe_ctx->plane_res.scl_data.format) {
334 	case PIXEL_FORMAT_ARGB8888:
335 		/* set border color to red */
336 		color->color_r_cr = color_value;
337 		if (pipe_ctx->plane_state->layer_index > 0) {
338 			/* set border color to pink */
339 			color->color_b_cb = color_value;
340 			color->color_g_y = color_value * 0.5;
341 		}
342 		break;
343 
344 	case PIXEL_FORMAT_ARGB2101010:
345 		/* set border color to blue */
346 		color->color_b_cb = color_value;
347 		if (pipe_ctx->plane_state->layer_index > 0) {
348 			/* set border color to cyan */
349 			color->color_g_y = color_value;
350 		}
351 		break;
352 	case PIXEL_FORMAT_420BPP8:
353 		/* set border color to green */
354 		color->color_g_y = color_value;
355 		break;
356 	case PIXEL_FORMAT_420BPP10:
357 		/* set border color to yellow */
358 		color->color_g_y = color_value;
359 		color->color_r_cr = color_value;
360 		break;
361 	case PIXEL_FORMAT_FP16:
362 		/* set border color to white */
363 		color->color_r_cr = color_value;
364 		color->color_b_cb = color_value;
365 		color->color_g_y = color_value;
366 		if (pipe_ctx->plane_state->layer_index > 0) {
367 			/* set border color to orange */
368 			color->color_g_y = 0.22 * color_value;
369 			color->color_b_cb = 0;
370 		}
371 		break;
372 	default:
373 		break;
374 	}
375 }
376 
get_hdr_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)377 void get_hdr_visual_confirm_color(
378 		struct pipe_ctx *pipe_ctx,
379 		struct tg_color *color)
380 {
381 	uint32_t color_value = MAX_TG_COLOR_VALUE;
382 	bool is_sdr = false;
383 
384 	/* Determine the overscan color based on the top-most (desktop) plane's context */
385 	struct pipe_ctx *top_pipe_ctx  = pipe_ctx;
386 
387 	while (top_pipe_ctx->top_pipe != NULL)
388 		top_pipe_ctx = top_pipe_ctx->top_pipe;
389 
390 	switch (top_pipe_ctx->plane_res.scl_data.format) {
391 	case PIXEL_FORMAT_ARGB2101010:
392 		if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
393 			/* HDR10, ARGB2101010 - set border color to red */
394 			color->color_r_cr = color_value;
395 		} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
396 			/* FreeSync 2 ARGB2101010 - set border color to pink */
397 			color->color_r_cr = color_value;
398 			color->color_b_cb = color_value;
399 		} else
400 			is_sdr = true;
401 		break;
402 	case PIXEL_FORMAT_FP16:
403 		if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
404 			/* HDR10, FP16 - set border color to blue */
405 			color->color_b_cb = color_value;
406 		} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
407 			/* FreeSync 2 HDR - set border color to green */
408 			color->color_g_y = color_value;
409 		} else
410 			is_sdr = true;
411 		break;
412 	default:
413 		is_sdr = true;
414 		break;
415 	}
416 
417 	if (is_sdr) {
418 		/* SDR - set border color to Gray */
419 		color->color_r_cr = color_value/2;
420 		color->color_b_cb = color_value/2;
421 		color->color_g_y = color_value/2;
422 	}
423 }
424 
get_subvp_visual_confirm_color(struct dc * dc,struct dc_state * context,struct pipe_ctx * pipe_ctx,struct tg_color * color)425 void get_subvp_visual_confirm_color(
426 		struct dc *dc,
427 		struct dc_state *context,
428 		struct pipe_ctx *pipe_ctx,
429 		struct tg_color *color)
430 {
431 	uint32_t color_value = MAX_TG_COLOR_VALUE;
432 	bool enable_subvp = false;
433 	int i;
434 
435 	if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !context)
436 		return;
437 
438 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
439 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
440 
441 		if (pipe->stream && pipe->stream->mall_stream_config.paired_stream &&
442 		    pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
443 			/* SubVP enable - red */
444 			color->color_g_y = 0;
445 			color->color_b_cb = 0;
446 			color->color_r_cr = color_value;
447 			enable_subvp = true;
448 
449 			if (pipe_ctx->stream == pipe->stream)
450 				return;
451 			break;
452 		}
453 	}
454 
455 	if (enable_subvp && pipe_ctx->stream->mall_stream_config.type == SUBVP_NONE) {
456 		color->color_r_cr = 0;
457 		if (pipe_ctx->stream->allow_freesync == 1) {
458 			/* SubVP enable and DRR on - green */
459 			color->color_b_cb = 0;
460 			color->color_g_y = color_value;
461 		} else {
462 			/* SubVP enable and No DRR - blue */
463 			color->color_g_y = 0;
464 			color->color_b_cb = color_value;
465 		}
466 	}
467 }
468 
hwss_build_fast_sequence(struct dc * dc,struct dc_dmub_cmd * dc_dmub_cmd,unsigned int dmub_cmd_count,struct block_sequence block_sequence[],int * num_steps,struct pipe_ctx * pipe_ctx)469 void hwss_build_fast_sequence(struct dc *dc,
470 		struct dc_dmub_cmd *dc_dmub_cmd,
471 		unsigned int dmub_cmd_count,
472 		struct block_sequence block_sequence[],
473 		int *num_steps,
474 		struct pipe_ctx *pipe_ctx)
475 {
476 	struct dc_plane_state *plane = pipe_ctx->plane_state;
477 	struct dc_stream_state *stream = pipe_ctx->stream;
478 	struct dce_hwseq *hws = dc->hwseq;
479 	struct pipe_ctx *current_pipe = NULL;
480 	struct pipe_ctx *current_mpc_pipe = NULL;
481 	unsigned int i = 0;
482 
483 	*num_steps = 0; // Initialize to 0
484 
485 	if (!plane || !stream)
486 		return;
487 
488 	if (dc->hwss.subvp_pipe_control_lock_fast) {
489 		block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc;
490 		block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = true;
491 		block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx;
492 		block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST;
493 		(*num_steps)++;
494 	}
495 	if (dc->hwss.pipe_control_lock) {
496 		block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc;
497 		block_sequence[*num_steps].params.pipe_control_lock_params.lock = true;
498 		block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
499 		block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK;
500 		(*num_steps)++;
501 	}
502 
503 	for (i = 0; i < dmub_cmd_count; i++) {
504 		block_sequence[*num_steps].params.send_dmcub_cmd_params.ctx = dc->ctx;
505 		block_sequence[*num_steps].params.send_dmcub_cmd_params.cmd = &(dc_dmub_cmd[i].dmub_cmd);
506 		block_sequence[*num_steps].params.send_dmcub_cmd_params.wait_type = dc_dmub_cmd[i].wait_type;
507 		block_sequence[*num_steps].func = DMUB_SEND_DMCUB_CMD;
508 		(*num_steps)++;
509 	}
510 
511 	current_pipe = pipe_ctx;
512 	while (current_pipe) {
513 		current_mpc_pipe = current_pipe;
514 		while (current_mpc_pipe) {
515 			if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state && current_mpc_pipe->plane_state->update_flags.raw) {
516 				block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe;
517 				block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate;
518 				block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL;
519 				(*num_steps)++;
520 			}
521 			if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
522 				block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
523 				block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe;
524 				block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips;
525 				block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER;
526 				(*num_steps)++;
527 			}
528 			if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
529 				block_sequence[*num_steps].params.update_plane_addr_params.dc = dc;
530 				block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe;
531 				block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR;
532 				(*num_steps)++;
533 			}
534 
535 			if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) {
536 				block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc;
537 				block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe;
538 				block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state;
539 				block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC;
540 				(*num_steps)++;
541 			}
542 
543 			if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) {
544 				block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe;
545 				block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP;
546 				(*num_steps)++;
547 			}
548 			if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) {
549 				block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe;
550 				block_sequence[*num_steps].func = DPP_SETUP_DPP;
551 				(*num_steps)++;
552 			}
553 			if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) {
554 				block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe;
555 				block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
556 				(*num_steps)++;
557 			}
558 			if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {
559 				block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc;
560 				block_sequence[*num_steps].params.set_output_transfer_func_params.pipe_ctx = current_mpc_pipe;
561 				block_sequence[*num_steps].params.set_output_transfer_func_params.stream = current_mpc_pipe->stream;
562 				block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC;
563 				(*num_steps)++;
564 			}
565 
566 			if (current_mpc_pipe->stream->update_flags.bits.out_csc) {
567 				block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpc = dc->res_pool->mpc;
568 				block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst;
569 				block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.power_on = true;
570 				block_sequence[*num_steps].func = MPC_POWER_ON_MPC_MEM_PWR;
571 				(*num_steps)++;
572 
573 				if (current_mpc_pipe->stream->csc_color_matrix.enable_adjustment == true) {
574 					block_sequence[*num_steps].params.set_output_csc_params.mpc = dc->res_pool->mpc;
575 					block_sequence[*num_steps].params.set_output_csc_params.opp_id = current_mpc_pipe->stream_res.opp->inst;
576 					block_sequence[*num_steps].params.set_output_csc_params.regval = current_mpc_pipe->stream->csc_color_matrix.matrix;
577 					block_sequence[*num_steps].params.set_output_csc_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
578 					block_sequence[*num_steps].func = MPC_SET_OUTPUT_CSC;
579 					(*num_steps)++;
580 				} else {
581 					block_sequence[*num_steps].params.set_ocsc_default_params.mpc = dc->res_pool->mpc;
582 					block_sequence[*num_steps].params.set_ocsc_default_params.opp_id = current_mpc_pipe->stream_res.opp->inst;
583 					block_sequence[*num_steps].params.set_ocsc_default_params.color_space = current_mpc_pipe->stream->output_color_space;
584 					block_sequence[*num_steps].params.set_ocsc_default_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
585 					block_sequence[*num_steps].func = MPC_SET_OCSC_DEFAULT;
586 					(*num_steps)++;
587 				}
588 			}
589 			current_mpc_pipe = current_mpc_pipe->bottom_pipe;
590 		}
591 		current_pipe = current_pipe->next_odm_pipe;
592 	}
593 
594 	if (dc->hwss.pipe_control_lock) {
595 		block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc;
596 		block_sequence[*num_steps].params.pipe_control_lock_params.lock = false;
597 		block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
598 		block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK;
599 		(*num_steps)++;
600 	}
601 	if (dc->hwss.subvp_pipe_control_lock_fast) {
602 		block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc;
603 		block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false;
604 		block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx;
605 		block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST;
606 		(*num_steps)++;
607 	}
608 
609 	current_pipe = pipe_ctx;
610 	while (current_pipe) {
611 		current_mpc_pipe = current_pipe;
612 
613 		while (current_mpc_pipe) {
614 			if (!current_mpc_pipe->bottom_pipe && !current_mpc_pipe->next_odm_pipe &&
615 					current_mpc_pipe->stream && current_mpc_pipe->plane_state &&
616 					current_mpc_pipe->plane_state->update_flags.bits.addr_update &&
617 					!current_mpc_pipe->plane_state->skip_manual_trigger) {
618 				block_sequence[*num_steps].params.program_manual_trigger_params.pipe_ctx = current_mpc_pipe;
619 				block_sequence[*num_steps].func = OPTC_PROGRAM_MANUAL_TRIGGER;
620 				(*num_steps)++;
621 			}
622 			current_mpc_pipe = current_mpc_pipe->bottom_pipe;
623 		}
624 		current_pipe = current_pipe->next_odm_pipe;
625 	}
626 }
627 
hwss_execute_sequence(struct dc * dc,struct block_sequence block_sequence[],int num_steps)628 void hwss_execute_sequence(struct dc *dc,
629 		struct block_sequence block_sequence[],
630 		int num_steps)
631 {
632 	unsigned int i;
633 	union block_sequence_params *params;
634 	struct dce_hwseq *hws = dc->hwseq;
635 
636 	for (i = 0; i < num_steps; i++) {
637 		params = &(block_sequence[i].params);
638 		switch (block_sequence[i].func) {
639 
640 		case DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST:
641 			dc->hwss.subvp_pipe_control_lock_fast(params);
642 			break;
643 		case OPTC_PIPE_CONTROL_LOCK:
644 			dc->hwss.pipe_control_lock(params->pipe_control_lock_params.dc,
645 					params->pipe_control_lock_params.pipe_ctx,
646 					params->pipe_control_lock_params.lock);
647 			break;
648 		case HUBP_SET_FLIP_CONTROL_GSL:
649 			dc->hwss.set_flip_control_gsl(params->set_flip_control_gsl_params.pipe_ctx,
650 					params->set_flip_control_gsl_params.flip_immediate);
651 			break;
652 		case HUBP_PROGRAM_TRIPLEBUFFER:
653 			dc->hwss.program_triplebuffer(params->program_triplebuffer_params.dc,
654 					params->program_triplebuffer_params.pipe_ctx,
655 					params->program_triplebuffer_params.enableTripleBuffer);
656 			break;
657 		case HUBP_UPDATE_PLANE_ADDR:
658 			dc->hwss.update_plane_addr(params->update_plane_addr_params.dc,
659 					params->update_plane_addr_params.pipe_ctx);
660 			break;
661 		case DPP_SET_INPUT_TRANSFER_FUNC:
662 			hws->funcs.set_input_transfer_func(params->set_input_transfer_func_params.dc,
663 					params->set_input_transfer_func_params.pipe_ctx,
664 					params->set_input_transfer_func_params.plane_state);
665 			break;
666 		case DPP_PROGRAM_GAMUT_REMAP:
667 			dc->hwss.program_gamut_remap(params->program_gamut_remap_params.pipe_ctx);
668 			break;
669 		case DPP_SETUP_DPP:
670 			hwss_setup_dpp(params);
671 			break;
672 		case DPP_PROGRAM_BIAS_AND_SCALE:
673 			hwss_program_bias_and_scale(params);
674 			break;
675 		case OPTC_PROGRAM_MANUAL_TRIGGER:
676 			hwss_program_manual_trigger(params);
677 			break;
678 		case DPP_SET_OUTPUT_TRANSFER_FUNC:
679 			hws->funcs.set_output_transfer_func(params->set_output_transfer_func_params.dc,
680 					params->set_output_transfer_func_params.pipe_ctx,
681 					params->set_output_transfer_func_params.stream);
682 			break;
683 		case MPC_UPDATE_VISUAL_CONFIRM:
684 			dc->hwss.update_visual_confirm_color(params->update_visual_confirm_params.dc,
685 					params->update_visual_confirm_params.pipe_ctx,
686 					params->update_visual_confirm_params.mpcc_id);
687 			break;
688 		case MPC_POWER_ON_MPC_MEM_PWR:
689 			hwss_power_on_mpc_mem_pwr(params);
690 			break;
691 		case MPC_SET_OUTPUT_CSC:
692 			hwss_set_output_csc(params);
693 			break;
694 		case MPC_SET_OCSC_DEFAULT:
695 			hwss_set_ocsc_default(params);
696 			break;
697 		case DMUB_SEND_DMCUB_CMD:
698 			hwss_send_dmcub_cmd(params);
699 			break;
700 		default:
701 			ASSERT(false);
702 			break;
703 		}
704 	}
705 }
706 
hwss_send_dmcub_cmd(union block_sequence_params * params)707 void hwss_send_dmcub_cmd(union block_sequence_params *params)
708 {
709 	struct dc_context *ctx = params->send_dmcub_cmd_params.ctx;
710 	union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd;
711 	enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type;
712 
713 	dm_execute_dmub_cmd(ctx, cmd, wait_type);
714 }
715 
hwss_program_manual_trigger(union block_sequence_params * params)716 void hwss_program_manual_trigger(union block_sequence_params *params)
717 {
718 	struct pipe_ctx *pipe_ctx = params->program_manual_trigger_params.pipe_ctx;
719 
720 	if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger)
721 		pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
722 }
723 
hwss_setup_dpp(union block_sequence_params * params)724 void hwss_setup_dpp(union block_sequence_params *params)
725 {
726 	struct pipe_ctx *pipe_ctx = params->setup_dpp_params.pipe_ctx;
727 	struct dpp *dpp = pipe_ctx->plane_res.dpp;
728 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
729 
730 	if (dpp && dpp->funcs->dpp_setup) {
731 		// program the input csc
732 		dpp->funcs->dpp_setup(dpp,
733 				plane_state->format,
734 				EXPANSION_MODE_ZERO,
735 				plane_state->input_csc_color_matrix,
736 				plane_state->color_space,
737 				NULL);
738 	}
739 }
740 
hwss_program_bias_and_scale(union block_sequence_params * params)741 void hwss_program_bias_and_scale(union block_sequence_params *params)
742 {
743 	struct pipe_ctx *pipe_ctx = params->program_bias_and_scale_params.pipe_ctx;
744 	struct dpp *dpp = pipe_ctx->plane_res.dpp;
745 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
746 	struct dc_bias_and_scale bns_params = {0};
747 
748 	//TODO :for CNVC set scale and bias registers if necessary
749 	build_prescale_params(&bns_params, plane_state);
750 	if (dpp->funcs->dpp_program_bias_and_scale)
751 		dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
752 }
753 
hwss_power_on_mpc_mem_pwr(union block_sequence_params * params)754 void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params)
755 {
756 	struct mpc *mpc = params->power_on_mpc_mem_pwr_params.mpc;
757 	int mpcc_id = params->power_on_mpc_mem_pwr_params.mpcc_id;
758 	bool power_on = params->power_on_mpc_mem_pwr_params.power_on;
759 
760 	if (mpc->funcs->power_on_mpc_mem_pwr)
761 		mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, power_on);
762 }
763 
hwss_set_output_csc(union block_sequence_params * params)764 void hwss_set_output_csc(union block_sequence_params *params)
765 {
766 	struct mpc *mpc = params->set_output_csc_params.mpc;
767 	int opp_id = params->set_output_csc_params.opp_id;
768 	const uint16_t *matrix = params->set_output_csc_params.regval;
769 	enum mpc_output_csc_mode ocsc_mode = params->set_output_csc_params.ocsc_mode;
770 
771 	if (mpc->funcs->set_output_csc != NULL)
772 		mpc->funcs->set_output_csc(mpc,
773 				opp_id,
774 				matrix,
775 				ocsc_mode);
776 }
777 
hwss_set_ocsc_default(union block_sequence_params * params)778 void hwss_set_ocsc_default(union block_sequence_params *params)
779 {
780 	struct mpc *mpc = params->set_ocsc_default_params.mpc;
781 	int opp_id = params->set_ocsc_default_params.opp_id;
782 	enum dc_color_space colorspace = params->set_ocsc_default_params.color_space;
783 	enum mpc_output_csc_mode ocsc_mode = params->set_ocsc_default_params.ocsc_mode;
784 
785 	if (mpc->funcs->set_ocsc_default != NULL)
786 		mpc->funcs->set_ocsc_default(mpc,
787 				opp_id,
788 				colorspace,
789 				ocsc_mode);
790 }
791 
get_mclk_switch_visual_confirm_color(struct dc * dc,struct dc_state * context,struct pipe_ctx * pipe_ctx,struct tg_color * color)792 void get_mclk_switch_visual_confirm_color(
793 		struct dc *dc,
794 		struct dc_state *context,
795 		struct pipe_ctx *pipe_ctx,
796 		struct tg_color *color)
797 {
798 	uint32_t color_value = MAX_TG_COLOR_VALUE;
799 	struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
800 
801 	if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba || !context)
802 		return;
803 
804 	if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] !=
805 			dm_dram_clock_change_unsupported) {
806 		/* MCLK switching is supported */
807 		if (!pipe_ctx->has_vactive_margin) {
808 			/* In Vblank - yellow */
809 			color->color_r_cr = color_value;
810 			color->color_g_y = color_value;
811 
812 			if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
813 				/* FPO + Vblank - cyan */
814 				color->color_r_cr = 0;
815 				color->color_g_y  = color_value;
816 				color->color_b_cb = color_value;
817 			}
818 		} else {
819 			/* In Vactive - pink */
820 			color->color_r_cr = color_value;
821 			color->color_b_cb = color_value;
822 		}
823 		/* SubVP */
824 		get_subvp_visual_confirm_color(dc, context, pipe_ctx, color);
825 	}
826 }
827 
get_surface_tile_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)828 void get_surface_tile_visual_confirm_color(
829 		struct pipe_ctx *pipe_ctx,
830 		struct tg_color *color)
831 {
832 	uint32_t color_value = MAX_TG_COLOR_VALUE;
833 	/* Determine the overscan color based on the bottom-most plane's context */
834 	struct pipe_ctx *bottom_pipe_ctx  = pipe_ctx;
835 
836 	while (bottom_pipe_ctx->bottom_pipe != NULL)
837 		bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe;
838 
839 	switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) {
840 	case DC_SW_LINEAR:
841 		/* LINEAR Surface - set border color to red */
842 		color->color_r_cr = color_value;
843 		break;
844 	default:
845 		break;
846 	}
847 }
848