1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/slab.h>
26#include <linux/mm.h>
27
28#include "dm_services.h"
29
30#include "dc.h"
31
32#include "core_status.h"
33#include "core_types.h"
34#include "hw_sequencer.h"
35#include "dce/dce_hwseq.h"
36
37#include "resource.h"
38
39#include "clk_mgr.h"
40#include "clock_source.h"
41#include "dc_bios_types.h"
42
43#include "bios_parser_interface.h"
44#include "bios/bios_parser_helper.h"
45#include "include/irq_service_interface.h"
46#include "transform.h"
47#include "dmcu.h"
48#include "dpp.h"
49#include "timing_generator.h"
50#include "abm.h"
51#include "virtual/virtual_link_encoder.h"
52#include "hubp.h"
53
54#include "link_hwss.h"
55#include "link_encoder.h"
56#include "link_enc_cfg.h"
57
58#include "dc_link.h"
59#include "dc_link_ddc.h"
60#include "dm_helpers.h"
61#include "mem_input.h"
62
63#include "dc_link_dp.h"
64#include "dc_dmub_srv.h"
65
66#include "dsc.h"
67
68#include "vm_helper.h"
69
70#include "dce/dce_i2c.h"
71
72#include "dmub/dmub_srv.h"
73
74#include "i2caux_interface.h"
75#include "dce/dmub_hw_lock_mgr.h"
76
77#include "dc_trace.h"
78
79#define CTX \
80 dc->ctx
81
82#define DC_LOGGER \
83 dc->ctx->logger
84
85static const char DC_BUILD_ID[] = "production-build";
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
141{
142 if (new > *original)
143 *original = new;
144}
145
146static void destroy_links(struct dc *dc)
147{
148 uint32_t i;
149
150 for (i = 0; i < dc->link_count; i++) {
151 if (NULL != dc->links[i])
152 link_destroy(&dc->links[i]);
153 }
154}
155
156static uint32_t get_num_of_internal_disp(struct dc_link **links, uint32_t num_links)
157{
158 int i;
159 uint32_t count = 0;
160
161 for (i = 0; i < num_links; i++) {
162 if (links[i]->connector_signal == SIGNAL_TYPE_EDP ||
163 links[i]->is_internal_display)
164 count++;
165 }
166
167 return count;
168}
169
170static int get_seamless_boot_stream_count(struct dc_state *ctx)
171{
172 uint8_t i;
173 uint8_t seamless_boot_stream_count = 0;
174
175 for (i = 0; i < ctx->stream_count; i++)
176 if (ctx->streams[i]->apply_seamless_boot_optimization)
177 seamless_boot_stream_count++;
178
179 return seamless_boot_stream_count;
180}
181
182static bool create_links(
183 struct dc *dc,
184 uint32_t num_virtual_links)
185{
186 int i;
187 int connectors_num;
188 struct dc_bios *bios = dc->ctx->dc_bios;
189
190 dc->link_count = 0;
191
192 connectors_num = bios->funcs->get_connectors_number(bios);
193
194 DC_LOG_DC("BIOS object table - number of connectors: %d", connectors_num);
195
196 if (connectors_num > ENUM_ID_COUNT) {
197 dm_error(
198 "DC: Number of connectors %d exceeds maximum of %d!\n",
199 connectors_num,
200 ENUM_ID_COUNT);
201 return false;
202 }
203
204 dm_output_to_console(
205 "DC: %s: connectors_num: physical:%d, virtual:%d\n",
206 __func__,
207 connectors_num,
208 num_virtual_links);
209
210 for (i = 0; i < connectors_num; i++) {
211 struct link_init_data link_init_params = {0};
212 struct dc_link *link;
213
214 DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count);
215
216 link_init_params.ctx = dc->ctx;
217
218 link_init_params.connector_index = i;
219 link_init_params.link_index = dc->link_count;
220 link_init_params.dc = dc;
221 link = link_create(&link_init_params);
222
223 if (link) {
224 dc->links[dc->link_count] = link;
225 link->dc = dc;
226 ++dc->link_count;
227 }
228 }
229
230 DC_LOG_DC("BIOS object table - end");
231
232 for (i = 0; i < num_virtual_links; i++) {
233 struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
234 struct encoder_init_data enc_init = {0};
235
236 if (link == NULL) {
237 BREAK_TO_DEBUGGER();
238 goto failed_alloc;
239 }
240
241 link->link_index = dc->link_count;
242 dc->links[dc->link_count] = link;
243 dc->link_count++;
244
245 link->ctx = dc->ctx;
246 link->dc = dc;
247 link->connector_signal = SIGNAL_TYPE_VIRTUAL;
248 link->link_id.type = OBJECT_TYPE_CONNECTOR;
249 link->link_id.id = CONNECTOR_ID_VIRTUAL;
250 link->link_id.enum_id = ENUM_ID_1;
251 link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL);
252
253 if (!link->link_enc) {
254 BREAK_TO_DEBUGGER();
255 goto failed_alloc;
256 }
257
258 link->link_status.dpcd_caps = &link->dpcd_caps;
259
260 enc_init.ctx = dc->ctx;
261 enc_init.channel = CHANNEL_ID_UNKNOWN;
262 enc_init.hpd_source = HPD_SOURCEID_UNKNOWN;
263 enc_init.transmitter = TRANSMITTER_UNKNOWN;
264 enc_init.connector = link->link_id;
265 enc_init.encoder.type = OBJECT_TYPE_ENCODER;
266 enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL;
267 enc_init.encoder.enum_id = ENUM_ID_1;
268 virtual_link_encoder_construct(link->link_enc, &enc_init);
269 }
270
271 dc->caps.num_of_internal_disp = get_num_of_internal_disp(dc->links, dc->link_count);
272
273 return true;
274
275failed_alloc:
276 return false;
277}
278
279static struct dc_perf_trace *dc_perf_trace_create(void)
280{
281 return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL);
282}
283
284static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace)
285{
286 kfree(*perf_trace);
287 *perf_trace = NULL;
288}
289
290
291
292
293
294
295
296
297
298
299
300
301
302bool dc_stream_adjust_vmin_vmax(struct dc *dc,
303 struct dc_stream_state *stream,
304 struct dc_crtc_timing_adjust *adjust)
305{
306 int i;
307 bool ret = false;
308
309 stream->adjust.v_total_max = adjust->v_total_max;
310 stream->adjust.v_total_mid = adjust->v_total_mid;
311 stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
312 stream->adjust.v_total_min = adjust->v_total_min;
313
314 for (i = 0; i < MAX_PIPES; i++) {
315 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
316
317 if (pipe->stream == stream && pipe->stream_res.tg) {
318 dc->hwss.set_drr(&pipe,
319 1,
320 *adjust);
321
322 ret = true;
323 }
324 }
325 return ret;
326}
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
343 struct dc_stream_state *stream,
344 uint32_t *refresh_rate)
345{
346 bool status = false;
347
348 int i = 0;
349
350 for (i = 0; i < MAX_PIPES; i++) {
351 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
352
353 if (pipe->stream == stream && pipe->stream_res.tg) {
354
355
356
357 if (pipe->stream_res.tg->funcs->get_last_used_drr_vtotal) {
358 pipe->stream_res.tg->funcs->get_last_used_drr_vtotal(pipe->stream_res.tg, refresh_rate);
359
360 status = true;
361
362 break;
363 }
364 }
365 }
366
367 return status;
368}
369
370bool dc_stream_get_crtc_position(struct dc *dc,
371 struct dc_stream_state **streams, int num_streams,
372 unsigned int *v_pos, unsigned int *nom_v_pos)
373{
374
375 const struct dc_stream_state *stream = streams[0];
376 int i;
377 bool ret = false;
378 struct crtc_position position;
379
380 for (i = 0; i < MAX_PIPES; i++) {
381 struct pipe_ctx *pipe =
382 &dc->current_state->res_ctx.pipe_ctx[i];
383
384 if (pipe->stream == stream && pipe->stream_res.stream_enc) {
385 dc->hwss.get_position(&pipe, 1, &position);
386
387 *v_pos = position.vertical_count;
388 *nom_v_pos = position.nominal_vcount;
389 ret = true;
390 }
391 }
392 return ret;
393}
394
395#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
396bool dc_stream_forward_dmcu_crc_window(struct dc *dc, struct dc_stream_state *stream,
397 struct crc_params *crc_window)
398{
399 int i;
400 struct dmcu *dmcu = dc->res_pool->dmcu;
401 struct pipe_ctx *pipe;
402 struct crc_region tmp_win, *crc_win;
403 struct otg_phy_mux mapping_tmp, *mux_mapping;
404
405
406 if (!crc_window)
407 return false;
408
409 if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) {
410 crc_win = &tmp_win;
411 mux_mapping = &mapping_tmp;
412
413 tmp_win.x_start = crc_window->windowa_x_start;
414 tmp_win.y_start = crc_window->windowa_y_start;
415 tmp_win.x_end = crc_window->windowa_x_end;
416 tmp_win.y_end = crc_window->windowa_y_end;
417
418 for (i = 0; i < MAX_PIPES; i++) {
419 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
420 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
421 break;
422 }
423
424
425 if (i == MAX_PIPES)
426 return false;
427
428
429
430 mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst;
431 mapping_tmp.otg_output_num = pipe->stream_res.tg->inst;
432
433 dmcu->funcs->forward_crc_window(dmcu, crc_win, mux_mapping);
434 } else {
435 DC_LOG_DC("dmcu is not initialized");
436 return false;
437 }
438
439 return true;
440}
441
442bool dc_stream_stop_dmcu_crc_win_update(struct dc *dc, struct dc_stream_state *stream)
443{
444 int i;
445 struct dmcu *dmcu = dc->res_pool->dmcu;
446 struct pipe_ctx *pipe;
447 struct otg_phy_mux mapping_tmp, *mux_mapping;
448
449 if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) {
450 mux_mapping = &mapping_tmp;
451
452 for (i = 0; i < MAX_PIPES; i++) {
453 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
454 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
455 break;
456 }
457
458
459 if (i == MAX_PIPES)
460 return false;
461
462
463
464 mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst;
465 mapping_tmp.otg_output_num = pipe->stream_res.tg->inst;
466
467 dmcu->funcs->stop_crc_win_update(dmcu, mux_mapping);
468 } else {
469 DC_LOG_DC("dmcu is not initialized");
470 return false;
471 }
472
473 return true;
474}
475#endif
476
477
478
479
480
481
482
483
484
485
486
487
488
489bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
490 struct crc_params *crc_window, bool enable, bool continuous)
491{
492 int i;
493 struct pipe_ctx *pipe;
494 struct crc_params param;
495 struct timing_generator *tg;
496
497 for (i = 0; i < MAX_PIPES; i++) {
498 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
499 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
500 break;
501 }
502
503 if (i == MAX_PIPES)
504 return false;
505
506
507 param.windowa_x_start = 0;
508 param.windowa_y_start = 0;
509 param.windowa_x_end = pipe->stream->timing.h_addressable;
510 param.windowa_y_end = pipe->stream->timing.v_addressable;
511 param.windowb_x_start = 0;
512 param.windowb_y_start = 0;
513 param.windowb_x_end = pipe->stream->timing.h_addressable;
514 param.windowb_y_end = pipe->stream->timing.v_addressable;
515
516 if (crc_window) {
517 param.windowa_x_start = crc_window->windowa_x_start;
518 param.windowa_y_start = crc_window->windowa_y_start;
519 param.windowa_x_end = crc_window->windowa_x_end;
520 param.windowa_y_end = crc_window->windowa_y_end;
521 param.windowb_x_start = crc_window->windowb_x_start;
522 param.windowb_y_start = crc_window->windowb_y_start;
523 param.windowb_x_end = crc_window->windowb_x_end;
524 param.windowb_y_end = crc_window->windowb_y_end;
525 }
526
527 param.dsc_mode = pipe->stream->timing.flags.DSC ? 1:0;
528 param.odm_mode = pipe->next_odm_pipe ? 1:0;
529
530
531 param.selection = UNION_WINDOW_A_B;
532 param.continuous_mode = continuous;
533 param.enable = enable;
534
535 tg = pipe->stream_res.tg;
536
537
538 if (tg->funcs->configure_crc)
539 return tg->funcs->configure_crc(tg, ¶m);
540 DC_LOG_WARNING("CRC capture not supported.");
541 return false;
542}
543
544
545
546
547
548
549
550
551
552
553
554
555bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
556 uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
557{
558 int i;
559 struct pipe_ctx *pipe;
560 struct timing_generator *tg;
561
562 for (i = 0; i < MAX_PIPES; i++) {
563 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
564 if (pipe->stream == stream)
565 break;
566 }
567
568 if (i == MAX_PIPES)
569 return false;
570
571 tg = pipe->stream_res.tg;
572
573 if (tg->funcs->get_crc)
574 return tg->funcs->get_crc(tg, r_cr, g_y, b_cb);
575 DC_LOG_WARNING("CRC capture not supported.");
576 return false;
577}
578
579void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
580 enum dc_dynamic_expansion option)
581{
582
583 int i;
584 struct pipe_ctx *pipe_ctx;
585
586 for (i = 0; i < MAX_PIPES; i++) {
587 if (dc->current_state->res_ctx.pipe_ctx[i].stream
588 == stream) {
589 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
590 pipe_ctx->stream_res.opp->dyn_expansion = option;
591 pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
592 pipe_ctx->stream_res.opp,
593 COLOR_SPACE_YCBCR601,
594 stream->timing.display_color_depth,
595 stream->signal);
596 }
597 }
598}
599
600void dc_stream_set_dither_option(struct dc_stream_state *stream,
601 enum dc_dither_option option)
602{
603 struct bit_depth_reduction_params params;
604 struct dc_link *link = stream->link;
605 struct pipe_ctx *pipes = NULL;
606 int i;
607
608 for (i = 0; i < MAX_PIPES; i++) {
609 if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
610 stream) {
611 pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
612 break;
613 }
614 }
615
616 if (!pipes)
617 return;
618 if (option > DITHER_OPTION_MAX)
619 return;
620
621 stream->dither_option = option;
622
623 memset(¶ms, 0, sizeof(params));
624 resource_build_bit_depth_reduction_params(stream, ¶ms);
625 stream->bit_depth_params = params;
626
627 if (pipes->plane_res.xfm &&
628 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) {
629 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
630 pipes->plane_res.xfm,
631 pipes->plane_res.scl_data.lb_params.depth,
632 &stream->bit_depth_params);
633 }
634
635 pipes->stream_res.opp->funcs->
636 opp_program_bit_depth_reduction(pipes->stream_res.opp, ¶ms);
637}
638
639bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
640{
641 int i;
642 bool ret = false;
643 struct pipe_ctx *pipes;
644
645 for (i = 0; i < MAX_PIPES; i++) {
646 if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
647 pipes = &dc->current_state->res_ctx.pipe_ctx[i];
648 dc->hwss.program_gamut_remap(pipes);
649 ret = true;
650 }
651 }
652
653 return ret;
654}
655
656bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
657{
658 int i;
659 bool ret = false;
660 struct pipe_ctx *pipes;
661
662 for (i = 0; i < MAX_PIPES; i++) {
663 if (dc->current_state->res_ctx.pipe_ctx[i].stream
664 == stream) {
665
666 pipes = &dc->current_state->res_ctx.pipe_ctx[i];
667 dc->hwss.program_output_csc(dc,
668 pipes,
669 stream->output_color_space,
670 stream->csc_color_matrix.matrix,
671 pipes->stream_res.opp->inst);
672 ret = true;
673 }
674 }
675
676 return ret;
677}
678
679void dc_stream_set_static_screen_params(struct dc *dc,
680 struct dc_stream_state **streams,
681 int num_streams,
682 const struct dc_static_screen_params *params)
683{
684 int i, j;
685 struct pipe_ctx *pipes_affected[MAX_PIPES];
686 int num_pipes_affected = 0;
687
688 for (i = 0; i < num_streams; i++) {
689 struct dc_stream_state *stream = streams[i];
690
691 for (j = 0; j < MAX_PIPES; j++) {
692 if (dc->current_state->res_ctx.pipe_ctx[j].stream
693 == stream) {
694 pipes_affected[num_pipes_affected++] =
695 &dc->current_state->res_ctx.pipe_ctx[j];
696 }
697 }
698 }
699
700 dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, params);
701}
702
703static void dc_destruct(struct dc *dc)
704{
705 if (dc->current_state) {
706 dc_release_state(dc->current_state);
707 dc->current_state = NULL;
708 }
709
710 destroy_links(dc);
711
712 if (dc->clk_mgr) {
713 dc_destroy_clk_mgr(dc->clk_mgr);
714 dc->clk_mgr = NULL;
715 }
716
717 dc_destroy_resource_pool(dc);
718
719 if (dc->ctx->gpio_service)
720 dal_gpio_service_destroy(&dc->ctx->gpio_service);
721
722 if (dc->ctx->created_bios)
723 dal_bios_parser_destroy(&dc->ctx->dc_bios);
724
725 dc_perf_trace_destroy(&dc->ctx->perf_trace);
726
727 kfree(dc->ctx);
728 dc->ctx = NULL;
729
730 kfree(dc->bw_vbios);
731 dc->bw_vbios = NULL;
732
733 kfree(dc->bw_dceip);
734 dc->bw_dceip = NULL;
735
736#ifdef CONFIG_DRM_AMD_DC_DCN
737 kfree(dc->dcn_soc);
738 dc->dcn_soc = NULL;
739
740 kfree(dc->dcn_ip);
741 dc->dcn_ip = NULL;
742
743#endif
744 kfree(dc->vm_helper);
745 dc->vm_helper = NULL;
746
747}
748
749static bool dc_construct_ctx(struct dc *dc,
750 const struct dc_init_data *init_params)
751{
752 struct dc_context *dc_ctx;
753 enum dce_version dc_version = DCE_VERSION_UNKNOWN;
754
755 dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL);
756 if (!dc_ctx)
757 return false;
758
759 dc_ctx->cgs_device = init_params->cgs_device;
760 dc_ctx->driver_context = init_params->driver;
761 dc_ctx->dc = dc;
762 dc_ctx->asic_id = init_params->asic_id;
763 dc_ctx->dc_sink_id_count = 0;
764 dc_ctx->dc_stream_id_count = 0;
765 dc_ctx->dce_environment = init_params->dce_environment;
766
767
768
769 dc_version = resource_parse_asic_id(init_params->asic_id);
770 dc_ctx->dce_version = dc_version;
771
772 dc_ctx->perf_trace = dc_perf_trace_create();
773 if (!dc_ctx->perf_trace) {
774 ASSERT_CRITICAL(false);
775 return false;
776 }
777
778 dc->ctx = dc_ctx;
779
780 return true;
781}
782
783static bool dc_construct(struct dc *dc,
784 const struct dc_init_data *init_params)
785{
786 struct dc_context *dc_ctx;
787 struct bw_calcs_dceip *dc_dceip;
788 struct bw_calcs_vbios *dc_vbios;
789#ifdef CONFIG_DRM_AMD_DC_DCN
790 struct dcn_soc_bounding_box *dcn_soc;
791 struct dcn_ip_params *dcn_ip;
792#endif
793
794 dc->config = init_params->flags;
795
796
797 dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
798 if (!dc->vm_helper) {
799 dm_error("%s: failed to create dc->vm_helper\n", __func__);
800 goto fail;
801 }
802
803 memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
804
805 dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL);
806 if (!dc_dceip) {
807 dm_error("%s: failed to create dceip\n", __func__);
808 goto fail;
809 }
810
811 dc->bw_dceip = dc_dceip;
812
813 dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL);
814 if (!dc_vbios) {
815 dm_error("%s: failed to create vbios\n", __func__);
816 goto fail;
817 }
818
819 dc->bw_vbios = dc_vbios;
820#ifdef CONFIG_DRM_AMD_DC_DCN
821 dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL);
822 if (!dcn_soc) {
823 dm_error("%s: failed to create dcn_soc\n", __func__);
824 goto fail;
825 }
826
827 dc->dcn_soc = dcn_soc;
828
829 dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL);
830 if (!dcn_ip) {
831 dm_error("%s: failed to create dcn_ip\n", __func__);
832 goto fail;
833 }
834
835 dc->dcn_ip = dcn_ip;
836#endif
837
838 if (!dc_construct_ctx(dc, init_params)) {
839 dm_error("%s: failed to create ctx\n", __func__);
840 goto fail;
841 }
842
843 dc_ctx = dc->ctx;
844
845
846
847
848 if (init_params->vbios_override)
849 dc_ctx->dc_bios = init_params->vbios_override;
850 else {
851
852 struct bp_init_data bp_init_data;
853
854 bp_init_data.ctx = dc_ctx;
855 bp_init_data.bios = init_params->asic_id.atombios_base_address;
856
857 dc_ctx->dc_bios = dal_bios_parser_create(
858 &bp_init_data, dc_ctx->dce_version);
859
860 if (!dc_ctx->dc_bios) {
861 ASSERT_CRITICAL(false);
862 goto fail;
863 }
864
865 dc_ctx->created_bios = true;
866 }
867
868 dc->vendor_signature = init_params->vendor_signature;
869
870
871 dc_ctx->gpio_service = dal_gpio_service_create(
872 dc_ctx->dce_version,
873 dc_ctx->dce_environment,
874 dc_ctx);
875
876 if (!dc_ctx->gpio_service) {
877 ASSERT_CRITICAL(false);
878 goto fail;
879 }
880
881 dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version);
882 if (!dc->res_pool)
883 goto fail;
884
885
886 if (dc->caps.i2c_speed_in_khz_hdcp == 0)
887 dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz;
888
889 dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg);
890 if (!dc->clk_mgr)
891 goto fail;
892#ifdef CONFIG_DRM_AMD_DC_DCN
893 dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present;
894#endif
895
896 if (dc->res_pool->funcs->update_bw_bounding_box)
897 dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
898
899
900
901
902
903
904 dc->current_state = dc_create_state(dc);
905
906 if (!dc->current_state) {
907 dm_error("%s: failed to create validate ctx\n", __func__);
908 goto fail;
909 }
910
911 dc_resource_state_construct(dc, dc->current_state);
912
913 if (!create_links(dc, init_params->num_virtual_links))
914 goto fail;
915
916
917 link_enc_cfg_init(dc, dc->current_state);
918
919 return true;
920
921fail:
922 return false;
923}
924
925static void disable_all_writeback_pipes_for_stream(
926 const struct dc *dc,
927 struct dc_stream_state *stream,
928 struct dc_state *context)
929{
930 int i;
931
932 for (i = 0; i < stream->num_wb_info; i++)
933 stream->writeback_info[i].wb_enabled = false;
934}
935
936static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context,
937 struct dc_stream_state *stream, bool lock)
938{
939 int i;
940
941
942 if (dc->hwss.interdependent_update_lock)
943 dc->hwss.interdependent_update_lock(dc, context, lock);
944 else {
945 for (i = 0; i < dc->res_pool->pipe_count; i++) {
946 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
947 struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
948
949
950 if (stream == pipe_ctx->stream) {
951 if (!pipe_ctx->top_pipe &&
952 (pipe_ctx->plane_state || old_pipe_ctx->plane_state))
953 dc->hwss.pipe_control_lock(dc, pipe_ctx, lock);
954 }
955 }
956 }
957}
958
959static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
960{
961 int i, j;
962 struct dc_state *dangling_context = dc_create_state(dc);
963 struct dc_state *current_ctx;
964
965 if (dangling_context == NULL)
966 return;
967
968 dc_resource_state_copy_construct(dc->current_state, dangling_context);
969
970 for (i = 0; i < dc->res_pool->pipe_count; i++) {
971 struct dc_stream_state *old_stream =
972 dc->current_state->res_ctx.pipe_ctx[i].stream;
973 bool should_disable = true;
974
975 for (j = 0; j < context->stream_count; j++) {
976 if (old_stream == context->streams[j]) {
977 should_disable = false;
978 break;
979 }
980 }
981 if (should_disable && old_stream) {
982 dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
983 disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
984
985 if (dc->hwss.apply_ctx_for_surface) {
986 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, true);
987 dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
988 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, false);
989 dc->hwss.post_unlock_program_front_end(dc, dangling_context);
990 }
991 if (dc->hwss.program_front_end_for_ctx) {
992 dc->hwss.interdependent_update_lock(dc, dc->current_state, true);
993 dc->hwss.program_front_end_for_ctx(dc, dangling_context);
994 dc->hwss.interdependent_update_lock(dc, dc->current_state, false);
995 dc->hwss.post_unlock_program_front_end(dc, dangling_context);
996 }
997 }
998 }
999
1000 current_ctx = dc->current_state;
1001 dc->current_state = dangling_context;
1002 dc_release_state(current_ctx);
1003}
1004
1005static void disable_vbios_mode_if_required(
1006 struct dc *dc,
1007 struct dc_state *context)
1008{
1009 unsigned int i, j;
1010
1011
1012 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1013 struct dc_stream_state *stream = NULL;
1014 struct dc_link *link = NULL;
1015 struct pipe_ctx *pipe = NULL;
1016
1017 pipe = &context->res_ctx.pipe_ctx[i];
1018 stream = pipe->stream;
1019 if (stream == NULL)
1020 continue;
1021
1022
1023 if (pipe->prev_odm_pipe)
1024 continue;
1025
1026 if (stream->link->local_sink &&
1027 stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1028 link = stream->link;
1029 }
1030
1031 if (link != NULL && link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
1032 unsigned int enc_inst, tg_inst = 0;
1033 unsigned int pix_clk_100hz;
1034
1035 enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
1036 if (enc_inst != ENGINE_ID_UNKNOWN) {
1037 for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
1038 if (dc->res_pool->stream_enc[j]->id == enc_inst) {
1039 tg_inst = dc->res_pool->stream_enc[j]->funcs->dig_source_otg(
1040 dc->res_pool->stream_enc[j]);
1041 break;
1042 }
1043 }
1044
1045 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1046 dc->res_pool->dp_clock_source,
1047 tg_inst, &pix_clk_100hz);
1048
1049 if (link->link_status.link_active) {
1050 uint32_t requested_pix_clk_100hz =
1051 pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
1052
1053 if (pix_clk_100hz != requested_pix_clk_100hz) {
1054 core_link_disable_stream(pipe);
1055 pipe->stream->dpms_off = false;
1056 }
1057 }
1058 }
1059 }
1060 }
1061}
1062
1063static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
1064{
1065 int i;
1066 PERF_TRACE();
1067 for (i = 0; i < MAX_PIPES; i++) {
1068 int count = 0;
1069 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1070
1071 if (!pipe->plane_state)
1072 continue;
1073
1074
1075 while (count < 100000) {
1076
1077 pipe->plane_state->status.is_flip_pending = false;
1078 dc->hwss.update_pending_status(pipe);
1079 if (!pipe->plane_state->status.is_flip_pending)
1080 break;
1081 udelay(1);
1082 count++;
1083 }
1084 ASSERT(!pipe->plane_state->status.is_flip_pending);
1085 }
1086 PERF_TRACE();
1087}
1088
1089
1090
1091
1092
1093struct dc *dc_create(const struct dc_init_data *init_params)
1094{
1095 struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
1096 unsigned int full_pipe_count;
1097
1098 if (!dc)
1099 return NULL;
1100
1101 if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) {
1102 if (!dc_construct_ctx(dc, init_params))
1103 goto destruct_dc;
1104 } else {
1105 if (!dc_construct(dc, init_params))
1106 goto destruct_dc;
1107
1108 full_pipe_count = dc->res_pool->pipe_count;
1109 if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE)
1110 full_pipe_count--;
1111 dc->caps.max_streams = min(
1112 full_pipe_count,
1113 dc->res_pool->stream_enc_count);
1114
1115 dc->caps.max_links = dc->link_count;
1116 dc->caps.max_audios = dc->res_pool->audio_count;
1117 dc->caps.linear_pitch_alignment = 64;
1118
1119 dc->caps.max_dp_protocol_version = DP_VERSION_1_4;
1120
1121 if (dc->res_pool->dmcu != NULL)
1122 dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version;
1123 }
1124
1125
1126 dc->versions.dc_ver = DC_VER;
1127
1128 dc->build_id = DC_BUILD_ID;
1129
1130 DC_LOG_DC("Display Core initialized\n");
1131
1132
1133
1134 return dc;
1135
1136destruct_dc:
1137 dc_destruct(dc);
1138 kfree(dc);
1139 return NULL;
1140}
1141
1142static void detect_edp_presence(struct dc *dc)
1143{
1144 struct dc_link *edp_links[MAX_NUM_EDP];
1145 struct dc_link *edp_link = NULL;
1146 enum dc_connection_type type;
1147 int i;
1148 int edp_num;
1149
1150 get_edp_links(dc, edp_links, &edp_num);
1151 if (!edp_num)
1152 return;
1153
1154 for (i = 0; i < edp_num; i++) {
1155 edp_link = edp_links[i];
1156 if (dc->config.edp_not_connected) {
1157 edp_link->edp_sink_present = false;
1158 } else {
1159 dc_link_detect_sink(edp_link, &type);
1160 edp_link->edp_sink_present = (type != dc_connection_none);
1161 }
1162 }
1163}
1164
1165void dc_hardware_init(struct dc *dc)
1166{
1167
1168 detect_edp_presence(dc);
1169 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW)
1170 dc->hwss.init_hw(dc);
1171}
1172
1173void dc_init_callbacks(struct dc *dc,
1174 const struct dc_callback_init *init_params)
1175{
1176#ifdef CONFIG_DRM_AMD_DC_HDCP
1177 dc->ctx->cp_psp = init_params->cp_psp;
1178#endif
1179}
1180
1181void dc_deinit_callbacks(struct dc *dc)
1182{
1183#ifdef CONFIG_DRM_AMD_DC_HDCP
1184 memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp));
1185#endif
1186}
1187
1188void dc_destroy(struct dc **dc)
1189{
1190 dc_destruct(*dc);
1191 kfree(*dc);
1192 *dc = NULL;
1193}
1194
1195static void enable_timing_multisync(
1196 struct dc *dc,
1197 struct dc_state *ctx)
1198{
1199 int i, multisync_count = 0;
1200 int pipe_count = dc->res_pool->pipe_count;
1201 struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL };
1202
1203 for (i = 0; i < pipe_count; i++) {
1204 if (!ctx->res_ctx.pipe_ctx[i].stream ||
1205 !ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled)
1206 continue;
1207 if (ctx->res_ctx.pipe_ctx[i].stream == ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.event_source)
1208 continue;
1209 multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i];
1210 multisync_count++;
1211 }
1212
1213 if (multisync_count > 0) {
1214 dc->hwss.enable_per_frame_crtc_position_reset(
1215 dc, multisync_count, multisync_pipes);
1216 }
1217}
1218
1219static void program_timing_sync(
1220 struct dc *dc,
1221 struct dc_state *ctx)
1222{
1223 int i, j, k;
1224 int group_index = 0;
1225 int num_group = 0;
1226 int pipe_count = dc->res_pool->pipe_count;
1227 struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
1228
1229 for (i = 0; i < pipe_count; i++) {
1230 if (!ctx->res_ctx.pipe_ctx[i].stream || ctx->res_ctx.pipe_ctx[i].top_pipe)
1231 continue;
1232
1233 unsynced_pipes[i] = &ctx->res_ctx.pipe_ctx[i];
1234 }
1235
1236 for (i = 0; i < pipe_count; i++) {
1237 int group_size = 1;
1238 enum timing_synchronization_type sync_type = NOT_SYNCHRONIZABLE;
1239 struct pipe_ctx *pipe_set[MAX_PIPES];
1240
1241 if (!unsynced_pipes[i])
1242 continue;
1243
1244 pipe_set[0] = unsynced_pipes[i];
1245 unsynced_pipes[i] = NULL;
1246
1247
1248
1249
1250 for (j = i + 1; j < pipe_count; j++) {
1251 if (!unsynced_pipes[j])
1252 continue;
1253 if (sync_type != TIMING_SYNCHRONIZABLE &&
1254 dc->hwss.enable_vblanks_synchronization &&
1255 unsynced_pipes[j]->stream_res.tg->funcs->align_vblanks &&
1256 resource_are_vblanks_synchronizable(
1257 unsynced_pipes[j]->stream,
1258 pipe_set[0]->stream)) {
1259 sync_type = VBLANK_SYNCHRONIZABLE;
1260 pipe_set[group_size] = unsynced_pipes[j];
1261 unsynced_pipes[j] = NULL;
1262 group_size++;
1263 } else
1264 if (sync_type != VBLANK_SYNCHRONIZABLE &&
1265 resource_are_streams_timing_synchronizable(
1266 unsynced_pipes[j]->stream,
1267 pipe_set[0]->stream)) {
1268 sync_type = TIMING_SYNCHRONIZABLE;
1269 pipe_set[group_size] = unsynced_pipes[j];
1270 unsynced_pipes[j] = NULL;
1271 group_size++;
1272 }
1273 }
1274
1275
1276 for (j = 0; j < group_size; j++) {
1277 bool is_blanked;
1278
1279 if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
1280 is_blanked =
1281 pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
1282 else
1283 is_blanked =
1284 pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
1285 if (!is_blanked) {
1286 if (j == 0)
1287 break;
1288
1289 swap(pipe_set[0], pipe_set[j]);
1290 break;
1291 }
1292 }
1293
1294 for (k = 0; k < group_size; k++) {
1295 struct dc_stream_status *status = dc_stream_get_status_from_state(ctx, pipe_set[k]->stream);
1296
1297 status->timing_sync_info.group_id = num_group;
1298 status->timing_sync_info.group_size = group_size;
1299 if (k == 0)
1300 status->timing_sync_info.master = true;
1301 else
1302 status->timing_sync_info.master = false;
1303
1304 }
1305
1306 for (j = j + 1; j < group_size; j++) {
1307 bool is_blanked;
1308
1309 if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
1310 is_blanked =
1311 pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
1312 else
1313 is_blanked =
1314 pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
1315 if (!is_blanked) {
1316 group_size--;
1317 pipe_set[j] = pipe_set[group_size];
1318 j--;
1319 }
1320 }
1321
1322 if (group_size > 1) {
1323 if (sync_type == TIMING_SYNCHRONIZABLE) {
1324 dc->hwss.enable_timing_synchronization(
1325 dc, group_index, group_size, pipe_set);
1326 } else
1327 if (sync_type == VBLANK_SYNCHRONIZABLE) {
1328 dc->hwss.enable_vblanks_synchronization(
1329 dc, group_index, group_size, pipe_set);
1330 }
1331 group_index++;
1332 }
1333 num_group++;
1334 }
1335}
1336
1337static bool context_changed(
1338 struct dc *dc,
1339 struct dc_state *context)
1340{
1341 uint8_t i;
1342
1343 if (context->stream_count != dc->current_state->stream_count)
1344 return true;
1345
1346 for (i = 0; i < dc->current_state->stream_count; i++) {
1347 if (dc->current_state->streams[i] != context->streams[i])
1348 return true;
1349 }
1350
1351 return false;
1352}
1353
1354bool dc_validate_seamless_boot_timing(const struct dc *dc,
1355 const struct dc_sink *sink,
1356 struct dc_crtc_timing *crtc_timing)
1357{
1358 struct timing_generator *tg;
1359 struct stream_encoder *se = NULL;
1360
1361 struct dc_crtc_timing hw_crtc_timing = {0};
1362
1363 struct dc_link *link = sink->link;
1364 unsigned int i, enc_inst, tg_inst = 0;
1365
1366
1367 if (sink->sink_signal != SIGNAL_TYPE_EDP) {
1368 return false;
1369 }
1370
1371
1372 if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
1373 return false;
1374
1375 enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
1376
1377 if (enc_inst == ENGINE_ID_UNKNOWN)
1378 return false;
1379
1380 for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
1381 if (dc->res_pool->stream_enc[i]->id == enc_inst) {
1382
1383 se = dc->res_pool->stream_enc[i];
1384
1385 tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg(
1386 dc->res_pool->stream_enc[i]);
1387 break;
1388 }
1389 }
1390
1391
1392 if (i == dc->res_pool->stream_enc_count)
1393 return false;
1394
1395 if (tg_inst >= dc->res_pool->timing_generator_count)
1396 return false;
1397
1398 tg = dc->res_pool->timing_generators[tg_inst];
1399
1400 if (!tg->funcs->get_hw_timing)
1401 return false;
1402
1403 if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing))
1404 return false;
1405
1406 if (crtc_timing->h_total != hw_crtc_timing.h_total)
1407 return false;
1408
1409 if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left)
1410 return false;
1411
1412 if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable)
1413 return false;
1414
1415 if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right)
1416 return false;
1417
1418 if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch)
1419 return false;
1420
1421 if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width)
1422 return false;
1423
1424 if (crtc_timing->v_total != hw_crtc_timing.v_total)
1425 return false;
1426
1427 if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top)
1428 return false;
1429
1430 if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable)
1431 return false;
1432
1433 if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom)
1434 return false;
1435
1436 if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch)
1437 return false;
1438
1439 if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width)
1440 return false;
1441
1442
1443 if (crtc_timing->flags.DSC)
1444 return false;
1445
1446 if (dc_is_dp_signal(link->connector_signal)) {
1447 unsigned int pix_clk_100hz;
1448
1449 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1450 dc->res_pool->dp_clock_source,
1451 tg_inst, &pix_clk_100hz);
1452
1453 if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
1454 return false;
1455
1456 if (!se->funcs->dp_get_pixel_format)
1457 return false;
1458
1459 if (!se->funcs->dp_get_pixel_format(
1460 se,
1461 &hw_crtc_timing.pixel_encoding,
1462 &hw_crtc_timing.display_color_depth))
1463 return false;
1464
1465 if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth)
1466 return false;
1467
1468 if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding)
1469 return false;
1470 }
1471
1472 if (link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) {
1473 return false;
1474 }
1475
1476 if (is_edp_ilr_optimization_required(link, crtc_timing)) {
1477 DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n");
1478 return false;
1479 }
1480
1481 return true;
1482}
1483
1484static inline bool should_update_pipe_for_stream(
1485 struct dc_state *context,
1486 struct pipe_ctx *pipe_ctx,
1487 struct dc_stream_state *stream)
1488{
1489 return (pipe_ctx->stream && pipe_ctx->stream == stream);
1490}
1491
1492static inline bool should_update_pipe_for_plane(
1493 struct dc_state *context,
1494 struct pipe_ctx *pipe_ctx,
1495 struct dc_plane_state *plane_state)
1496{
1497 return (pipe_ctx->plane_state == plane_state);
1498}
1499
1500void dc_enable_stereo(
1501 struct dc *dc,
1502 struct dc_state *context,
1503 struct dc_stream_state *streams[],
1504 uint8_t stream_count)
1505{
1506 int i, j;
1507 struct pipe_ctx *pipe;
1508
1509 for (i = 0; i < MAX_PIPES; i++) {
1510 if (context != NULL) {
1511 pipe = &context->res_ctx.pipe_ctx[i];
1512 } else {
1513 context = dc->current_state;
1514 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1515 }
1516
1517 for (j = 0; pipe && j < stream_count; j++) {
1518 if (should_update_pipe_for_stream(context, pipe, streams[j]) &&
1519 dc->hwss.setup_stereo)
1520 dc->hwss.setup_stereo(pipe, dc);
1521 }
1522 }
1523}
1524
1525void dc_trigger_sync(struct dc *dc, struct dc_state *context)
1526{
1527 if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
1528 enable_timing_multisync(dc, context);
1529 program_timing_sync(dc, context);
1530 }
1531}
1532
1533static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context)
1534{
1535 int i;
1536 unsigned int stream_mask = 0;
1537
1538 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1539 if (context->res_ctx.pipe_ctx[i].stream)
1540 stream_mask |= 1 << i;
1541 }
1542
1543 return stream_mask;
1544}
1545
1546#if defined(CONFIG_DRM_AMD_DC_DCN)
1547void dc_z10_restore(struct dc *dc)
1548{
1549 if (dc->hwss.z10_restore)
1550 dc->hwss.z10_restore(dc);
1551}
1552
1553void dc_z10_save_init(struct dc *dc)
1554{
1555 if (dc->hwss.z10_save_init)
1556 dc->hwss.z10_save_init(dc);
1557}
1558#endif
1559
1560
1561
1562
1563static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
1564{
1565 struct dc_bios *dcb = dc->ctx->dc_bios;
1566 enum dc_status result = DC_ERROR_UNEXPECTED;
1567 struct pipe_ctx *pipe;
1568 int i, k, l;
1569 struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
1570
1571#if defined(CONFIG_DRM_AMD_DC_DCN)
1572 dc_z10_restore(dc);
1573 dc_allow_idle_optimizations(dc, false);
1574#endif
1575
1576 for (i = 0; i < context->stream_count; i++)
1577 dc_streams[i] = context->streams[i];
1578
1579 if (!dcb->funcs->is_accelerated_mode(dcb)) {
1580 disable_vbios_mode_if_required(dc, context);
1581 dc->hwss.enable_accelerated_mode(dc, context);
1582 }
1583
1584 if (context->stream_count > get_seamless_boot_stream_count(context) ||
1585 context->stream_count == 0)
1586 dc->hwss.prepare_bandwidth(dc, context);
1587
1588 disable_dangling_plane(dc, context);
1589
1590
1591
1592 if (dc->hwss.apply_ctx_for_surface) {
1593 for (i = 0; i < context->stream_count; i++) {
1594 if (context->streams[i]->mode_changed)
1595 continue;
1596 apply_ctx_interdependent_lock(dc, context, context->streams[i], true);
1597 dc->hwss.apply_ctx_for_surface(
1598 dc, context->streams[i],
1599 context->stream_status[i].plane_count,
1600 context);
1601 apply_ctx_interdependent_lock(dc, context, context->streams[i], false);
1602 dc->hwss.post_unlock_program_front_end(dc, context);
1603 }
1604 }
1605
1606
1607 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1608 pipe = &context->res_ctx.pipe_ctx[i];
1609 dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
1610 }
1611
1612 result = dc->hwss.apply_ctx_to_hw(dc, context);
1613
1614 if (result != DC_OK)
1615 return result;
1616
1617 dc_trigger_sync(dc, context);
1618
1619
1620 if (dc->hwss.program_front_end_for_ctx) {
1621 dc->hwss.interdependent_update_lock(dc, context, true);
1622 dc->hwss.program_front_end_for_ctx(dc, context);
1623 dc->hwss.interdependent_update_lock(dc, context, false);
1624 dc->hwss.post_unlock_program_front_end(dc, context);
1625 }
1626 for (i = 0; i < context->stream_count; i++) {
1627 const struct dc_link *link = context->streams[i]->link;
1628
1629 if (!context->streams[i]->mode_changed)
1630 continue;
1631
1632 if (dc->hwss.apply_ctx_for_surface) {
1633 apply_ctx_interdependent_lock(dc, context, context->streams[i], true);
1634 dc->hwss.apply_ctx_for_surface(
1635 dc, context->streams[i],
1636 context->stream_status[i].plane_count,
1637 context);
1638 apply_ctx_interdependent_lock(dc, context, context->streams[i], false);
1639 dc->hwss.post_unlock_program_front_end(dc, context);
1640 }
1641
1642
1643
1644
1645
1646 for (k = 0; k < MAX_PIPES; k++) {
1647 pipe = &context->res_ctx.pipe_ctx[k];
1648
1649 for (l = 0 ; pipe && l < context->stream_count; l++) {
1650 if (context->streams[l] &&
1651 context->streams[l] == pipe->stream &&
1652 dc->hwss.setup_stereo)
1653 dc->hwss.setup_stereo(pipe, dc);
1654 }
1655 }
1656
1657 CONN_MSG_MODE(link, "{%dx%d, %dx%d@%dKhz}",
1658 context->streams[i]->timing.h_addressable,
1659 context->streams[i]->timing.v_addressable,
1660 context->streams[i]->timing.h_total,
1661 context->streams[i]->timing.v_total,
1662 context->streams[i]->timing.pix_clk_100hz / 10);
1663 }
1664
1665 dc_enable_stereo(dc, context, dc_streams, context->stream_count);
1666
1667 if (context->stream_count > get_seamless_boot_stream_count(context) ||
1668 context->stream_count == 0) {
1669
1670 wait_for_no_pipes_pending(dc, context);
1671
1672 dc->hwss.optimize_bandwidth(dc, context);
1673 }
1674
1675 if (dc->ctx->dce_version >= DCE_VERSION_MAX)
1676 TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk);
1677 else
1678 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
1679
1680 context->stream_mask = get_stream_mask(dc, context);
1681
1682 if (context->stream_mask != dc->current_state->stream_mask)
1683 dc_dmub_srv_notify_stream_mask(dc->ctx->dmub_srv, context->stream_mask);
1684
1685 for (i = 0; i < context->stream_count; i++)
1686 context->streams[i]->mode_changed = false;
1687
1688 dc_release_state(dc->current_state);
1689
1690 dc->current_state = context;
1691
1692 dc_retain_state(dc->current_state);
1693
1694 return result;
1695}
1696
1697bool dc_commit_state(struct dc *dc, struct dc_state *context)
1698{
1699 enum dc_status result = DC_ERROR_UNEXPECTED;
1700 int i;
1701
1702 if (!context_changed(dc, context))
1703 return DC_OK;
1704
1705 DC_LOG_DC("%s: %d streams\n",
1706 __func__, context->stream_count);
1707
1708 for (i = 0; i < context->stream_count; i++) {
1709 struct dc_stream_state *stream = context->streams[i];
1710
1711 dc_stream_log(dc, stream);
1712 }
1713
1714 result = dc_commit_state_no_check(dc, context);
1715
1716 return (result == DC_OK);
1717}
1718
1719#if defined(CONFIG_DRM_AMD_DC_DCN)
1720bool dc_acquire_release_mpc_3dlut(
1721 struct dc *dc, bool acquire,
1722 struct dc_stream_state *stream,
1723 struct dc_3dlut **lut,
1724 struct dc_transfer_func **shaper)
1725{
1726 int pipe_idx;
1727 bool ret = false;
1728 bool found_pipe_idx = false;
1729 const struct resource_pool *pool = dc->res_pool;
1730 struct resource_context *res_ctx = &dc->current_state->res_ctx;
1731 int mpcc_id = 0;
1732
1733 if (pool && res_ctx) {
1734 if (acquire) {
1735
1736 for (pipe_idx = 0; pipe_idx < pool->pipe_count; pipe_idx++) {
1737 if (res_ctx->pipe_ctx[pipe_idx].stream == stream) {
1738 found_pipe_idx = true;
1739 mpcc_id = res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst;
1740 break;
1741 }
1742 }
1743 } else
1744 found_pipe_idx = true;
1745
1746 if (found_pipe_idx) {
1747 if (acquire && pool->funcs->acquire_post_bldn_3dlut)
1748 ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper);
1749 else if (!acquire && pool->funcs->release_post_bldn_3dlut)
1750 ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper);
1751 }
1752 }
1753 return ret;
1754}
1755#endif
1756static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
1757{
1758 int i;
1759 struct pipe_ctx *pipe;
1760
1761 for (i = 0; i < MAX_PIPES; i++) {
1762 pipe = &context->res_ctx.pipe_ctx[i];
1763
1764 if (!pipe->plane_state)
1765 continue;
1766
1767
1768 pipe->plane_state->status.is_flip_pending = false;
1769 dc->hwss.update_pending_status(pipe);
1770 if (pipe->plane_state->status.is_flip_pending)
1771 return true;
1772 }
1773 return false;
1774}
1775
1776void dc_post_update_surfaces_to_stream(struct dc *dc)
1777{
1778 int i;
1779 struct dc_state *context = dc->current_state;
1780
1781 if ((!dc->optimized_required) || get_seamless_boot_stream_count(context) > 0)
1782 return;
1783
1784 post_surface_trace(dc);
1785
1786 if (is_flip_pending_in_pipes(dc, context))
1787 return;
1788
1789 for (i = 0; i < dc->res_pool->pipe_count; i++)
1790 if (context->res_ctx.pipe_ctx[i].stream == NULL ||
1791 context->res_ctx.pipe_ctx[i].plane_state == NULL) {
1792 context->res_ctx.pipe_ctx[i].pipe_idx = i;
1793 dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
1794 }
1795
1796 dc->hwss.optimize_bandwidth(dc, context);
1797
1798 dc->optimized_required = false;
1799 dc->wm_optimized_required = false;
1800}
1801
1802static void init_state(struct dc *dc, struct dc_state *context)
1803{
1804
1805
1806
1807
1808#ifdef CONFIG_DRM_AMD_DC_DCN
1809 memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib));
1810#endif
1811}
1812
1813struct dc_state *dc_create_state(struct dc *dc)
1814{
1815 struct dc_state *context = kvzalloc(sizeof(struct dc_state),
1816 GFP_KERNEL);
1817
1818 if (!context)
1819 return NULL;
1820
1821 init_state(dc, context);
1822
1823 kref_init(&context->refcount);
1824
1825 return context;
1826}
1827
1828struct dc_state *dc_copy_state(struct dc_state *src_ctx)
1829{
1830 int i, j;
1831 struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL);
1832
1833 if (!new_ctx)
1834 return NULL;
1835 memcpy(new_ctx, src_ctx, sizeof(struct dc_state));
1836
1837 for (i = 0; i < MAX_PIPES; i++) {
1838 struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i];
1839
1840 if (cur_pipe->top_pipe)
1841 cur_pipe->top_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx];
1842
1843 if (cur_pipe->bottom_pipe)
1844 cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx];
1845
1846 if (cur_pipe->prev_odm_pipe)
1847 cur_pipe->prev_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->prev_odm_pipe->pipe_idx];
1848
1849 if (cur_pipe->next_odm_pipe)
1850 cur_pipe->next_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->next_odm_pipe->pipe_idx];
1851
1852 }
1853
1854 for (i = 0; i < new_ctx->stream_count; i++) {
1855 dc_stream_retain(new_ctx->streams[i]);
1856 for (j = 0; j < new_ctx->stream_status[i].plane_count; j++)
1857 dc_plane_state_retain(
1858 new_ctx->stream_status[i].plane_states[j]);
1859 }
1860
1861 kref_init(&new_ctx->refcount);
1862
1863 return new_ctx;
1864}
1865
1866void dc_retain_state(struct dc_state *context)
1867{
1868 kref_get(&context->refcount);
1869}
1870
1871static void dc_state_free(struct kref *kref)
1872{
1873 struct dc_state *context = container_of(kref, struct dc_state, refcount);
1874 dc_resource_state_destruct(context);
1875 kvfree(context);
1876}
1877
1878void dc_release_state(struct dc_state *context)
1879{
1880 kref_put(&context->refcount, dc_state_free);
1881}
1882
1883bool dc_set_generic_gpio_for_stereo(bool enable,
1884 struct gpio_service *gpio_service)
1885{
1886 enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR;
1887 struct gpio_pin_info pin_info;
1888 struct gpio *generic;
1889 struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config),
1890 GFP_KERNEL);
1891
1892 if (!config)
1893 return false;
1894 pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0);
1895
1896 if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) {
1897 kfree(config);
1898 return false;
1899 } else {
1900 generic = dal_gpio_service_create_generic_mux(
1901 gpio_service,
1902 pin_info.offset,
1903 pin_info.mask);
1904 }
1905
1906 if (!generic) {
1907 kfree(config);
1908 return false;
1909 }
1910
1911 gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT);
1912
1913 config->enable_output_from_mux = enable;
1914 config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC;
1915
1916 if (gpio_result == GPIO_RESULT_OK)
1917 gpio_result = dal_mux_setup_config(generic, config);
1918
1919 if (gpio_result == GPIO_RESULT_OK) {
1920 dal_gpio_close(generic);
1921 dal_gpio_destroy_generic_mux(&generic);
1922 kfree(config);
1923 return true;
1924 } else {
1925 dal_gpio_close(generic);
1926 dal_gpio_destroy_generic_mux(&generic);
1927 kfree(config);
1928 return false;
1929 }
1930}
1931
1932static bool is_surface_in_context(
1933 const struct dc_state *context,
1934 const struct dc_plane_state *plane_state)
1935{
1936 int j;
1937
1938 for (j = 0; j < MAX_PIPES; j++) {
1939 const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1940
1941 if (plane_state == pipe_ctx->plane_state) {
1942 return true;
1943 }
1944 }
1945
1946 return false;
1947}
1948
1949static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
1950{
1951 union surface_update_flags *update_flags = &u->surface->update_flags;
1952 enum surface_update_type update_type = UPDATE_TYPE_FAST;
1953
1954 if (!u->plane_info)
1955 return UPDATE_TYPE_FAST;
1956
1957 if (u->plane_info->color_space != u->surface->color_space) {
1958 update_flags->bits.color_space_change = 1;
1959 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1960 }
1961
1962 if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror) {
1963 update_flags->bits.horizontal_mirror_change = 1;
1964 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1965 }
1966
1967 if (u->plane_info->rotation != u->surface->rotation) {
1968 update_flags->bits.rotation_change = 1;
1969 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1970 }
1971
1972 if (u->plane_info->format != u->surface->format) {
1973 update_flags->bits.pixel_format_change = 1;
1974 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1975 }
1976
1977 if (u->plane_info->stereo_format != u->surface->stereo_format) {
1978 update_flags->bits.stereo_format_change = 1;
1979 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1980 }
1981
1982 if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha) {
1983 update_flags->bits.per_pixel_alpha_change = 1;
1984 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1985 }
1986
1987 if (u->plane_info->global_alpha_value != u->surface->global_alpha_value) {
1988 update_flags->bits.global_alpha_change = 1;
1989 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1990 }
1991
1992 if (u->plane_info->dcc.enable != u->surface->dcc.enable
1993 || u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks
1994 || u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) {
1995
1996
1997
1998
1999
2000 update_flags->bits.dcc_change = 1;
2001 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2002 }
2003
2004 if (resource_pixel_format_to_bpp(u->plane_info->format) !=
2005 resource_pixel_format_to_bpp(u->surface->format)) {
2006
2007
2008
2009 update_flags->bits.bpp_change = 1;
2010 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2011 }
2012
2013 if (u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
2014 || u->plane_info->plane_size.chroma_pitch != u->surface->plane_size.chroma_pitch) {
2015 update_flags->bits.plane_size_change = 1;
2016 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2017 }
2018
2019
2020 if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
2021 sizeof(union dc_tiling_info)) != 0) {
2022 update_flags->bits.swizzle_change = 1;
2023 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2024
2025
2026
2027
2028 if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
2029
2030
2031
2032 update_flags->bits.bandwidth_change = 1;
2033 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2034 }
2035 }
2036
2037
2038 return update_type;
2039}
2040
2041static enum surface_update_type get_scaling_info_update_type(
2042 const struct dc_surface_update *u)
2043{
2044 union surface_update_flags *update_flags = &u->surface->update_flags;
2045
2046 if (!u->scaling_info)
2047 return UPDATE_TYPE_FAST;
2048
2049 if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width
2050 || u->scaling_info->clip_rect.height != u->surface->clip_rect.height
2051 || u->scaling_info->dst_rect.width != u->surface->dst_rect.width
2052 || u->scaling_info->dst_rect.height != u->surface->dst_rect.height
2053 || u->scaling_info->scaling_quality.integer_scaling !=
2054 u->surface->scaling_quality.integer_scaling
2055 ) {
2056 update_flags->bits.scaling_change = 1;
2057
2058 if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width
2059 || u->scaling_info->dst_rect.height < u->surface->dst_rect.height)
2060 && (u->scaling_info->dst_rect.width < u->surface->src_rect.width
2061 || u->scaling_info->dst_rect.height < u->surface->src_rect.height))
2062
2063 update_flags->bits.bandwidth_change = 1;
2064 }
2065
2066 if (u->scaling_info->src_rect.width != u->surface->src_rect.width
2067 || u->scaling_info->src_rect.height != u->surface->src_rect.height) {
2068
2069 update_flags->bits.scaling_change = 1;
2070 if (u->scaling_info->src_rect.width > u->surface->src_rect.width
2071 || u->scaling_info->src_rect.height > u->surface->src_rect.height)
2072
2073 update_flags->bits.clock_change = 1;
2074 }
2075
2076 if (u->scaling_info->src_rect.x != u->surface->src_rect.x
2077 || u->scaling_info->src_rect.y != u->surface->src_rect.y
2078 || u->scaling_info->clip_rect.x != u->surface->clip_rect.x
2079 || u->scaling_info->clip_rect.y != u->surface->clip_rect.y
2080 || u->scaling_info->dst_rect.x != u->surface->dst_rect.x
2081 || u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
2082 update_flags->bits.position_change = 1;
2083
2084 if (update_flags->bits.clock_change
2085 || update_flags->bits.bandwidth_change
2086 || update_flags->bits.scaling_change)
2087 return UPDATE_TYPE_FULL;
2088
2089 if (update_flags->bits.position_change)
2090 return UPDATE_TYPE_MED;
2091
2092 return UPDATE_TYPE_FAST;
2093}
2094
2095static enum surface_update_type det_surface_update(const struct dc *dc,
2096 const struct dc_surface_update *u)
2097{
2098 const struct dc_state *context = dc->current_state;
2099 enum surface_update_type type;
2100 enum surface_update_type overall_type = UPDATE_TYPE_FAST;
2101 union surface_update_flags *update_flags = &u->surface->update_flags;
2102
2103 if (u->flip_addr)
2104 update_flags->bits.addr_update = 1;
2105
2106 if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) {
2107 update_flags->raw = 0xFFFFFFFF;
2108 return UPDATE_TYPE_FULL;
2109 }
2110
2111 update_flags->raw = 0;
2112
2113 type = get_plane_info_update_type(u);
2114 elevate_update_type(&overall_type, type);
2115
2116 type = get_scaling_info_update_type(u);
2117 elevate_update_type(&overall_type, type);
2118
2119 if (u->flip_addr)
2120 update_flags->bits.addr_update = 1;
2121
2122 if (u->in_transfer_func)
2123 update_flags->bits.in_transfer_func_change = 1;
2124
2125 if (u->input_csc_color_matrix)
2126 update_flags->bits.input_csc_change = 1;
2127
2128 if (u->coeff_reduction_factor)
2129 update_flags->bits.coeff_reduction_change = 1;
2130
2131 if (u->gamut_remap_matrix)
2132 update_flags->bits.gamut_remap_change = 1;
2133
2134 if (u->gamma) {
2135 enum surface_pixel_format format = SURFACE_PIXEL_FORMAT_GRPH_BEGIN;
2136
2137 if (u->plane_info)
2138 format = u->plane_info->format;
2139 else if (u->surface)
2140 format = u->surface->format;
2141
2142 if (dce_use_lut(format))
2143 update_flags->bits.gamma_change = 1;
2144 }
2145
2146 if (u->hdr_mult.value)
2147 if (u->hdr_mult.value != u->surface->hdr_mult.value) {
2148 update_flags->bits.hdr_mult = 1;
2149 elevate_update_type(&overall_type, UPDATE_TYPE_MED);
2150 }
2151
2152 if (update_flags->bits.in_transfer_func_change) {
2153 type = UPDATE_TYPE_MED;
2154 elevate_update_type(&overall_type, type);
2155 }
2156
2157 if (update_flags->bits.input_csc_change
2158 || update_flags->bits.coeff_reduction_change
2159 || update_flags->bits.gamma_change
2160 || update_flags->bits.gamut_remap_change) {
2161 type = UPDATE_TYPE_FULL;
2162 elevate_update_type(&overall_type, type);
2163 }
2164
2165 return overall_type;
2166}
2167
2168static enum surface_update_type check_update_surfaces_for_stream(
2169 struct dc *dc,
2170 struct dc_surface_update *updates,
2171 int surface_count,
2172 struct dc_stream_update *stream_update,
2173 const struct dc_stream_status *stream_status)
2174{
2175 int i;
2176 enum surface_update_type overall_type = UPDATE_TYPE_FAST;
2177
2178#if defined(CONFIG_DRM_AMD_DC_DCN)
2179 if (dc->idle_optimizations_allowed)
2180 overall_type = UPDATE_TYPE_FULL;
2181
2182#endif
2183 if (stream_status == NULL || stream_status->plane_count != surface_count)
2184 overall_type = UPDATE_TYPE_FULL;
2185
2186 if (stream_update && stream_update->pending_test_pattern) {
2187 overall_type = UPDATE_TYPE_FULL;
2188 }
2189
2190
2191 if (stream_update) {
2192 union stream_update_flags *su_flags = &stream_update->stream->update_flags;
2193
2194 if ((stream_update->src.height != 0 && stream_update->src.width != 0) ||
2195 (stream_update->dst.height != 0 && stream_update->dst.width != 0) ||
2196 stream_update->integer_scaling_update)
2197 su_flags->bits.scaling = 1;
2198
2199 if (stream_update->out_transfer_func)
2200 su_flags->bits.out_tf = 1;
2201
2202 if (stream_update->abm_level)
2203 su_flags->bits.abm_level = 1;
2204
2205 if (stream_update->dpms_off)
2206 su_flags->bits.dpms_off = 1;
2207
2208 if (stream_update->gamut_remap)
2209 su_flags->bits.gamut_remap = 1;
2210
2211 if (stream_update->wb_update)
2212 su_flags->bits.wb_update = 1;
2213
2214 if (stream_update->dsc_config)
2215 su_flags->bits.dsc_changed = 1;
2216
2217 if (su_flags->raw != 0)
2218 overall_type = UPDATE_TYPE_FULL;
2219
2220 if (stream_update->output_csc_transform || stream_update->output_color_space)
2221 su_flags->bits.out_csc = 1;
2222 }
2223
2224 for (i = 0 ; i < surface_count; i++) {
2225 enum surface_update_type type =
2226 det_surface_update(dc, &updates[i]);
2227
2228 elevate_update_type(&overall_type, type);
2229 }
2230
2231 return overall_type;
2232}
2233
2234
2235
2236
2237
2238
2239enum surface_update_type dc_check_update_surfaces_for_stream(
2240 struct dc *dc,
2241 struct dc_surface_update *updates,
2242 int surface_count,
2243 struct dc_stream_update *stream_update,
2244 const struct dc_stream_status *stream_status)
2245{
2246 int i;
2247 enum surface_update_type type;
2248
2249 if (stream_update)
2250 stream_update->stream->update_flags.raw = 0;
2251 for (i = 0; i < surface_count; i++)
2252 updates[i].surface->update_flags.raw = 0;
2253
2254 type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
2255 if (type == UPDATE_TYPE_FULL) {
2256 if (stream_update) {
2257 uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed;
2258 stream_update->stream->update_flags.raw = 0xFFFFFFFF;
2259 stream_update->stream->update_flags.bits.dsc_changed = dsc_changed;
2260 }
2261 for (i = 0; i < surface_count; i++)
2262 updates[i].surface->update_flags.raw = 0xFFFFFFFF;
2263 }
2264
2265 if (type == UPDATE_TYPE_FAST) {
2266
2267 if (dc->clk_mgr->funcs->are_clock_states_equal) {
2268 if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk))
2269 dc->optimized_required = true;
2270
2271 } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
2272 dc->optimized_required = true;
2273 }
2274
2275 dc->optimized_required |= dc->wm_optimized_required;
2276 }
2277
2278 return type;
2279}
2280
2281static struct dc_stream_status *stream_get_status(
2282 struct dc_state *ctx,
2283 struct dc_stream_state *stream)
2284{
2285 uint8_t i;
2286
2287 for (i = 0; i < ctx->stream_count; i++) {
2288 if (stream == ctx->streams[i]) {
2289 return &ctx->stream_status[i];
2290 }
2291 }
2292
2293 return NULL;
2294}
2295
2296static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
2297
2298static void copy_surface_update_to_plane(
2299 struct dc_plane_state *surface,
2300 struct dc_surface_update *srf_update)
2301{
2302 if (srf_update->flip_addr) {
2303 surface->address = srf_update->flip_addr->address;
2304 surface->flip_immediate =
2305 srf_update->flip_addr->flip_immediate;
2306 surface->time.time_elapsed_in_us[surface->time.index] =
2307 srf_update->flip_addr->flip_timestamp_in_us -
2308 surface->time.prev_update_time_in_us;
2309 surface->time.prev_update_time_in_us =
2310 srf_update->flip_addr->flip_timestamp_in_us;
2311 surface->time.index++;
2312 if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
2313 surface->time.index = 0;
2314
2315 surface->triplebuffer_flips = srf_update->flip_addr->triplebuffer_flips;
2316 }
2317
2318 if (srf_update->scaling_info) {
2319 surface->scaling_quality =
2320 srf_update->scaling_info->scaling_quality;
2321 surface->dst_rect =
2322 srf_update->scaling_info->dst_rect;
2323 surface->src_rect =
2324 srf_update->scaling_info->src_rect;
2325 surface->clip_rect =
2326 srf_update->scaling_info->clip_rect;
2327 }
2328
2329 if (srf_update->plane_info) {
2330 surface->color_space =
2331 srf_update->plane_info->color_space;
2332 surface->format =
2333 srf_update->plane_info->format;
2334 surface->plane_size =
2335 srf_update->plane_info->plane_size;
2336 surface->rotation =
2337 srf_update->plane_info->rotation;
2338 surface->horizontal_mirror =
2339 srf_update->plane_info->horizontal_mirror;
2340 surface->stereo_format =
2341 srf_update->plane_info->stereo_format;
2342 surface->tiling_info =
2343 srf_update->plane_info->tiling_info;
2344 surface->visible =
2345 srf_update->plane_info->visible;
2346 surface->per_pixel_alpha =
2347 srf_update->plane_info->per_pixel_alpha;
2348 surface->global_alpha =
2349 srf_update->plane_info->global_alpha;
2350 surface->global_alpha_value =
2351 srf_update->plane_info->global_alpha_value;
2352 surface->dcc =
2353 srf_update->plane_info->dcc;
2354 surface->layer_index =
2355 srf_update->plane_info->layer_index;
2356 }
2357
2358 if (srf_update->gamma &&
2359 (surface->gamma_correction !=
2360 srf_update->gamma)) {
2361 memcpy(&surface->gamma_correction->entries,
2362 &srf_update->gamma->entries,
2363 sizeof(struct dc_gamma_entries));
2364 surface->gamma_correction->is_identity =
2365 srf_update->gamma->is_identity;
2366 surface->gamma_correction->num_entries =
2367 srf_update->gamma->num_entries;
2368 surface->gamma_correction->type =
2369 srf_update->gamma->type;
2370 }
2371
2372 if (srf_update->in_transfer_func &&
2373 (surface->in_transfer_func !=
2374 srf_update->in_transfer_func)) {
2375 surface->in_transfer_func->sdr_ref_white_level =
2376 srf_update->in_transfer_func->sdr_ref_white_level;
2377 surface->in_transfer_func->tf =
2378 srf_update->in_transfer_func->tf;
2379 surface->in_transfer_func->type =
2380 srf_update->in_transfer_func->type;
2381 memcpy(&surface->in_transfer_func->tf_pts,
2382 &srf_update->in_transfer_func->tf_pts,
2383 sizeof(struct dc_transfer_func_distributed_points));
2384 }
2385
2386 if (srf_update->func_shaper &&
2387 (surface->in_shaper_func !=
2388 srf_update->func_shaper))
2389 memcpy(surface->in_shaper_func, srf_update->func_shaper,
2390 sizeof(*surface->in_shaper_func));
2391
2392 if (srf_update->lut3d_func &&
2393 (surface->lut3d_func !=
2394 srf_update->lut3d_func))
2395 memcpy(surface->lut3d_func, srf_update->lut3d_func,
2396 sizeof(*surface->lut3d_func));
2397
2398 if (srf_update->hdr_mult.value)
2399 surface->hdr_mult =
2400 srf_update->hdr_mult;
2401
2402 if (srf_update->blend_tf &&
2403 (surface->blend_tf !=
2404 srf_update->blend_tf))
2405 memcpy(surface->blend_tf, srf_update->blend_tf,
2406 sizeof(*surface->blend_tf));
2407
2408 if (srf_update->input_csc_color_matrix)
2409 surface->input_csc_color_matrix =
2410 *srf_update->input_csc_color_matrix;
2411
2412 if (srf_update->coeff_reduction_factor)
2413 surface->coeff_reduction_factor =
2414 *srf_update->coeff_reduction_factor;
2415
2416 if (srf_update->gamut_remap_matrix)
2417 surface->gamut_remap_matrix =
2418 *srf_update->gamut_remap_matrix;
2419}
2420
2421static void copy_stream_update_to_stream(struct dc *dc,
2422 struct dc_state *context,
2423 struct dc_stream_state *stream,
2424 struct dc_stream_update *update)
2425{
2426 struct dc_context *dc_ctx = dc->ctx;
2427
2428 if (update == NULL || stream == NULL)
2429 return;
2430
2431 if (update->src.height && update->src.width)
2432 stream->src = update->src;
2433
2434 if (update->dst.height && update->dst.width)
2435 stream->dst = update->dst;
2436
2437 if (update->out_transfer_func &&
2438 stream->out_transfer_func != update->out_transfer_func) {
2439 stream->out_transfer_func->sdr_ref_white_level =
2440 update->out_transfer_func->sdr_ref_white_level;
2441 stream->out_transfer_func->tf = update->out_transfer_func->tf;
2442 stream->out_transfer_func->type =
2443 update->out_transfer_func->type;
2444 memcpy(&stream->out_transfer_func->tf_pts,
2445 &update->out_transfer_func->tf_pts,
2446 sizeof(struct dc_transfer_func_distributed_points));
2447 }
2448
2449 if (update->hdr_static_metadata)
2450 stream->hdr_static_metadata = *update->hdr_static_metadata;
2451
2452 if (update->abm_level)
2453 stream->abm_level = *update->abm_level;
2454
2455 if (update->periodic_interrupt0)
2456 stream->periodic_interrupt0 = *update->periodic_interrupt0;
2457
2458 if (update->periodic_interrupt1)
2459 stream->periodic_interrupt1 = *update->periodic_interrupt1;
2460
2461 if (update->gamut_remap)
2462 stream->gamut_remap_matrix = *update->gamut_remap;
2463
2464
2465
2466
2467
2468 if (update->output_color_space)
2469 stream->output_color_space = *update->output_color_space;
2470
2471 if (update->output_csc_transform)
2472 stream->csc_color_matrix = *update->output_csc_transform;
2473
2474 if (update->vrr_infopacket)
2475 stream->vrr_infopacket = *update->vrr_infopacket;
2476
2477 if (update->dpms_off)
2478 stream->dpms_off = *update->dpms_off;
2479
2480 if (update->vsc_infopacket)
2481 stream->vsc_infopacket = *update->vsc_infopacket;
2482
2483 if (update->vsp_infopacket)
2484 stream->vsp_infopacket = *update->vsp_infopacket;
2485
2486 if (update->dither_option)
2487 stream->dither_option = *update->dither_option;
2488
2489 if (update->pending_test_pattern)
2490 stream->test_pattern = *update->pending_test_pattern;
2491
2492 if (update->wb_update) {
2493 int i;
2494
2495 stream->num_wb_info = update->wb_update->num_wb_info;
2496 ASSERT(stream->num_wb_info <= MAX_DWB_PIPES);
2497 for (i = 0; i < stream->num_wb_info; i++)
2498 stream->writeback_info[i] =
2499 update->wb_update->writeback_info[i];
2500 }
2501 if (update->dsc_config) {
2502 struct dc_dsc_config old_dsc_cfg = stream->timing.dsc_cfg;
2503 uint32_t old_dsc_enabled = stream->timing.flags.DSC;
2504 uint32_t enable_dsc = (update->dsc_config->num_slices_h != 0 &&
2505 update->dsc_config->num_slices_v != 0);
2506
2507
2508 struct dc_state *dsc_validate_context = dc_create_state(dc);
2509
2510 if (dsc_validate_context) {
2511 dc_resource_state_copy_construct(dc->current_state, dsc_validate_context);
2512
2513 stream->timing.dsc_cfg = *update->dsc_config;
2514 stream->timing.flags.DSC = enable_dsc;
2515 if (!dc->res_pool->funcs->validate_bandwidth(dc, dsc_validate_context, true)) {
2516 stream->timing.dsc_cfg = old_dsc_cfg;
2517 stream->timing.flags.DSC = old_dsc_enabled;
2518 update->dsc_config = NULL;
2519 }
2520
2521 dc_release_state(dsc_validate_context);
2522 } else {
2523 DC_ERROR("Failed to allocate new validate context for DSC change\n");
2524 update->dsc_config = NULL;
2525 }
2526 }
2527}
2528
2529static void commit_planes_do_stream_update(struct dc *dc,
2530 struct dc_stream_state *stream,
2531 struct dc_stream_update *stream_update,
2532 enum surface_update_type update_type,
2533 struct dc_state *context)
2534{
2535 int j;
2536
2537
2538 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2539 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2540
2541 if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) {
2542
2543 if (stream_update->periodic_interrupt0 &&
2544 dc->hwss.setup_periodic_interrupt)
2545 dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE0);
2546
2547 if (stream_update->periodic_interrupt1 &&
2548 dc->hwss.setup_periodic_interrupt)
2549 dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE1);
2550
2551 if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
2552 stream_update->vrr_infopacket ||
2553 stream_update->vsc_infopacket ||
2554 stream_update->vsp_infopacket) {
2555 resource_build_info_frame(pipe_ctx);
2556 dc->hwss.update_info_frame(pipe_ctx);
2557 }
2558
2559 if (stream_update->hdr_static_metadata &&
2560 stream->use_dynamic_meta &&
2561 dc->hwss.set_dmdata_attributes &&
2562 pipe_ctx->stream->dmdata_address.quad_part != 0)
2563 dc->hwss.set_dmdata_attributes(pipe_ctx);
2564
2565 if (stream_update->gamut_remap)
2566 dc_stream_set_gamut_remap(dc, stream);
2567
2568 if (stream_update->output_csc_transform)
2569 dc_stream_program_csc_matrix(dc, stream);
2570
2571 if (stream_update->dither_option) {
2572 struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
2573 resource_build_bit_depth_reduction_params(pipe_ctx->stream,
2574 &pipe_ctx->stream->bit_depth_params);
2575 pipe_ctx->stream_res.opp->funcs->opp_program_fmt(pipe_ctx->stream_res.opp,
2576 &stream->bit_depth_params,
2577 &stream->clamping);
2578 while (odm_pipe) {
2579 odm_pipe->stream_res.opp->funcs->opp_program_fmt(odm_pipe->stream_res.opp,
2580 &stream->bit_depth_params,
2581 &stream->clamping);
2582 odm_pipe = odm_pipe->next_odm_pipe;
2583 }
2584 }
2585
2586
2587
2588 if (update_type == UPDATE_TYPE_FAST)
2589 continue;
2590
2591 if (stream_update->dsc_config)
2592 dp_update_dsc_config(pipe_ctx);
2593
2594 if (stream_update->pending_test_pattern) {
2595 dc_link_dp_set_test_pattern(stream->link,
2596 stream->test_pattern.type,
2597 stream->test_pattern.color_space,
2598 stream->test_pattern.p_link_settings,
2599 stream->test_pattern.p_custom_pattern,
2600 stream->test_pattern.cust_pattern_size);
2601 }
2602
2603 if (stream_update->dpms_off) {
2604 if (*stream_update->dpms_off) {
2605 core_link_disable_stream(pipe_ctx);
2606
2607 if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
2608 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
2609
2610 dc->optimized_required = true;
2611
2612 } else {
2613 if (get_seamless_boot_stream_count(context) == 0)
2614 dc->hwss.prepare_bandwidth(dc, dc->current_state);
2615
2616 core_link_enable_stream(dc->current_state, pipe_ctx);
2617 }
2618 }
2619
2620 if (stream_update->abm_level && pipe_ctx->stream_res.abm) {
2621 bool should_program_abm = true;
2622
2623
2624 if (pipe_ctx->stream_res.tg->funcs->is_blanked)
2625 if (pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg))
2626 should_program_abm = false;
2627
2628 if (should_program_abm) {
2629 if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
2630 dc->hwss.set_abm_immediate_disable(pipe_ctx);
2631 } else {
2632 pipe_ctx->stream_res.abm->funcs->set_abm_level(
2633 pipe_ctx->stream_res.abm, stream->abm_level);
2634 }
2635 }
2636 }
2637 }
2638 }
2639}
2640
2641static void commit_planes_for_stream(struct dc *dc,
2642 struct dc_surface_update *srf_updates,
2643 int surface_count,
2644 struct dc_stream_state *stream,
2645 struct dc_stream_update *stream_update,
2646 enum surface_update_type update_type,
2647 struct dc_state *context)
2648{
2649 int i, j;
2650 struct pipe_ctx *top_pipe_to_program = NULL;
2651 bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST);
2652
2653#if defined(CONFIG_DRM_AMD_DC_DCN)
2654 dc_z10_restore(dc);
2655#endif
2656
2657 if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) {
2658
2659
2660
2661
2662
2663
2664 if (stream->apply_seamless_boot_optimization) {
2665 stream->apply_seamless_boot_optimization = false;
2666
2667 if (get_seamless_boot_stream_count(context) == 0)
2668 dc->optimized_required = true;
2669 }
2670 }
2671
2672 if (update_type == UPDATE_TYPE_FULL) {
2673#if defined(CONFIG_DRM_AMD_DC_DCN)
2674 dc_allow_idle_optimizations(dc, false);
2675
2676#endif
2677 if (get_seamless_boot_stream_count(context) == 0)
2678 dc->hwss.prepare_bandwidth(dc, context);
2679
2680 context_clock_trace(dc, context);
2681 }
2682
2683 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2684 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2685
2686 if (!pipe_ctx->top_pipe &&
2687 !pipe_ctx->prev_odm_pipe &&
2688 pipe_ctx->stream &&
2689 pipe_ctx->stream == stream) {
2690 top_pipe_to_program = pipe_ctx;
2691 }
2692 }
2693
2694#ifdef CONFIG_DRM_AMD_DC_DCN
2695 if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) {
2696 struct pipe_ctx *mpcc_pipe;
2697 struct pipe_ctx *odm_pipe;
2698
2699 for (mpcc_pipe = top_pipe_to_program; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe)
2700 for (odm_pipe = mpcc_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
2701 odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU;
2702 }
2703#endif
2704
2705 if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
2706 if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
2707 if (should_use_dmub_lock(stream->link)) {
2708 union dmub_hw_lock_flags hw_locks = { 0 };
2709 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
2710
2711 hw_locks.bits.lock_dig = 1;
2712 inst_flags.dig_inst = top_pipe_to_program->stream_res.tg->inst;
2713
2714 dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
2715 true,
2716 &hw_locks,
2717 &inst_flags);
2718 } else
2719 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable(
2720 top_pipe_to_program->stream_res.tg);
2721 }
2722
2723 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock)
2724 dc->hwss.interdependent_update_lock(dc, context, true);
2725 else
2726
2727
2728
2729
2730 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
2731
2732
2733 if (stream_update)
2734 commit_planes_do_stream_update(dc, stream, stream_update, update_type, context);
2735
2736 if (surface_count == 0) {
2737
2738
2739
2740
2741 if (dc->hwss.apply_ctx_for_surface)
2742 dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
2743 if (dc->hwss.program_front_end_for_ctx)
2744 dc->hwss.program_front_end_for_ctx(dc, context);
2745
2746 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock)
2747 dc->hwss.interdependent_update_lock(dc, context, false);
2748 else
2749 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
2750 dc->hwss.post_unlock_program_front_end(dc, context);
2751 return;
2752 }
2753
2754 if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
2755 for (i = 0; i < surface_count; i++) {
2756 struct dc_plane_state *plane_state = srf_updates[i].surface;
2757
2758 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2759 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2760 if (!pipe_ctx->plane_state)
2761 continue;
2762 if (should_update_pipe_for_plane(context, pipe_ctx, plane_state))
2763 continue;
2764 pipe_ctx->plane_state->triplebuffer_flips = false;
2765 if (update_type == UPDATE_TYPE_FAST &&
2766 dc->hwss.program_triplebuffer != NULL &&
2767 !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) {
2768
2769 pipe_ctx->plane_state->triplebuffer_flips = true;
2770 }
2771 }
2772 if (update_type == UPDATE_TYPE_FULL) {
2773
2774 plane_state->flip_immediate = false;
2775 }
2776 }
2777 }
2778
2779
2780 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2781 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2782
2783 if (!pipe_ctx->top_pipe &&
2784 !pipe_ctx->prev_odm_pipe &&
2785 should_update_pipe_for_stream(context, pipe_ctx, stream)) {
2786 struct dc_stream_status *stream_status = NULL;
2787
2788 if (!pipe_ctx->plane_state)
2789 continue;
2790
2791
2792 if (update_type == UPDATE_TYPE_FAST)
2793 continue;
2794
2795 ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
2796
2797 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
2798
2799 dc->hwss.program_triplebuffer(
2800 dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
2801 }
2802 stream_status =
2803 stream_get_status(context, pipe_ctx->stream);
2804
2805 if (dc->hwss.apply_ctx_for_surface)
2806 dc->hwss.apply_ctx_for_surface(
2807 dc, pipe_ctx->stream, stream_status->plane_count, context);
2808 }
2809 }
2810 if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) {
2811 dc->hwss.program_front_end_for_ctx(dc, context);
2812#ifdef CONFIG_DRM_AMD_DC_DCN
2813 if (dc->debug.validate_dml_output) {
2814 for (i = 0; i < dc->res_pool->pipe_count; i++) {
2815 struct pipe_ctx cur_pipe = context->res_ctx.pipe_ctx[i];
2816 if (cur_pipe.stream == NULL)
2817 continue;
2818
2819 cur_pipe.plane_res.hubp->funcs->validate_dml_output(
2820 cur_pipe.plane_res.hubp, dc->ctx,
2821 &context->res_ctx.pipe_ctx[i].rq_regs,
2822 &context->res_ctx.pipe_ctx[i].dlg_regs,
2823 &context->res_ctx.pipe_ctx[i].ttu_regs);
2824 }
2825 }
2826#endif
2827 }
2828
2829
2830 if (update_type == UPDATE_TYPE_FAST) {
2831 if (dc->hwss.set_flip_control_gsl)
2832 for (i = 0; i < surface_count; i++) {
2833 struct dc_plane_state *plane_state = srf_updates[i].surface;
2834
2835 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2836 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2837
2838 if (!should_update_pipe_for_stream(context, pipe_ctx, stream))
2839 continue;
2840
2841 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
2842 continue;
2843
2844
2845 dc->hwss.set_flip_control_gsl(pipe_ctx,
2846 pipe_ctx->plane_state->flip_immediate);
2847 }
2848 }
2849
2850
2851 for (i = 0; i < surface_count; i++) {
2852 struct dc_plane_state *plane_state = srf_updates[i].surface;
2853
2854 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2855 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2856
2857 if (!should_update_pipe_for_stream(context, pipe_ctx, stream))
2858 continue;
2859
2860 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
2861 continue;
2862
2863
2864 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
2865
2866 dc->hwss.program_triplebuffer(
2867 dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
2868 }
2869 if (pipe_ctx->plane_state->update_flags.bits.addr_update)
2870 dc->hwss.update_plane_addr(dc, pipe_ctx);
2871 }
2872 }
2873
2874 }
2875
2876 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock)
2877 dc->hwss.interdependent_update_lock(dc, context, false);
2878 else
2879 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
2880
2881 if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
2882 if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
2883 top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
2884 top_pipe_to_program->stream_res.tg,
2885 CRTC_STATE_VACTIVE);
2886 top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
2887 top_pipe_to_program->stream_res.tg,
2888 CRTC_STATE_VBLANK);
2889 top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
2890 top_pipe_to_program->stream_res.tg,
2891 CRTC_STATE_VACTIVE);
2892
2893 if (stream && should_use_dmub_lock(stream->link)) {
2894 union dmub_hw_lock_flags hw_locks = { 0 };
2895 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
2896
2897 hw_locks.bits.lock_dig = 1;
2898 inst_flags.dig_inst = top_pipe_to_program->stream_res.tg->inst;
2899
2900 dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
2901 false,
2902 &hw_locks,
2903 &inst_flags);
2904 } else
2905 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_disable(
2906 top_pipe_to_program->stream_res.tg);
2907 }
2908
2909 if (update_type != UPDATE_TYPE_FAST)
2910 dc->hwss.post_unlock_program_front_end(dc, context);
2911
2912
2913 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2914 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2915
2916 if (!pipe_ctx->plane_state)
2917 continue;
2918
2919 if (pipe_ctx->bottom_pipe || pipe_ctx->next_odm_pipe ||
2920 !pipe_ctx->stream || !should_update_pipe_for_stream(context, pipe_ctx, stream) ||
2921 !pipe_ctx->plane_state->update_flags.bits.addr_update ||
2922 pipe_ctx->plane_state->skip_manual_trigger)
2923 continue;
2924
2925 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger)
2926 pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
2927 }
2928}
2929
2930void dc_commit_updates_for_stream(struct dc *dc,
2931 struct dc_surface_update *srf_updates,
2932 int surface_count,
2933 struct dc_stream_state *stream,
2934 struct dc_stream_update *stream_update,
2935 struct dc_state *state)
2936{
2937 const struct dc_stream_status *stream_status;
2938 enum surface_update_type update_type;
2939 struct dc_state *context;
2940 struct dc_context *dc_ctx = dc->ctx;
2941 int i, j;
2942
2943 stream_status = dc_stream_get_status(stream);
2944 context = dc->current_state;
2945
2946 update_type = dc_check_update_surfaces_for_stream(
2947 dc, srf_updates, surface_count, stream_update, stream_status);
2948
2949 if (update_type >= update_surface_trace_level)
2950 update_surface_trace(dc, srf_updates, surface_count);
2951
2952
2953 if (update_type >= UPDATE_TYPE_FULL) {
2954
2955
2956 context = dc_create_state(dc);
2957 if (context == NULL) {
2958 DC_ERROR("Failed to allocate new validate context!\n");
2959 return;
2960 }
2961
2962 dc_resource_state_copy_construct(state, context);
2963
2964 for (i = 0; i < dc->res_pool->pipe_count; i++) {
2965 struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
2966 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
2967
2968 if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
2969 new_pipe->plane_state->force_full_update = true;
2970 }
2971 }
2972
2973
2974 for (i = 0; i < surface_count; i++) {
2975 struct dc_plane_state *surface = srf_updates[i].surface;
2976
2977 copy_surface_update_to_plane(surface, &srf_updates[i]);
2978
2979 if (update_type >= UPDATE_TYPE_MED) {
2980 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2981 struct pipe_ctx *pipe_ctx =
2982 &context->res_ctx.pipe_ctx[j];
2983
2984 if (pipe_ctx->plane_state != surface)
2985 continue;
2986
2987 resource_build_scaling_params(pipe_ctx);
2988 }
2989 }
2990 }
2991
2992 copy_stream_update_to_stream(dc, context, stream, stream_update);
2993
2994 if (update_type >= UPDATE_TYPE_FULL) {
2995 if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
2996 DC_ERROR("Mode validation failed for stream update!\n");
2997 dc_release_state(context);
2998 return;
2999 }
3000 }
3001
3002 TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
3003
3004 commit_planes_for_stream(
3005 dc,
3006 srf_updates,
3007 surface_count,
3008 stream,
3009 stream_update,
3010 update_type,
3011 context);
3012
3013 if (dc->current_state != context) {
3014
3015 struct dc_state *old = dc->current_state;
3016
3017 dc->current_state = context;
3018 dc_release_state(old);
3019
3020 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3021 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
3022
3023 if (pipe_ctx->plane_state && pipe_ctx->stream == stream)
3024 pipe_ctx->plane_state->force_full_update = false;
3025 }
3026 }
3027
3028 if (update_type >= UPDATE_TYPE_FULL) {
3029 dc_post_update_surfaces_to_stream(dc);
3030
3031 if (dc_ctx->dce_version >= DCE_VERSION_MAX)
3032 TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk);
3033 else
3034 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
3035 }
3036
3037 return;
3038
3039}
3040
3041uint8_t dc_get_current_stream_count(struct dc *dc)
3042{
3043 return dc->current_state->stream_count;
3044}
3045
3046struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
3047{
3048 if (i < dc->current_state->stream_count)
3049 return dc->current_state->streams[i];
3050 return NULL;
3051}
3052
3053struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link)
3054{
3055 uint8_t i;
3056 struct dc_context *ctx = link->ctx;
3057
3058 for (i = 0; i < ctx->dc->current_state->stream_count; i++) {
3059 if (ctx->dc->current_state->streams[i]->link == link)
3060 return ctx->dc->current_state->streams[i];
3061 }
3062
3063 return NULL;
3064}
3065
3066enum dc_irq_source dc_interrupt_to_irq_source(
3067 struct dc *dc,
3068 uint32_t src_id,
3069 uint32_t ext_id)
3070{
3071 return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
3072}
3073
3074
3075
3076
3077bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
3078{
3079
3080 if (dc == NULL)
3081 return false;
3082
3083 return dal_irq_service_set(dc->res_pool->irqs, src, enable);
3084}
3085
3086void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
3087{
3088 dal_irq_service_ack(dc->res_pool->irqs, src);
3089}
3090
3091void dc_power_down_on_boot(struct dc *dc)
3092{
3093 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW &&
3094 dc->hwss.power_down_on_boot)
3095 dc->hwss.power_down_on_boot(dc);
3096}
3097
3098void dc_set_power_state(
3099 struct dc *dc,
3100 enum dc_acpi_cm_power_state power_state)
3101{
3102 struct kref refcount;
3103 struct display_mode_lib *dml;
3104
3105 if (!dc->current_state)
3106 return;
3107
3108 switch (power_state) {
3109 case DC_ACPI_CM_POWER_STATE_D0:
3110 dc_resource_state_construct(dc, dc->current_state);
3111
3112#if defined(CONFIG_DRM_AMD_DC_DCN)
3113 dc_z10_restore(dc);
3114#endif
3115 if (dc->ctx->dmub_srv)
3116 dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv);
3117
3118 dc->hwss.init_hw(dc);
3119
3120 if (dc->hwss.init_sys_ctx != NULL &&
3121 dc->vm_pa_config.valid) {
3122 dc->hwss.init_sys_ctx(dc->hwseq, dc, &dc->vm_pa_config);
3123 }
3124
3125 break;
3126 default:
3127 ASSERT(dc->current_state->stream_count == 0);
3128
3129
3130
3131
3132 dml = kzalloc(sizeof(struct display_mode_lib),
3133 GFP_KERNEL);
3134
3135 ASSERT(dml);
3136 if (!dml)
3137 return;
3138
3139
3140 refcount = dc->current_state->refcount;
3141
3142 memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib));
3143
3144 dc_resource_state_destruct(dc->current_state);
3145 memset(dc->current_state, 0,
3146 sizeof(*dc->current_state));
3147
3148 dc->current_state->refcount = refcount;
3149 dc->current_state->bw_ctx.dml = *dml;
3150
3151 kfree(dml);
3152
3153 break;
3154 }
3155}
3156
3157void dc_resume(struct dc *dc)
3158{
3159 uint32_t i;
3160
3161 for (i = 0; i < dc->link_count; i++)
3162 core_link_resume(dc->links[i]);
3163}
3164
3165bool dc_is_dmcu_initialized(struct dc *dc)
3166{
3167 struct dmcu *dmcu = dc->res_pool->dmcu;
3168
3169 if (dmcu)
3170 return dmcu->funcs->is_dmcu_initialized(dmcu);
3171 return false;
3172}
3173
3174bool dc_submit_i2c(
3175 struct dc *dc,
3176 uint32_t link_index,
3177 struct i2c_command *cmd)
3178{
3179
3180 struct dc_link *link = dc->links[link_index];
3181 struct ddc_service *ddc = link->ddc;
3182 return dce_i2c_submit_command(
3183 dc->res_pool,
3184 ddc->ddc_pin,
3185 cmd);
3186}
3187
3188bool dc_submit_i2c_oem(
3189 struct dc *dc,
3190 struct i2c_command *cmd)
3191{
3192 struct ddc_service *ddc = dc->res_pool->oem_device;
3193 return dce_i2c_submit_command(
3194 dc->res_pool,
3195 ddc->ddc_pin,
3196 cmd);
3197}
3198
3199static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
3200{
3201 if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
3202 BREAK_TO_DEBUGGER();
3203 return false;
3204 }
3205
3206 dc_sink_retain(sink);
3207
3208 dc_link->remote_sinks[dc_link->sink_count] = sink;
3209 dc_link->sink_count++;
3210
3211 return true;
3212}
3213
3214
3215
3216
3217
3218
3219struct dc_sink *dc_link_add_remote_sink(
3220 struct dc_link *link,
3221 const uint8_t *edid,
3222 int len,
3223 struct dc_sink_init_data *init_data)
3224{
3225 struct dc_sink *dc_sink;
3226 enum dc_edid_status edid_status;
3227
3228 if (len > DC_MAX_EDID_BUFFER_SIZE) {
3229 dm_error("Max EDID buffer size breached!\n");
3230 return NULL;
3231 }
3232
3233 if (!init_data) {
3234 BREAK_TO_DEBUGGER();
3235 return NULL;
3236 }
3237
3238 if (!init_data->link) {
3239 BREAK_TO_DEBUGGER();
3240 return NULL;
3241 }
3242
3243 dc_sink = dc_sink_create(init_data);
3244
3245 if (!dc_sink)
3246 return NULL;
3247
3248 memmove(dc_sink->dc_edid.raw_edid, edid, len);
3249 dc_sink->dc_edid.length = len;
3250
3251 if (!link_add_remote_sink_helper(
3252 link,
3253 dc_sink))
3254 goto fail_add_sink;
3255
3256 edid_status = dm_helpers_parse_edid_caps(
3257 link->ctx,
3258 &dc_sink->dc_edid,
3259 &dc_sink->edid_caps);
3260
3261
3262
3263
3264
3265 if (edid_status != EDID_OK) {
3266 dc_sink->dc_edid.length = 0;
3267 dm_error("Bad EDID, status%d!\n", edid_status);
3268 }
3269
3270 return dc_sink;
3271
3272fail_add_sink:
3273 dc_sink_release(dc_sink);
3274 return NULL;
3275}
3276
3277
3278
3279
3280
3281
3282
3283void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
3284{
3285 int i;
3286
3287 if (!link->sink_count) {
3288 BREAK_TO_DEBUGGER();
3289 return;
3290 }
3291
3292 for (i = 0; i < link->sink_count; i++) {
3293 if (link->remote_sinks[i] == sink) {
3294 dc_sink_release(sink);
3295 link->remote_sinks[i] = NULL;
3296
3297
3298 while (i < link->sink_count - 1) {
3299 link->remote_sinks[i] = link->remote_sinks[i+1];
3300 i++;
3301 }
3302 link->remote_sinks[i] = NULL;
3303 link->sink_count--;
3304 return;
3305 }
3306 }
3307}
3308
3309void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
3310{
3311 info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
3312 info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz;
3313 info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz;
3314 info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz;
3315 info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz;
3316 info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz;
3317 info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz;
3318 info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz;
3319 info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz;
3320}
3321enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping)
3322{
3323 if (dc->hwss.set_clock)
3324 return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping);
3325 return DC_ERROR_UNEXPECTED;
3326}
3327void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg)
3328{
3329 if (dc->hwss.get_clock)
3330 dc->hwss.get_clock(dc, clock_type, clock_cfg);
3331}
3332
3333
3334bool dc_set_psr_allow_active(struct dc *dc, bool enable)
3335{
3336 int i;
3337
3338 for (i = 0; i < dc->current_state->stream_count ; i++) {
3339 struct dc_link *link;
3340 struct dc_stream_state *stream = dc->current_state->streams[i];
3341
3342 link = stream->link;
3343 if (!link)
3344 continue;
3345
3346 if (link->psr_settings.psr_feature_enabled) {
3347 if (enable && !link->psr_settings.psr_allow_active) {
3348 if (!dc_link_set_psr_allow_active(link, true, false, false))
3349 return false;
3350 } else if (!enable && link->psr_settings.psr_allow_active) {
3351 if (!dc_link_set_psr_allow_active(link, false, true, false))
3352 return false;
3353 }
3354 }
3355 }
3356
3357 return true;
3358}
3359
3360#if defined(CONFIG_DRM_AMD_DC_DCN)
3361
3362void dc_allow_idle_optimizations(struct dc *dc, bool allow)
3363{
3364 if (dc->debug.disable_idle_power_optimizations)
3365 return;
3366
3367 if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
3368 if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr))
3369 return;
3370
3371 if (allow == dc->idle_optimizations_allowed)
3372 return;
3373
3374 if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations(dc, allow))
3375 dc->idle_optimizations_allowed = allow;
3376}
3377
3378
3379
3380
3381
3382void dc_unlock_memory_clock_frequency(struct dc *dc)
3383{
3384 unsigned int i;
3385
3386 for (i = 0; i < MAX_PIPES; i++)
3387 if (dc->current_state->res_ctx.pipe_ctx[i].plane_state)
3388 core_link_disable_stream(&dc->current_state->res_ctx.pipe_ctx[i]);
3389
3390 dc->clk_mgr->funcs->set_hard_min_memclk(dc->clk_mgr, false);
3391 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
3392}
3393
3394
3395
3396
3397
3398void dc_lock_memory_clock_frequency(struct dc *dc)
3399{
3400 unsigned int i;
3401
3402 dc->clk_mgr->funcs->get_memclk_states_from_smu(dc->clk_mgr);
3403 dc->clk_mgr->funcs->set_hard_min_memclk(dc->clk_mgr, true);
3404 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
3405
3406 for (i = 0; i < MAX_PIPES; i++)
3407 if (dc->current_state->res_ctx.pipe_ctx[i].plane_state)
3408 core_link_enable_stream(dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]);
3409}
3410
3411bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane,
3412 struct dc_cursor_attributes *cursor_attr)
3413{
3414 if (dc->hwss.does_plane_fit_in_mall && dc->hwss.does_plane_fit_in_mall(dc, plane, cursor_attr))
3415 return true;
3416 return false;
3417}
3418
3419
3420void dc_hardware_release(struct dc *dc)
3421{
3422 if (dc->hwss.hardware_release)
3423 dc->hwss.hardware_release(dc);
3424}
3425#endif
3426
3427
3428
3429
3430
3431
3432
3433bool dc_enable_dmub_notifications(struct dc *dc)
3434{
3435
3436 return dc->debug.enable_dmub_aux_for_legacy_ddc;
3437}
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448bool dc_process_dmub_aux_transfer_async(struct dc *dc,
3449 uint32_t link_index,
3450 struct aux_payload *payload)
3451{
3452 uint8_t action;
3453 union dmub_rb_cmd cmd = {0};
3454 struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
3455
3456 ASSERT(payload->length <= 16);
3457
3458 cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
3459 cmd.dp_aux_access.header.payload_bytes = 0;
3460 cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
3461 cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst;
3462 cmd.dp_aux_access.aux_control.sw_crc_enabled = 0;
3463 cmd.dp_aux_access.aux_control.timeout = 0;
3464 cmd.dp_aux_access.aux_control.dpaux.address = payload->address;
3465 cmd.dp_aux_access.aux_control.dpaux.is_i2c_over_aux = payload->i2c_over_aux;
3466 cmd.dp_aux_access.aux_control.dpaux.length = payload->length;
3467
3468
3469 if (payload->i2c_over_aux) {
3470 if (payload->write) {
3471 if (payload->mot)
3472 action = DP_AUX_REQ_ACTION_I2C_WRITE_MOT;
3473 else
3474 action = DP_AUX_REQ_ACTION_I2C_WRITE;
3475 } else {
3476 if (payload->mot)
3477 action = DP_AUX_REQ_ACTION_I2C_READ_MOT;
3478 else
3479 action = DP_AUX_REQ_ACTION_I2C_READ;
3480 }
3481 } else {
3482 if (payload->write)
3483 action = DP_AUX_REQ_ACTION_DPCD_WRITE;
3484 else
3485 action = DP_AUX_REQ_ACTION_DPCD_READ;
3486 }
3487
3488 cmd.dp_aux_access.aux_control.dpaux.action = action;
3489
3490 if (payload->length && payload->write) {
3491 memcpy(cmd.dp_aux_access.aux_control.dpaux.data,
3492 payload->data,
3493 payload->length
3494 );
3495 }
3496
3497 dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
3498 dc_dmub_srv_cmd_execute(dmub_srv);
3499 dc_dmub_srv_wait_idle(dmub_srv);
3500
3501 return true;
3502}
3503
3504
3505
3506
3507
3508void dc_disable_accelerated_mode(struct dc *dc)
3509{
3510 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 0);
3511}
3512