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 #include "resource.h"
33 #include "dc_dmub_srv.h"
34 #include "dc_state_priv.h"
35
36 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
37 #define MAX_NUM_MCACHE 8
38
39 /* used as index in array of black_color_format */
40 enum black_color_format {
41 BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0,
42 BLACK_COLOR_FORMAT_RGB_LIMITED,
43 BLACK_COLOR_FORMAT_YUV_TV,
44 BLACK_COLOR_FORMAT_YUV_CV,
45 BLACK_COLOR_FORMAT_YUV_SUPER_AA,
46 BLACK_COLOR_FORMAT_DEBUG,
47 };
48
49 enum dc_color_space_type {
50 COLOR_SPACE_RGB_TYPE,
51 COLOR_SPACE_RGB_LIMITED_TYPE,
52 COLOR_SPACE_YCBCR601_TYPE,
53 COLOR_SPACE_YCBCR709_TYPE,
54 COLOR_SPACE_YCBCR2020_TYPE,
55 COLOR_SPACE_YCBCR601_LIMITED_TYPE,
56 COLOR_SPACE_YCBCR709_LIMITED_TYPE,
57 COLOR_SPACE_YCBCR709_BLACK_TYPE,
58 };
59
60 static const struct tg_color black_color_format[] = {
61 /* BlackColorFormat_RGB_FullRange */
62 {0, 0, 0},
63 /* BlackColorFormat_RGB_Limited */
64 {0x40, 0x40, 0x40},
65 /* BlackColorFormat_YUV_TV */
66 {0x200, 0x40, 0x200},
67 /* BlackColorFormat_YUV_CV */
68 {0x1f4, 0x40, 0x1f4},
69 /* BlackColorFormat_YUV_SuperAA */
70 {0x1a2, 0x20, 0x1a2},
71 /* visual confirm debug */
72 {0xff, 0xff, 0},
73 };
74
75 struct out_csc_color_matrix_type {
76 enum dc_color_space_type color_space_type;
77 uint16_t regval[12];
78 };
79
80 static const struct out_csc_color_matrix_type output_csc_matrix[] = {
81 { COLOR_SPACE_RGB_TYPE,
82 { 0x2000, 0, 0, 0,
83 0, 0x2000, 0, 0,
84 0, 0, 0x2000, 0} },
85 { COLOR_SPACE_RGB_LIMITED_TYPE,
86 { 0x1B67, 0, 0, 0x201,
87 0, 0x1B67, 0, 0x201,
88 0, 0, 0x1B67, 0x201} },
89 { COLOR_SPACE_YCBCR601_TYPE,
90 { 0xE04, 0xF444, 0xFDB9, 0x1004,
91 0x831, 0x1016, 0x320, 0x201,
92 0xFB45, 0xF6B7, 0xE04, 0x1004} },
93 { COLOR_SPACE_YCBCR709_TYPE,
94 { 0xE04, 0xF345, 0xFEB7, 0x1004,
95 0x5D3, 0x1399, 0x1FA, 0x201,
96 0xFCCA, 0xF533, 0xE04, 0x1004} },
97 /* TODO: correct values below */
98 { COLOR_SPACE_YCBCR601_LIMITED_TYPE,
99 { 0xE00, 0xF447, 0xFDB9, 0x1000,
100 0x991, 0x12C9, 0x3A6, 0x200,
101 0xFB47, 0xF6B9, 0xE00, 0x1000} },
102 { COLOR_SPACE_YCBCR709_LIMITED_TYPE,
103 { 0xE00, 0xF349, 0xFEB7, 0x1000,
104 0x6CE, 0x16E3, 0x24F, 0x200,
105 0xFCCB, 0xF535, 0xE00, 0x1000} },
106 { COLOR_SPACE_YCBCR2020_TYPE,
107 { 0x1000, 0xF149, 0xFEB7, 0x1004,
108 0x0868, 0x15B2, 0x01E6, 0x201,
109 0xFB88, 0xF478, 0x1000, 0x1004} },
110 { COLOR_SPACE_YCBCR709_BLACK_TYPE,
111 { 0x0000, 0x0000, 0x0000, 0x1000,
112 0x0000, 0x0000, 0x0000, 0x0200,
113 0x0000, 0x0000, 0x0000, 0x1000} },
114 };
115
is_rgb_type(enum dc_color_space color_space)116 static bool is_rgb_type(
117 enum dc_color_space color_space)
118 {
119 bool ret = false;
120
121 if (color_space == COLOR_SPACE_SRGB ||
122 color_space == COLOR_SPACE_XR_RGB ||
123 color_space == COLOR_SPACE_MSREF_SCRGB ||
124 color_space == COLOR_SPACE_2020_RGB_FULLRANGE ||
125 color_space == COLOR_SPACE_ADOBERGB ||
126 color_space == COLOR_SPACE_DCIP3 ||
127 color_space == COLOR_SPACE_DOLBYVISION)
128 ret = true;
129 return ret;
130 }
131
is_rgb_limited_type(enum dc_color_space color_space)132 static bool is_rgb_limited_type(
133 enum dc_color_space color_space)
134 {
135 bool ret = false;
136
137 if (color_space == COLOR_SPACE_SRGB_LIMITED ||
138 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
139 ret = true;
140 return ret;
141 }
142
is_ycbcr601_type(enum dc_color_space color_space)143 static bool is_ycbcr601_type(
144 enum dc_color_space color_space)
145 {
146 bool ret = false;
147
148 if (color_space == COLOR_SPACE_YCBCR601 ||
149 color_space == COLOR_SPACE_XV_YCC_601)
150 ret = true;
151 return ret;
152 }
153
is_ycbcr601_limited_type(enum dc_color_space color_space)154 static bool is_ycbcr601_limited_type(
155 enum dc_color_space color_space)
156 {
157 bool ret = false;
158
159 if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
160 ret = true;
161 return ret;
162 }
163
is_ycbcr709_type(enum dc_color_space color_space)164 static bool is_ycbcr709_type(
165 enum dc_color_space color_space)
166 {
167 bool ret = false;
168
169 if (color_space == COLOR_SPACE_YCBCR709 ||
170 color_space == COLOR_SPACE_XV_YCC_709)
171 ret = true;
172 return ret;
173 }
174
is_ycbcr2020_type(enum dc_color_space color_space)175 static bool is_ycbcr2020_type(
176 enum dc_color_space color_space)
177 {
178 bool ret = false;
179
180 if (color_space == COLOR_SPACE_2020_YCBCR_LIMITED || color_space == COLOR_SPACE_2020_YCBCR_FULL)
181 ret = true;
182 return ret;
183 }
184
is_ycbcr709_limited_type(enum dc_color_space color_space)185 static bool is_ycbcr709_limited_type(
186 enum dc_color_space color_space)
187 {
188 bool ret = false;
189
190 if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
191 ret = true;
192 return ret;
193 }
194
get_color_space_type(enum dc_color_space color_space)195 static enum dc_color_space_type get_color_space_type(enum dc_color_space color_space)
196 {
197 enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE;
198
199 if (is_rgb_type(color_space))
200 type = COLOR_SPACE_RGB_TYPE;
201 else if (is_rgb_limited_type(color_space))
202 type = COLOR_SPACE_RGB_LIMITED_TYPE;
203 else if (is_ycbcr601_type(color_space))
204 type = COLOR_SPACE_YCBCR601_TYPE;
205 else if (is_ycbcr709_type(color_space))
206 type = COLOR_SPACE_YCBCR709_TYPE;
207 else if (is_ycbcr601_limited_type(color_space))
208 type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
209 else if (is_ycbcr709_limited_type(color_space))
210 type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
211 else if (is_ycbcr2020_type(color_space))
212 type = COLOR_SPACE_YCBCR2020_TYPE;
213 else if (color_space == COLOR_SPACE_YCBCR709)
214 type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
215 else if (color_space == COLOR_SPACE_YCBCR709_BLACK)
216 type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
217 return type;
218 }
219
find_color_matrix(enum dc_color_space color_space,uint32_t * array_size)220 const uint16_t *find_color_matrix(enum dc_color_space color_space,
221 uint32_t *array_size)
222 {
223 int i;
224 enum dc_color_space_type type;
225 const uint16_t *val = NULL;
226 int arr_size = NUM_ELEMENTS(output_csc_matrix);
227
228 type = get_color_space_type(color_space);
229 for (i = 0; i < arr_size; i++)
230 if (output_csc_matrix[i].color_space_type == type) {
231 val = output_csc_matrix[i].regval;
232 *array_size = 12;
233 break;
234 }
235
236 return val;
237 }
238
239
color_space_to_black_color(const struct dc * dc,enum dc_color_space colorspace,struct tg_color * black_color)240 void color_space_to_black_color(
241 const struct dc *dc,
242 enum dc_color_space colorspace,
243 struct tg_color *black_color)
244 {
245 switch (colorspace) {
246 case COLOR_SPACE_YCBCR601:
247 case COLOR_SPACE_YCBCR709:
248 case COLOR_SPACE_YCBCR709_BLACK:
249 case COLOR_SPACE_YCBCR601_LIMITED:
250 case COLOR_SPACE_YCBCR709_LIMITED:
251 case COLOR_SPACE_2020_YCBCR_LIMITED:
252 case COLOR_SPACE_2020_YCBCR_FULL:
253 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
254 break;
255
256 case COLOR_SPACE_SRGB_LIMITED:
257 *black_color =
258 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
259 break;
260
261 /**
262 * Remove default and add case for all color space
263 * so when we forget to add new color space
264 * compiler will give a warning
265 */
266 case COLOR_SPACE_UNKNOWN:
267 case COLOR_SPACE_SRGB:
268 case COLOR_SPACE_XR_RGB:
269 case COLOR_SPACE_MSREF_SCRGB:
270 case COLOR_SPACE_XV_YCC_709:
271 case COLOR_SPACE_XV_YCC_601:
272 case COLOR_SPACE_2020_RGB_FULLRANGE:
273 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
274 case COLOR_SPACE_ADOBERGB:
275 case COLOR_SPACE_DCIP3:
276 case COLOR_SPACE_DISPLAYNATIVE:
277 case COLOR_SPACE_DOLBYVISION:
278 case COLOR_SPACE_APPCTRL:
279 case COLOR_SPACE_CUSTOMPOINTS:
280 /* fefault is sRGB black (full range). */
281 *black_color =
282 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
283 /* default is sRGB black 0. */
284 break;
285 }
286 }
287
hwss_wait_for_blank_complete(struct timing_generator * tg)288 bool hwss_wait_for_blank_complete(
289 struct timing_generator *tg)
290 {
291 int counter;
292
293 /* Not applicable if the pipe is not primary, save 300ms of boot time */
294 if (!tg->funcs->is_blanked)
295 return true;
296 for (counter = 0; counter < 100; counter++) {
297 if (tg->funcs->is_blanked(tg))
298 break;
299
300 msleep(1);
301 }
302
303 if (counter == 100) {
304 dm_error("DC: failed to blank crtc!\n");
305 return false;
306 }
307
308 return true;
309 }
310
get_mpctree_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)311 void get_mpctree_visual_confirm_color(
312 struct pipe_ctx *pipe_ctx,
313 struct tg_color *color)
314 {
315 const struct tg_color pipe_colors[6] = {
316 {MAX_TG_COLOR_VALUE, 0, 0}, /* red */
317 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */
318 {0, MAX_TG_COLOR_VALUE, 0}, /* green */
319 {0, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* cyan */
320 {0, 0, MAX_TG_COLOR_VALUE}, /* blue */
321 {MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, /* magenta */
322 };
323
324 struct pipe_ctx *top_pipe = pipe_ctx;
325
326 while (top_pipe->top_pipe)
327 top_pipe = top_pipe->top_pipe;
328
329 *color = pipe_colors[top_pipe->pipe_idx];
330 }
331
get_surface_visual_confirm_color(const struct pipe_ctx * pipe_ctx,struct tg_color * color)332 void get_surface_visual_confirm_color(
333 const struct pipe_ctx *pipe_ctx,
334 struct tg_color *color)
335 {
336 uint32_t color_value = MAX_TG_COLOR_VALUE;
337
338 switch (pipe_ctx->plane_res.scl_data.format) {
339 case PIXEL_FORMAT_ARGB8888:
340 /* set border color to red */
341 color->color_r_cr = color_value;
342 if (pipe_ctx->plane_state->layer_index > 0) {
343 /* set border color to pink */
344 color->color_b_cb = color_value;
345 color->color_g_y = color_value * 0.5;
346 }
347 break;
348
349 case PIXEL_FORMAT_ARGB2101010:
350 /* set border color to blue */
351 color->color_b_cb = color_value;
352 if (pipe_ctx->plane_state->layer_index > 0) {
353 /* set border color to cyan */
354 color->color_g_y = color_value;
355 }
356 break;
357 case PIXEL_FORMAT_420BPP8:
358 /* set border color to green */
359 color->color_g_y = color_value;
360 break;
361 case PIXEL_FORMAT_420BPP10:
362 /* set border color to yellow */
363 color->color_g_y = color_value;
364 color->color_r_cr = color_value;
365 break;
366 case PIXEL_FORMAT_FP16:
367 /* set border color to white */
368 color->color_r_cr = color_value;
369 color->color_b_cb = color_value;
370 color->color_g_y = color_value;
371 if (pipe_ctx->plane_state->layer_index > 0) {
372 /* set border color to orange */
373 color->color_g_y = 0.22 * color_value;
374 color->color_b_cb = 0;
375 }
376 break;
377 default:
378 break;
379 }
380 }
381
get_hdr_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)382 void get_hdr_visual_confirm_color(
383 struct pipe_ctx *pipe_ctx,
384 struct tg_color *color)
385 {
386 uint32_t color_value = MAX_TG_COLOR_VALUE;
387 bool is_sdr = false;
388
389 /* Determine the overscan color based on the top-most (desktop) plane's context */
390 struct pipe_ctx *top_pipe_ctx = pipe_ctx;
391
392 while (top_pipe_ctx->top_pipe != NULL)
393 top_pipe_ctx = top_pipe_ctx->top_pipe;
394
395 switch (top_pipe_ctx->plane_res.scl_data.format) {
396 case PIXEL_FORMAT_ARGB2101010:
397 if (top_pipe_ctx->stream->out_transfer_func.tf == TRANSFER_FUNCTION_PQ) {
398 /* HDR10, ARGB2101010 - set border color to red */
399 color->color_r_cr = color_value;
400 } else if (top_pipe_ctx->stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) {
401 /* FreeSync 2 ARGB2101010 - set border color to pink */
402 color->color_r_cr = color_value;
403 color->color_b_cb = color_value;
404 } else
405 is_sdr = true;
406 break;
407 case PIXEL_FORMAT_FP16:
408 if (top_pipe_ctx->stream->out_transfer_func.tf == TRANSFER_FUNCTION_PQ) {
409 /* HDR10, FP16 - set border color to blue */
410 color->color_b_cb = color_value;
411 } else if (top_pipe_ctx->stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) {
412 /* FreeSync 2 HDR - set border color to green */
413 color->color_g_y = color_value;
414 } else
415 is_sdr = true;
416 break;
417 default:
418 is_sdr = true;
419 break;
420 }
421
422 if (is_sdr) {
423 /* SDR - set border color to Gray */
424 color->color_r_cr = color_value/2;
425 color->color_b_cb = color_value/2;
426 color->color_g_y = color_value/2;
427 }
428 }
429
430 /* Visual Confirm color definition for VABC */
get_vabc_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)431 void get_vabc_visual_confirm_color(
432 struct pipe_ctx *pipe_ctx,
433 struct tg_color *color)
434 {
435 uint32_t color_value = MAX_TG_COLOR_VALUE;
436 struct dc_link *edp_link = NULL;
437
438 if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link) {
439 if (pipe_ctx->stream->link->connector_signal == SIGNAL_TYPE_EDP)
440 edp_link = pipe_ctx->stream->link;
441 }
442
443 if (edp_link) {
444 switch (edp_link->backlight_control_type) {
445 case BACKLIGHT_CONTROL_PWM:
446 color->color_r_cr = color_value;
447 color->color_g_y = 0;
448 color->color_b_cb = 0;
449 break;
450 case BACKLIGHT_CONTROL_AMD_AUX:
451 color->color_r_cr = 0;
452 color->color_g_y = color_value;
453 color->color_b_cb = 0;
454 break;
455 case BACKLIGHT_CONTROL_VESA_AUX:
456 color->color_r_cr = 0;
457 color->color_g_y = 0;
458 color->color_b_cb = color_value;
459 break;
460 }
461 } else {
462 color->color_r_cr = 0;
463 color->color_g_y = 0;
464 color->color_b_cb = 0;
465 }
466 }
467
get_subvp_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)468 void get_subvp_visual_confirm_color(
469 struct pipe_ctx *pipe_ctx,
470 struct tg_color *color)
471 {
472 uint32_t color_value = MAX_TG_COLOR_VALUE;
473 if (pipe_ctx) {
474 switch (pipe_ctx->p_state_type) {
475 case P_STATE_SUB_VP:
476 color->color_r_cr = color_value;
477 color->color_g_y = 0;
478 color->color_b_cb = 0;
479 break;
480 case P_STATE_DRR_SUB_VP:
481 color->color_r_cr = 0;
482 color->color_g_y = color_value;
483 color->color_b_cb = 0;
484 break;
485 case P_STATE_V_BLANK_SUB_VP:
486 color->color_r_cr = 0;
487 color->color_g_y = 0;
488 color->color_b_cb = color_value;
489 break;
490 default:
491 break;
492 }
493 }
494 }
495
get_mclk_switch_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)496 void get_mclk_switch_visual_confirm_color(
497 struct pipe_ctx *pipe_ctx,
498 struct tg_color *color)
499 {
500 uint32_t color_value = MAX_TG_COLOR_VALUE;
501
502 if (pipe_ctx) {
503 switch (pipe_ctx->p_state_type) {
504 case P_STATE_V_BLANK:
505 color->color_r_cr = color_value;
506 color->color_g_y = color_value;
507 color->color_b_cb = 0;
508 break;
509 case P_STATE_FPO:
510 color->color_r_cr = 0;
511 color->color_g_y = color_value;
512 color->color_b_cb = color_value;
513 break;
514 case P_STATE_V_ACTIVE:
515 color->color_r_cr = color_value;
516 color->color_g_y = 0;
517 color->color_b_cb = color_value;
518 break;
519 case P_STATE_SUB_VP:
520 color->color_r_cr = color_value;
521 color->color_g_y = 0;
522 color->color_b_cb = 0;
523 break;
524 case P_STATE_DRR_SUB_VP:
525 color->color_r_cr = 0;
526 color->color_g_y = color_value;
527 color->color_b_cb = 0;
528 break;
529 case P_STATE_V_BLANK_SUB_VP:
530 color->color_r_cr = 0;
531 color->color_g_y = 0;
532 color->color_b_cb = color_value;
533 break;
534 default:
535 break;
536 }
537 }
538 }
539
get_cursor_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)540 void get_cursor_visual_confirm_color(
541 struct pipe_ctx *pipe_ctx,
542 struct tg_color *color)
543 {
544 uint32_t color_value = MAX_TG_COLOR_VALUE;
545
546 if (pipe_ctx->stream && pipe_ctx->stream->cursor_position.enable) {
547 color->color_r_cr = color_value;
548 color->color_g_y = 0;
549 color->color_b_cb = 0;
550 } else {
551 color->color_r_cr = 0;
552 color->color_g_y = 0;
553 color->color_b_cb = color_value;
554 }
555 }
556
get_dcc_visual_confirm_color(struct dc * dc,struct pipe_ctx * pipe_ctx,struct tg_color * color)557 void get_dcc_visual_confirm_color(
558 struct dc *dc,
559 struct pipe_ctx *pipe_ctx,
560 struct tg_color *color)
561 {
562 const uint32_t MCACHE_ID_UNASSIGNED = 0xF;
563
564 if (!pipe_ctx->plane_state->dcc.enable) {
565 color->color_r_cr = 0; /* black - DCC disabled */
566 color->color_g_y = 0;
567 color->color_b_cb = 0;
568 return;
569 }
570
571 if (dc->ctx->dce_version < DCN_VERSION_4_01) {
572 color->color_r_cr = MAX_TG_COLOR_VALUE; /* red - DCC enabled */
573 color->color_g_y = 0;
574 color->color_b_cb = 0;
575 return;
576 }
577
578 uint32_t first_id = pipe_ctx->mcache_regs.main.p0.mcache_id_first;
579 uint32_t second_id = pipe_ctx->mcache_regs.main.p0.mcache_id_second;
580
581 if (first_id != MCACHE_ID_UNASSIGNED && second_id != MCACHE_ID_UNASSIGNED && first_id != second_id) {
582 color->color_r_cr = MAX_TG_COLOR_VALUE/2; /* grey - 2 mcache */
583 color->color_g_y = MAX_TG_COLOR_VALUE/2;
584 color->color_b_cb = MAX_TG_COLOR_VALUE/2;
585 }
586
587 else if (first_id != MCACHE_ID_UNASSIGNED || second_id != MCACHE_ID_UNASSIGNED) {
588 const struct tg_color id_colors[MAX_NUM_MCACHE] = {
589 {0, MAX_TG_COLOR_VALUE, 0}, /* green */
590 {0, 0, MAX_TG_COLOR_VALUE}, /* blue */
591 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */
592 {MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, /* magenta */
593 {0, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* cyan */
594 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* white */
595 {MAX_TG_COLOR_VALUE/2, 0, 0}, /* dark red */
596 {0, MAX_TG_COLOR_VALUE/2, 0}, /* dark green */
597 };
598
599 uint32_t assigned_id = (first_id != MCACHE_ID_UNASSIGNED) ? first_id : second_id;
600 *color = id_colors[assigned_id];
601 }
602 }
603
set_p_state_switch_method(struct dc * dc,struct dc_state * context,struct pipe_ctx * pipe_ctx)604 void set_p_state_switch_method(
605 struct dc *dc,
606 struct dc_state *context,
607 struct pipe_ctx *pipe_ctx)
608 {
609 struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
610 bool enable_subvp;
611
612 if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba)
613 return;
614
615 pipe_ctx->p_state_type = P_STATE_UNKNOWN;
616 if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] !=
617 dm_dram_clock_change_unsupported) {
618 /* MCLK switching is supported */
619 if (!pipe_ctx->has_vactive_margin) {
620 /* In Vblank - yellow */
621 pipe_ctx->p_state_type = P_STATE_V_BLANK;
622
623 if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
624 /* FPO + Vblank - cyan */
625 pipe_ctx->p_state_type = P_STATE_FPO;
626 }
627 } else {
628 /* In Vactive - pink */
629 pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
630 }
631
632 /* SubVP */
633 enable_subvp = false;
634
635 for (int i = 0; i < dc->res_pool->pipe_count; i++) {
636 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
637
638 if (pipe->stream && dc_state_get_paired_subvp_stream(context, pipe->stream) &&
639 dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_MAIN) {
640 /* SubVP enable - red */
641 pipe_ctx->p_state_type = P_STATE_SUB_VP;
642 enable_subvp = true;
643
644 if (pipe_ctx->stream == pipe->stream)
645 return;
646 break;
647 }
648 }
649
650 if (enable_subvp && dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_NONE) {
651 if (pipe_ctx->stream->allow_freesync == 1) {
652 /* SubVP enable and DRR on - green */
653 pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
654 } else {
655 /* SubVP enable and No DRR - blue */
656 pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
657 }
658 }
659 }
660 }
661
set_drr_and_clear_adjust_pending(struct pipe_ctx * pipe_ctx,struct dc_stream_state * stream,struct drr_params * params)662 void set_drr_and_clear_adjust_pending(
663 struct pipe_ctx *pipe_ctx,
664 struct dc_stream_state *stream,
665 struct drr_params *params)
666 {
667 /* params can be null.*/
668 if (pipe_ctx && pipe_ctx->stream_res.tg &&
669 pipe_ctx->stream_res.tg->funcs->set_drr)
670 pipe_ctx->stream_res.tg->funcs->set_drr(
671 pipe_ctx->stream_res.tg, params);
672
673 if (stream)
674 stream->adjust.timing_adjust_pending = false;
675 }
676
get_fams2_visual_confirm_color(struct dc * dc,struct dc_state * context,struct pipe_ctx * pipe_ctx,struct tg_color * color)677 void get_fams2_visual_confirm_color(
678 struct dc *dc,
679 struct dc_state *context,
680 struct pipe_ctx *pipe_ctx,
681 struct tg_color *color)
682 {
683 uint32_t color_value = MAX_TG_COLOR_VALUE;
684
685 if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !context || !dc->debug.fams2_config.bits.enable)
686 return;
687
688 /* driver only handles visual confirm when FAMS2 is disabled */
689 if (!dc_state_is_fams2_in_use(dc, context)) {
690 /* when FAMS2 is disabled, all pipes are grey */
691 color->color_g_y = color_value / 2;
692 color->color_b_cb = color_value / 2;
693 color->color_r_cr = color_value / 2;
694 }
695 }
696
hwss_build_fast_sequence(struct dc * dc,struct dc_dmub_cmd * dc_dmub_cmd,unsigned int dmub_cmd_count,struct block_sequence block_sequence[],unsigned int * num_steps,struct pipe_ctx * pipe_ctx,struct dc_stream_status * stream_status,struct dc_state * context)697 void hwss_build_fast_sequence(struct dc *dc,
698 struct dc_dmub_cmd *dc_dmub_cmd,
699 unsigned int dmub_cmd_count,
700 struct block_sequence block_sequence[],
701 unsigned int *num_steps,
702 struct pipe_ctx *pipe_ctx,
703 struct dc_stream_status *stream_status,
704 struct dc_state *context)
705 {
706 struct dc_plane_state *plane = pipe_ctx->plane_state;
707 struct dc_stream_state *stream = pipe_ctx->stream;
708 struct dce_hwseq *hws = dc->hwseq;
709 struct pipe_ctx *current_pipe = NULL;
710 struct pipe_ctx *current_mpc_pipe = NULL;
711 unsigned int i = 0;
712
713 *num_steps = 0; // Initialize to 0
714
715 if (!plane || !stream)
716 return;
717
718 if (dc->hwss.wait_for_dcc_meta_propagation) {
719 block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.dc = dc;
720 block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.top_pipe_to_program = pipe_ctx;
721 block_sequence[*num_steps].func = HUBP_WAIT_FOR_DCC_META_PROP;
722 (*num_steps)++;
723 }
724 if (dc->hwss.subvp_pipe_control_lock_fast) {
725 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc;
726 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = true;
727 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.subvp_immediate_flip =
728 plane->flip_immediate && stream_status->mall_stream_config.type == SUBVP_MAIN;
729 block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST;
730 (*num_steps)++;
731 }
732 if (dc->hwss.fams2_global_control_lock_fast) {
733 block_sequence[*num_steps].params.fams2_global_control_lock_fast_params.dc = dc;
734 block_sequence[*num_steps].params.fams2_global_control_lock_fast_params.lock = true;
735 block_sequence[*num_steps].params.fams2_global_control_lock_fast_params.is_required = dc_state_is_fams2_in_use(dc, context);
736 block_sequence[*num_steps].func = DMUB_FAMS2_GLOBAL_CONTROL_LOCK_FAST;
737 (*num_steps)++;
738 }
739 if (dc->hwss.pipe_control_lock) {
740 block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc;
741 block_sequence[*num_steps].params.pipe_control_lock_params.lock = true;
742 block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
743 block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK;
744 (*num_steps)++;
745 }
746
747 for (i = 0; i < dmub_cmd_count; i++) {
748 block_sequence[*num_steps].params.send_dmcub_cmd_params.ctx = dc->ctx;
749 block_sequence[*num_steps].params.send_dmcub_cmd_params.cmd = &(dc_dmub_cmd[i].dmub_cmd);
750 block_sequence[*num_steps].params.send_dmcub_cmd_params.wait_type = dc_dmub_cmd[i].wait_type;
751 block_sequence[*num_steps].func = DMUB_SEND_DMCUB_CMD;
752 (*num_steps)++;
753 }
754
755 current_pipe = pipe_ctx;
756 while (current_pipe) {
757 current_mpc_pipe = current_pipe;
758 while (current_mpc_pipe) {
759 if (current_mpc_pipe->plane_state) {
760 if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state->update_flags.raw) {
761 block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe;
762 block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate;
763 block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL;
764 (*num_steps)++;
765 }
766 if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
767 block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
768 block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe;
769 block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips;
770 block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER;
771 (*num_steps)++;
772 }
773 if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
774 if (resource_is_pipe_type(current_mpc_pipe, OTG_MASTER) &&
775 stream_status->mall_stream_config.type == SUBVP_MAIN) {
776 block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
777 block_sequence[*num_steps].params.subvp_save_surf_addr.addr = ¤t_mpc_pipe->plane_state->address;
778 block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
779 block_sequence[*num_steps].func = DMUB_SUBVP_SAVE_SURF_ADDR;
780 (*num_steps)++;
781 }
782
783 block_sequence[*num_steps].params.update_plane_addr_params.dc = dc;
784 block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe;
785 block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR;
786 (*num_steps)++;
787 }
788
789 if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) {
790 block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc;
791 block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe;
792 block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state;
793 block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC;
794 (*num_steps)++;
795 }
796
797 if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) {
798 block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe;
799 block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP;
800 (*num_steps)++;
801 }
802 if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) {
803 block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe;
804 block_sequence[*num_steps].func = DPP_SETUP_DPP;
805 (*num_steps)++;
806 }
807 if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) {
808 block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe;
809 block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
810 (*num_steps)++;
811 }
812 }
813 if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {
814 block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc;
815 block_sequence[*num_steps].params.set_output_transfer_func_params.pipe_ctx = current_mpc_pipe;
816 block_sequence[*num_steps].params.set_output_transfer_func_params.stream = current_mpc_pipe->stream;
817 block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC;
818 (*num_steps)++;
819 }
820 if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE &&
821 dc->hwss.update_visual_confirm_color) {
822 block_sequence[*num_steps].params.update_visual_confirm_params.dc = dc;
823 block_sequence[*num_steps].params.update_visual_confirm_params.pipe_ctx = current_mpc_pipe;
824 block_sequence[*num_steps].params.update_visual_confirm_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst;
825 block_sequence[*num_steps].func = MPC_UPDATE_VISUAL_CONFIRM;
826 (*num_steps)++;
827 }
828 if (current_mpc_pipe->stream->update_flags.bits.out_csc) {
829 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpc = dc->res_pool->mpc;
830 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst;
831 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.power_on = true;
832 block_sequence[*num_steps].func = MPC_POWER_ON_MPC_MEM_PWR;
833 (*num_steps)++;
834
835 if (current_mpc_pipe->stream->csc_color_matrix.enable_adjustment == true) {
836 block_sequence[*num_steps].params.set_output_csc_params.mpc = dc->res_pool->mpc;
837 block_sequence[*num_steps].params.set_output_csc_params.opp_id = current_mpc_pipe->stream_res.opp->inst;
838 block_sequence[*num_steps].params.set_output_csc_params.regval = current_mpc_pipe->stream->csc_color_matrix.matrix;
839 block_sequence[*num_steps].params.set_output_csc_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
840 block_sequence[*num_steps].func = MPC_SET_OUTPUT_CSC;
841 (*num_steps)++;
842 } else {
843 block_sequence[*num_steps].params.set_ocsc_default_params.mpc = dc->res_pool->mpc;
844 block_sequence[*num_steps].params.set_ocsc_default_params.opp_id = current_mpc_pipe->stream_res.opp->inst;
845 block_sequence[*num_steps].params.set_ocsc_default_params.color_space = current_mpc_pipe->stream->output_color_space;
846 block_sequence[*num_steps].params.set_ocsc_default_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
847 block_sequence[*num_steps].func = MPC_SET_OCSC_DEFAULT;
848 (*num_steps)++;
849 }
850 }
851 current_mpc_pipe = current_mpc_pipe->bottom_pipe;
852 }
853 current_pipe = current_pipe->next_odm_pipe;
854 }
855
856 if (dc->hwss.pipe_control_lock) {
857 block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc;
858 block_sequence[*num_steps].params.pipe_control_lock_params.lock = false;
859 block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
860 block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK;
861 (*num_steps)++;
862 }
863 if (dc->hwss.subvp_pipe_control_lock_fast) {
864 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc;
865 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false;
866 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.subvp_immediate_flip =
867 plane->flip_immediate && stream_status->mall_stream_config.type == SUBVP_MAIN;
868 block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST;
869 (*num_steps)++;
870 }
871 if (dc->hwss.fams2_global_control_lock_fast) {
872 block_sequence[*num_steps].params.fams2_global_control_lock_fast_params.dc = dc;
873 block_sequence[*num_steps].params.fams2_global_control_lock_fast_params.lock = false;
874 block_sequence[*num_steps].params.fams2_global_control_lock_fast_params.is_required = dc_state_is_fams2_in_use(dc, context);
875 block_sequence[*num_steps].func = DMUB_FAMS2_GLOBAL_CONTROL_LOCK_FAST;
876 (*num_steps)++;
877 }
878
879 current_pipe = pipe_ctx;
880 while (current_pipe) {
881 current_mpc_pipe = current_pipe;
882
883 while (current_mpc_pipe) {
884 if (!current_mpc_pipe->bottom_pipe && !current_mpc_pipe->next_odm_pipe &&
885 current_mpc_pipe->stream && current_mpc_pipe->plane_state &&
886 current_mpc_pipe->plane_state->update_flags.bits.addr_update &&
887 !current_mpc_pipe->plane_state->skip_manual_trigger) {
888 block_sequence[*num_steps].params.program_manual_trigger_params.pipe_ctx = current_mpc_pipe;
889 block_sequence[*num_steps].func = OPTC_PROGRAM_MANUAL_TRIGGER;
890 (*num_steps)++;
891 }
892 current_mpc_pipe = current_mpc_pipe->bottom_pipe;
893 }
894 current_pipe = current_pipe->next_odm_pipe;
895 }
896 }
897
hwss_execute_sequence(struct dc * dc,struct block_sequence block_sequence[],int num_steps)898 void hwss_execute_sequence(struct dc *dc,
899 struct block_sequence block_sequence[],
900 int num_steps)
901 {
902 unsigned int i;
903 union block_sequence_params *params;
904 struct dce_hwseq *hws = dc->hwseq;
905
906 for (i = 0; i < num_steps; i++) {
907 params = &(block_sequence[i].params);
908 switch (block_sequence[i].func) {
909
910 case DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST:
911 dc->hwss.subvp_pipe_control_lock_fast(params);
912 break;
913 case OPTC_PIPE_CONTROL_LOCK:
914 dc->hwss.pipe_control_lock(params->pipe_control_lock_params.dc,
915 params->pipe_control_lock_params.pipe_ctx,
916 params->pipe_control_lock_params.lock);
917 break;
918 case HUBP_SET_FLIP_CONTROL_GSL:
919 dc->hwss.set_flip_control_gsl(params->set_flip_control_gsl_params.pipe_ctx,
920 params->set_flip_control_gsl_params.flip_immediate);
921 break;
922 case HUBP_PROGRAM_TRIPLEBUFFER:
923 dc->hwss.program_triplebuffer(params->program_triplebuffer_params.dc,
924 params->program_triplebuffer_params.pipe_ctx,
925 params->program_triplebuffer_params.enableTripleBuffer);
926 break;
927 case HUBP_UPDATE_PLANE_ADDR:
928 dc->hwss.update_plane_addr(params->update_plane_addr_params.dc,
929 params->update_plane_addr_params.pipe_ctx);
930 break;
931 case DPP_SET_INPUT_TRANSFER_FUNC:
932 hws->funcs.set_input_transfer_func(params->set_input_transfer_func_params.dc,
933 params->set_input_transfer_func_params.pipe_ctx,
934 params->set_input_transfer_func_params.plane_state);
935 break;
936 case DPP_PROGRAM_GAMUT_REMAP:
937 dc->hwss.program_gamut_remap(params->program_gamut_remap_params.pipe_ctx);
938 break;
939 case DPP_SETUP_DPP:
940 hwss_setup_dpp(params);
941 break;
942 case DPP_PROGRAM_BIAS_AND_SCALE:
943 hwss_program_bias_and_scale(params);
944 break;
945 case OPTC_PROGRAM_MANUAL_TRIGGER:
946 hwss_program_manual_trigger(params);
947 break;
948 case DPP_SET_OUTPUT_TRANSFER_FUNC:
949 hws->funcs.set_output_transfer_func(params->set_output_transfer_func_params.dc,
950 params->set_output_transfer_func_params.pipe_ctx,
951 params->set_output_transfer_func_params.stream);
952 break;
953 case MPC_UPDATE_VISUAL_CONFIRM:
954 dc->hwss.update_visual_confirm_color(params->update_visual_confirm_params.dc,
955 params->update_visual_confirm_params.pipe_ctx,
956 params->update_visual_confirm_params.mpcc_id);
957 break;
958 case MPC_POWER_ON_MPC_MEM_PWR:
959 hwss_power_on_mpc_mem_pwr(params);
960 break;
961 case MPC_SET_OUTPUT_CSC:
962 hwss_set_output_csc(params);
963 break;
964 case MPC_SET_OCSC_DEFAULT:
965 hwss_set_ocsc_default(params);
966 break;
967 case DMUB_SEND_DMCUB_CMD:
968 hwss_send_dmcub_cmd(params);
969 break;
970 case DMUB_SUBVP_SAVE_SURF_ADDR:
971 hwss_subvp_save_surf_addr(params);
972 break;
973 case HUBP_WAIT_FOR_DCC_META_PROP:
974 dc->hwss.wait_for_dcc_meta_propagation(
975 params->wait_for_dcc_meta_propagation_params.dc,
976 params->wait_for_dcc_meta_propagation_params.top_pipe_to_program);
977 break;
978 case DMUB_FAMS2_GLOBAL_CONTROL_LOCK_FAST:
979 dc->hwss.fams2_global_control_lock_fast(params);
980 break;
981 default:
982 ASSERT(false);
983 break;
984 }
985 }
986 }
987
hwss_send_dmcub_cmd(union block_sequence_params * params)988 void hwss_send_dmcub_cmd(union block_sequence_params *params)
989 {
990 struct dc_context *ctx = params->send_dmcub_cmd_params.ctx;
991 union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd;
992 enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type;
993
994 dc_wake_and_execute_dmub_cmd(ctx, cmd, wait_type);
995 }
996
hwss_program_manual_trigger(union block_sequence_params * params)997 void hwss_program_manual_trigger(union block_sequence_params *params)
998 {
999 struct pipe_ctx *pipe_ctx = params->program_manual_trigger_params.pipe_ctx;
1000
1001 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger)
1002 pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
1003 }
1004
hwss_setup_dpp(union block_sequence_params * params)1005 void hwss_setup_dpp(union block_sequence_params *params)
1006 {
1007 struct pipe_ctx *pipe_ctx = params->setup_dpp_params.pipe_ctx;
1008 struct dpp *dpp = pipe_ctx->plane_res.dpp;
1009 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
1010
1011 if (!plane_state)
1012 return;
1013
1014 if (dpp && dpp->funcs->dpp_setup) {
1015 // program the input csc
1016 dpp->funcs->dpp_setup(dpp,
1017 plane_state->format,
1018 EXPANSION_MODE_ZERO,
1019 plane_state->input_csc_color_matrix,
1020 plane_state->color_space,
1021 NULL);
1022 }
1023
1024 if (dpp && dpp->funcs->set_cursor_matrix) {
1025 dpp->funcs->set_cursor_matrix(dpp,
1026 plane_state->color_space,
1027 plane_state->cursor_csc_color_matrix);
1028 }
1029 }
1030
hwss_program_bias_and_scale(union block_sequence_params * params)1031 void hwss_program_bias_and_scale(union block_sequence_params *params)
1032 {
1033 struct pipe_ctx *pipe_ctx = params->program_bias_and_scale_params.pipe_ctx;
1034 struct dpp *dpp = pipe_ctx->plane_res.dpp;
1035 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
1036 struct dc_bias_and_scale bns_params = plane_state->bias_and_scale;
1037
1038 //TODO :for CNVC set scale and bias registers if necessary
1039 if (dpp->funcs->dpp_program_bias_and_scale) {
1040 dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
1041 }
1042 }
1043
hwss_power_on_mpc_mem_pwr(union block_sequence_params * params)1044 void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params)
1045 {
1046 struct mpc *mpc = params->power_on_mpc_mem_pwr_params.mpc;
1047 int mpcc_id = params->power_on_mpc_mem_pwr_params.mpcc_id;
1048 bool power_on = params->power_on_mpc_mem_pwr_params.power_on;
1049
1050 if (mpc->funcs->power_on_mpc_mem_pwr)
1051 mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, power_on);
1052 }
1053
hwss_set_output_csc(union block_sequence_params * params)1054 void hwss_set_output_csc(union block_sequence_params *params)
1055 {
1056 struct mpc *mpc = params->set_output_csc_params.mpc;
1057 int opp_id = params->set_output_csc_params.opp_id;
1058 const uint16_t *matrix = params->set_output_csc_params.regval;
1059 enum mpc_output_csc_mode ocsc_mode = params->set_output_csc_params.ocsc_mode;
1060
1061 if (mpc->funcs->set_output_csc != NULL)
1062 mpc->funcs->set_output_csc(mpc,
1063 opp_id,
1064 matrix,
1065 ocsc_mode);
1066 }
1067
hwss_set_ocsc_default(union block_sequence_params * params)1068 void hwss_set_ocsc_default(union block_sequence_params *params)
1069 {
1070 struct mpc *mpc = params->set_ocsc_default_params.mpc;
1071 int opp_id = params->set_ocsc_default_params.opp_id;
1072 enum dc_color_space colorspace = params->set_ocsc_default_params.color_space;
1073 enum mpc_output_csc_mode ocsc_mode = params->set_ocsc_default_params.ocsc_mode;
1074
1075 if (mpc->funcs->set_ocsc_default != NULL)
1076 mpc->funcs->set_ocsc_default(mpc,
1077 opp_id,
1078 colorspace,
1079 ocsc_mode);
1080 }
1081
hwss_subvp_save_surf_addr(union block_sequence_params * params)1082 void hwss_subvp_save_surf_addr(union block_sequence_params *params)
1083 {
1084 struct dc_dmub_srv *dc_dmub_srv = params->subvp_save_surf_addr.dc_dmub_srv;
1085 const struct dc_plane_address *addr = params->subvp_save_surf_addr.addr;
1086 uint8_t subvp_index = params->subvp_save_surf_addr.subvp_index;
1087
1088 dc_dmub_srv_subvp_save_surf_addr(dc_dmub_srv, addr, subvp_index);
1089 }
1090
get_surface_tile_visual_confirm_color(struct pipe_ctx * pipe_ctx,struct tg_color * color)1091 void get_surface_tile_visual_confirm_color(
1092 struct pipe_ctx *pipe_ctx,
1093 struct tg_color *color)
1094 {
1095 uint32_t color_value = MAX_TG_COLOR_VALUE;
1096 /* Determine the overscan color based on the bottom-most plane's context */
1097 struct pipe_ctx *bottom_pipe_ctx = pipe_ctx;
1098
1099 while (bottom_pipe_ctx->bottom_pipe != NULL)
1100 bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe;
1101
1102 switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) {
1103 case DC_SW_LINEAR:
1104 /* LINEAR Surface - set border color to red */
1105 color->color_r_cr = color_value;
1106 break;
1107 default:
1108 break;
1109 }
1110 }
1111
1112 /**
1113 * hwss_wait_for_all_blank_complete - wait for all active OPPs to finish pending blank
1114 * pattern updates
1115 *
1116 * @dc: [in] dc reference
1117 * @context: [in] hardware context in use
1118 */
hwss_wait_for_all_blank_complete(struct dc * dc,struct dc_state * context)1119 void hwss_wait_for_all_blank_complete(struct dc *dc,
1120 struct dc_state *context)
1121 {
1122 struct pipe_ctx *opp_head;
1123 struct dce_hwseq *hws = dc->hwseq;
1124 int i;
1125
1126 if (!hws->funcs.wait_for_blank_complete)
1127 return;
1128
1129 for (i = 0; i < MAX_PIPES; i++) {
1130 opp_head = &context->res_ctx.pipe_ctx[i];
1131
1132 if (!resource_is_pipe_type(opp_head, OPP_HEAD) ||
1133 dc_state_get_pipe_subvp_type(context, opp_head) == SUBVP_PHANTOM)
1134 continue;
1135
1136 hws->funcs.wait_for_blank_complete(opp_head->stream_res.opp);
1137 }
1138 }
1139
hwss_wait_for_odm_update_pending_complete(struct dc * dc,struct dc_state * context)1140 void hwss_wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *context)
1141 {
1142 struct pipe_ctx *otg_master;
1143 struct timing_generator *tg;
1144 int i;
1145
1146 for (i = 0; i < MAX_PIPES; i++) {
1147 otg_master = &context->res_ctx.pipe_ctx[i];
1148 if (!resource_is_pipe_type(otg_master, OTG_MASTER) ||
1149 dc_state_get_pipe_subvp_type(context, otg_master) == SUBVP_PHANTOM)
1150 continue;
1151 tg = otg_master->stream_res.tg;
1152 if (tg->funcs->wait_odm_doublebuffer_pending_clear)
1153 tg->funcs->wait_odm_doublebuffer_pending_clear(tg);
1154 }
1155
1156 /* ODM update may require to reprogram blank pattern for each OPP */
1157 hwss_wait_for_all_blank_complete(dc, context);
1158 }
1159
hwss_wait_for_no_pipes_pending(struct dc * dc,struct dc_state * context)1160 void hwss_wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
1161 {
1162 int i;
1163 for (i = 0; i < MAX_PIPES; i++) {
1164 int count = 0;
1165 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1166
1167 if (!pipe->plane_state || dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
1168 continue;
1169
1170 /* Timeout 100 ms */
1171 while (count < 100000) {
1172 /* Must set to false to start with, due to OR in update function */
1173 pipe->plane_state->status.is_flip_pending = false;
1174 dc->hwss.update_pending_status(pipe);
1175 if (!pipe->plane_state->status.is_flip_pending)
1176 break;
1177 udelay(1);
1178 count++;
1179 }
1180 ASSERT(!pipe->plane_state->status.is_flip_pending);
1181 }
1182 }
1183
hwss_wait_for_outstanding_hw_updates(struct dc * dc,struct dc_state * dc_context)1184 void hwss_wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
1185 {
1186 /*
1187 * This function calls HWSS to wait for any potentially double buffered
1188 * operations to complete. It should be invoked as a pre-amble prior
1189 * to full update programming before asserting any HW locks.
1190 */
1191 int pipe_idx;
1192 int opp_inst;
1193 int opp_count = dc->res_pool->res_cap->num_opp;
1194 struct hubp *hubp;
1195 int mpcc_inst;
1196 const struct pipe_ctx *pipe_ctx;
1197
1198 for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
1199 pipe_ctx = &dc_context->res_ctx.pipe_ctx[pipe_idx];
1200
1201 if (!pipe_ctx->stream)
1202 continue;
1203
1204 /* For full update we must wait for all double buffer updates, not just DRR updates. This
1205 * is particularly important for minimal transitions. Only check for OTG_MASTER pipes,
1206 * as non-OTG Master pipes share the same OTG as
1207 */
1208 if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && dc->hwss.wait_for_all_pending_updates) {
1209 dc->hwss.wait_for_all_pending_updates(pipe_ctx);
1210 }
1211
1212 hubp = pipe_ctx->plane_res.hubp;
1213 if (!hubp)
1214 continue;
1215
1216 mpcc_inst = hubp->inst;
1217 // MPCC inst is equal to pipe index in practice
1218 for (opp_inst = 0; opp_inst < opp_count; opp_inst++) {
1219 if ((dc->res_pool->opps[opp_inst] != NULL) &&
1220 (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst])) {
1221 dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst);
1222 dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false;
1223 break;
1224 }
1225 }
1226 }
1227 hwss_wait_for_odm_update_pending_complete(dc, dc_context);
1228 }
1229
hwss_process_outstanding_hw_updates(struct dc * dc,struct dc_state * dc_context)1230 void hwss_process_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
1231 {
1232 /* wait for outstanding updates */
1233 hwss_wait_for_outstanding_hw_updates(dc, dc_context);
1234
1235 /* perform outstanding post update programming */
1236 if (dc->hwss.program_outstanding_updates)
1237 dc->hwss.program_outstanding_updates(dc, dc_context);
1238 }
1239