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 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