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 "include/irq_service_interface.h"
45#include "transform.h"
46#include "dmcu.h"
47#include "dpp.h"
48#include "timing_generator.h"
49#include "abm.h"
50#include "virtual/virtual_link_encoder.h"
51
52#include "link_hwss.h"
53#include "link_encoder.h"
54
55#include "dc_link_ddc.h"
56#include "dm_helpers.h"
57#include "mem_input.h"
58#include "hubp.h"
59
60#include "dc_link_dp.h"
61#include "dc_dmub_srv.h"
62
63#include "dsc.h"
64
65#include "vm_helper.h"
66
67#include "dce/dce_i2c.h"
68
69#define CTX \
70 dc->ctx
71
72#define DC_LOGGER \
73 dc->ctx->logger
74
75static const char DC_BUILD_ID[] = "production-build";
76
77
78
79
80
81
82
83
84
85
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
130static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
131{
132 if (new > *original)
133 *original = new;
134}
135
136static void destroy_links(struct dc *dc)
137{
138 uint32_t i;
139
140 for (i = 0; i < dc->link_count; i++) {
141 if (NULL != dc->links[i])
142 link_destroy(&dc->links[i]);
143 }
144}
145
146static bool create_links(
147 struct dc *dc,
148 uint32_t num_virtual_links)
149{
150 int i;
151 int connectors_num;
152 struct dc_bios *bios = dc->ctx->dc_bios;
153
154 dc->link_count = 0;
155
156 connectors_num = bios->funcs->get_connectors_number(bios);
157
158 if (connectors_num > ENUM_ID_COUNT) {
159 dm_error(
160 "DC: Number of connectors %d exceeds maximum of %d!\n",
161 connectors_num,
162 ENUM_ID_COUNT);
163 return false;
164 }
165
166 dm_output_to_console(
167 "DC: %s: connectors_num: physical:%d, virtual:%d\n",
168 __func__,
169 connectors_num,
170 num_virtual_links);
171
172 for (i = 0; i < connectors_num; i++) {
173 struct link_init_data link_init_params = {0};
174 struct dc_link *link;
175
176 link_init_params.ctx = dc->ctx;
177
178 link_init_params.connector_index = i;
179 link_init_params.link_index = dc->link_count;
180 link_init_params.dc = dc;
181 link = link_create(&link_init_params);
182
183 if (link) {
184 bool should_destory_link = false;
185
186 if (link->connector_signal == SIGNAL_TYPE_EDP) {
187 if (dc->config.edp_not_connected)
188 should_destory_link = true;
189 else if (dc->debug.remove_disconnect_edp) {
190 enum dc_connection_type type;
191 dc_link_detect_sink(link, &type);
192 if (type == dc_connection_none)
193 should_destory_link = true;
194 }
195 }
196
197 if (dc->config.force_enum_edp || !should_destory_link) {
198 dc->links[dc->link_count] = link;
199 link->dc = dc;
200 ++dc->link_count;
201 } else {
202 link_destroy(&link);
203 }
204 }
205 }
206
207 for (i = 0; i < num_virtual_links; i++) {
208 struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
209 struct encoder_init_data enc_init = {0};
210
211 if (link == NULL) {
212 BREAK_TO_DEBUGGER();
213 goto failed_alloc;
214 }
215
216 link->link_index = dc->link_count;
217 dc->links[dc->link_count] = link;
218 dc->link_count++;
219
220 link->ctx = dc->ctx;
221 link->dc = dc;
222 link->connector_signal = SIGNAL_TYPE_VIRTUAL;
223 link->link_id.type = OBJECT_TYPE_CONNECTOR;
224 link->link_id.id = CONNECTOR_ID_VIRTUAL;
225 link->link_id.enum_id = ENUM_ID_1;
226 link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL);
227
228 if (!link->link_enc) {
229 BREAK_TO_DEBUGGER();
230 goto failed_alloc;
231 }
232
233 link->link_status.dpcd_caps = &link->dpcd_caps;
234
235 enc_init.ctx = dc->ctx;
236 enc_init.channel = CHANNEL_ID_UNKNOWN;
237 enc_init.hpd_source = HPD_SOURCEID_UNKNOWN;
238 enc_init.transmitter = TRANSMITTER_UNKNOWN;
239 enc_init.connector = link->link_id;
240 enc_init.encoder.type = OBJECT_TYPE_ENCODER;
241 enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL;
242 enc_init.encoder.enum_id = ENUM_ID_1;
243 virtual_link_encoder_construct(link->link_enc, &enc_init);
244 }
245
246 return true;
247
248failed_alloc:
249 return false;
250}
251
252static struct dc_perf_trace *dc_perf_trace_create(void)
253{
254 return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL);
255}
256
257static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace)
258{
259 kfree(*perf_trace);
260 *perf_trace = NULL;
261}
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279bool dc_stream_adjust_vmin_vmax(struct dc *dc,
280 struct dc_stream_state *stream,
281 struct dc_crtc_timing_adjust *adjust)
282{
283 int i = 0;
284 bool ret = false;
285
286 stream->adjust = *adjust;
287
288 for (i = 0; i < MAX_PIPES; i++) {
289 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
290
291 if (pipe->stream == stream && pipe->stream_res.tg) {
292 dc->hwss.set_drr(&pipe,
293 1,
294 adjust->v_total_min,
295 adjust->v_total_max,
296 adjust->v_total_mid,
297 adjust->v_total_mid_frame_num);
298
299 ret = true;
300 }
301 }
302 return ret;
303}
304
305bool dc_stream_get_crtc_position(struct dc *dc,
306 struct dc_stream_state **streams, int num_streams,
307 unsigned int *v_pos, unsigned int *nom_v_pos)
308{
309
310 const struct dc_stream_state *stream = streams[0];
311 int i = 0;
312 bool ret = false;
313 struct crtc_position position;
314
315 for (i = 0; i < MAX_PIPES; i++) {
316 struct pipe_ctx *pipe =
317 &dc->current_state->res_ctx.pipe_ctx[i];
318
319 if (pipe->stream == stream && pipe->stream_res.stream_enc) {
320 dc->hwss.get_position(&pipe, 1, &position);
321
322 *v_pos = position.vertical_count;
323 *nom_v_pos = position.nominal_vcount;
324 ret = true;
325 }
326 }
327 return ret;
328}
329
330
331
332
333
334
335
336
337
338
339
340
341bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
342 bool enable, bool continuous)
343{
344 int i;
345 struct pipe_ctx *pipe;
346 struct crc_params param;
347 struct timing_generator *tg;
348
349 for (i = 0; i < MAX_PIPES; i++) {
350 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
351 if (pipe->stream == stream)
352 break;
353 }
354
355 if (i == MAX_PIPES)
356 return false;
357
358
359 param.windowa_x_start = 0;
360 param.windowa_y_start = 0;
361 param.windowa_x_end = pipe->stream->timing.h_addressable;
362 param.windowa_y_end = pipe->stream->timing.v_addressable;
363 param.windowb_x_start = 0;
364 param.windowb_y_start = 0;
365 param.windowb_x_end = pipe->stream->timing.h_addressable;
366 param.windowb_y_end = pipe->stream->timing.v_addressable;
367
368
369 param.selection = UNION_WINDOW_A_B;
370 param.continuous_mode = continuous;
371 param.enable = enable;
372
373 tg = pipe->stream_res.tg;
374
375
376 if (tg->funcs->configure_crc)
377 return tg->funcs->configure_crc(tg, ¶m);
378 DC_LOG_WARNING("CRC capture not supported.");
379 return false;
380}
381
382
383
384
385
386
387
388
389
390
391bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
392 uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
393{
394 int i;
395 struct pipe_ctx *pipe;
396 struct timing_generator *tg;
397
398 for (i = 0; i < MAX_PIPES; i++) {
399 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
400 if (pipe->stream == stream)
401 break;
402 }
403
404 if (i == MAX_PIPES)
405 return false;
406
407 tg = pipe->stream_res.tg;
408
409 if (tg->funcs->get_crc)
410 return tg->funcs->get_crc(tg, r_cr, g_y, b_cb);
411 DC_LOG_WARNING("CRC capture not supported.");
412 return false;
413}
414
415void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
416 enum dc_dynamic_expansion option)
417{
418
419 int i = 0;
420 struct pipe_ctx *pipe_ctx;
421
422 for (i = 0; i < MAX_PIPES; i++) {
423 if (dc->current_state->res_ctx.pipe_ctx[i].stream
424 == stream) {
425 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
426 pipe_ctx->stream_res.opp->dyn_expansion = option;
427 pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
428 pipe_ctx->stream_res.opp,
429 COLOR_SPACE_YCBCR601,
430 stream->timing.display_color_depth,
431 stream->signal);
432 }
433 }
434}
435
436void dc_stream_set_dither_option(struct dc_stream_state *stream,
437 enum dc_dither_option option)
438{
439 struct bit_depth_reduction_params params;
440 struct dc_link *link = stream->link;
441 struct pipe_ctx *pipes = NULL;
442 int i;
443
444 for (i = 0; i < MAX_PIPES; i++) {
445 if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
446 stream) {
447 pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
448 break;
449 }
450 }
451
452 if (!pipes)
453 return;
454 if (option > DITHER_OPTION_MAX)
455 return;
456
457 stream->dither_option = option;
458
459 memset(¶ms, 0, sizeof(params));
460 resource_build_bit_depth_reduction_params(stream, ¶ms);
461 stream->bit_depth_params = params;
462
463 if (pipes->plane_res.xfm &&
464 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) {
465 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
466 pipes->plane_res.xfm,
467 pipes->plane_res.scl_data.lb_params.depth,
468 &stream->bit_depth_params);
469 }
470
471 pipes->stream_res.opp->funcs->
472 opp_program_bit_depth_reduction(pipes->stream_res.opp, ¶ms);
473}
474
475bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
476{
477 int i = 0;
478 bool ret = false;
479 struct pipe_ctx *pipes;
480
481 for (i = 0; i < MAX_PIPES; i++) {
482 if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
483 pipes = &dc->current_state->res_ctx.pipe_ctx[i];
484 dc->hwss.program_gamut_remap(pipes);
485 ret = true;
486 }
487 }
488
489 return ret;
490}
491
492bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
493{
494 int i = 0;
495 bool ret = false;
496 struct pipe_ctx *pipes;
497
498 for (i = 0; i < MAX_PIPES; i++) {
499 if (dc->current_state->res_ctx.pipe_ctx[i].stream
500 == stream) {
501
502 pipes = &dc->current_state->res_ctx.pipe_ctx[i];
503 dc->hwss.program_output_csc(dc,
504 pipes,
505 stream->output_color_space,
506 stream->csc_color_matrix.matrix,
507 pipes->stream_res.opp->inst);
508 ret = true;
509 }
510 }
511
512 return ret;
513}
514
515void dc_stream_set_static_screen_params(struct dc *dc,
516 struct dc_stream_state **streams,
517 int num_streams,
518 const struct dc_static_screen_params *params)
519{
520 int i = 0;
521 int j = 0;
522 struct pipe_ctx *pipes_affected[MAX_PIPES];
523 int num_pipes_affected = 0;
524
525 for (i = 0; i < num_streams; i++) {
526 struct dc_stream_state *stream = streams[i];
527
528 for (j = 0; j < MAX_PIPES; j++) {
529 if (dc->current_state->res_ctx.pipe_ctx[j].stream
530 == stream) {
531 pipes_affected[num_pipes_affected++] =
532 &dc->current_state->res_ctx.pipe_ctx[j];
533 }
534 }
535 }
536
537 dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, params);
538}
539
540static void dc_destruct(struct dc *dc)
541{
542 if (dc->current_state) {
543 dc_release_state(dc->current_state);
544 dc->current_state = NULL;
545 }
546
547 destroy_links(dc);
548
549 if (dc->clk_mgr) {
550 dc_destroy_clk_mgr(dc->clk_mgr);
551 dc->clk_mgr = NULL;
552 }
553
554 dc_destroy_resource_pool(dc);
555
556 if (dc->ctx->gpio_service)
557 dal_gpio_service_destroy(&dc->ctx->gpio_service);
558
559 if (dc->ctx->created_bios)
560 dal_bios_parser_destroy(&dc->ctx->dc_bios);
561
562 dc_perf_trace_destroy(&dc->ctx->perf_trace);
563
564 kfree(dc->ctx);
565 dc->ctx = NULL;
566
567 kfree(dc->bw_vbios);
568 dc->bw_vbios = NULL;
569
570 kfree(dc->bw_dceip);
571 dc->bw_dceip = NULL;
572
573#ifdef CONFIG_DRM_AMD_DC_DCN
574 kfree(dc->dcn_soc);
575 dc->dcn_soc = NULL;
576
577 kfree(dc->dcn_ip);
578 dc->dcn_ip = NULL;
579
580#endif
581 kfree(dc->vm_helper);
582 dc->vm_helper = NULL;
583
584}
585
586static bool dc_construct_ctx(struct dc *dc,
587 const struct dc_init_data *init_params)
588{
589 struct dc_context *dc_ctx;
590 enum dce_version dc_version = DCE_VERSION_UNKNOWN;
591
592 dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL);
593 if (!dc_ctx)
594 return false;
595
596 dc_ctx->cgs_device = init_params->cgs_device;
597 dc_ctx->driver_context = init_params->driver;
598 dc_ctx->dc = dc;
599 dc_ctx->asic_id = init_params->asic_id;
600 dc_ctx->dc_sink_id_count = 0;
601 dc_ctx->dc_stream_id_count = 0;
602 dc_ctx->dce_environment = init_params->dce_environment;
603
604
605
606 dc_version = resource_parse_asic_id(init_params->asic_id);
607 dc_ctx->dce_version = dc_version;
608
609 dc_ctx->perf_trace = dc_perf_trace_create();
610 if (!dc_ctx->perf_trace) {
611 ASSERT_CRITICAL(false);
612 return false;
613 }
614
615 dc->ctx = dc_ctx;
616
617 return true;
618}
619
620static bool dc_construct(struct dc *dc,
621 const struct dc_init_data *init_params)
622{
623 struct dc_context *dc_ctx;
624 struct bw_calcs_dceip *dc_dceip;
625 struct bw_calcs_vbios *dc_vbios;
626#ifdef CONFIG_DRM_AMD_DC_DCN
627 struct dcn_soc_bounding_box *dcn_soc;
628 struct dcn_ip_params *dcn_ip;
629#endif
630
631 dc->config = init_params->flags;
632
633
634 dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
635 if (!dc->vm_helper) {
636 dm_error("%s: failed to create dc->vm_helper\n", __func__);
637 goto fail;
638 }
639
640 memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
641
642 dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL);
643 if (!dc_dceip) {
644 dm_error("%s: failed to create dceip\n", __func__);
645 goto fail;
646 }
647
648 dc->bw_dceip = dc_dceip;
649
650 dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL);
651 if (!dc_vbios) {
652 dm_error("%s: failed to create vbios\n", __func__);
653 goto fail;
654 }
655
656 dc->bw_vbios = dc_vbios;
657#ifdef CONFIG_DRM_AMD_DC_DCN
658 dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL);
659 if (!dcn_soc) {
660 dm_error("%s: failed to create dcn_soc\n", __func__);
661 goto fail;
662 }
663
664 dc->dcn_soc = dcn_soc;
665
666 dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL);
667 if (!dcn_ip) {
668 dm_error("%s: failed to create dcn_ip\n", __func__);
669 goto fail;
670 }
671
672 dc->dcn_ip = dcn_ip;
673 dc->soc_bounding_box = init_params->soc_bounding_box;
674#endif
675
676 if (!dc_construct_ctx(dc, init_params)) {
677 dm_error("%s: failed to create ctx\n", __func__);
678 goto fail;
679 }
680
681 dc_ctx = dc->ctx;
682
683
684
685
686 if (init_params->vbios_override)
687 dc_ctx->dc_bios = init_params->vbios_override;
688 else {
689
690 struct bp_init_data bp_init_data;
691
692 bp_init_data.ctx = dc_ctx;
693 bp_init_data.bios = init_params->asic_id.atombios_base_address;
694
695 dc_ctx->dc_bios = dal_bios_parser_create(
696 &bp_init_data, dc_ctx->dce_version);
697
698 if (!dc_ctx->dc_bios) {
699 ASSERT_CRITICAL(false);
700 goto fail;
701 }
702
703 dc_ctx->created_bios = true;
704 }
705
706 dc->vendor_signature = init_params->vendor_signature;
707
708
709 dc_ctx->gpio_service = dal_gpio_service_create(
710 dc_ctx->dce_version,
711 dc_ctx->dce_environment,
712 dc_ctx);
713
714 if (!dc_ctx->gpio_service) {
715 ASSERT_CRITICAL(false);
716 goto fail;
717 }
718
719 dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version);
720 if (!dc->res_pool)
721 goto fail;
722
723 dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg);
724 if (!dc->clk_mgr)
725 goto fail;
726
727 if (dc->res_pool->funcs->update_bw_bounding_box)
728 dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
729
730
731
732
733
734
735 dc->current_state = dc_create_state(dc);
736
737 if (!dc->current_state) {
738 dm_error("%s: failed to create validate ctx\n", __func__);
739 goto fail;
740 }
741
742 dc_resource_state_construct(dc, dc->current_state);
743
744 if (!create_links(dc, init_params->num_virtual_links))
745 goto fail;
746
747 return true;
748
749fail:
750 return false;
751}
752
753static bool disable_all_writeback_pipes_for_stream(
754 const struct dc *dc,
755 struct dc_stream_state *stream,
756 struct dc_state *context)
757{
758 int i;
759
760 for (i = 0; i < stream->num_wb_info; i++)
761 stream->writeback_info[i].wb_enabled = false;
762
763 return true;
764}
765
766void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream, bool lock)
767{
768 int i = 0;
769
770
771 if (dc->hwss.interdependent_update_lock)
772 dc->hwss.interdependent_update_lock(dc, context, lock);
773 else {
774 for (i = 0; i < dc->res_pool->pipe_count; i++) {
775 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
776 struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
777
778
779 if (stream == pipe_ctx->stream) {
780 if (!pipe_ctx->top_pipe &&
781 (pipe_ctx->plane_state || old_pipe_ctx->plane_state))
782 dc->hwss.pipe_control_lock(dc, pipe_ctx, lock);
783 }
784 }
785 }
786}
787
788static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
789{
790 int i, j;
791 struct dc_state *dangling_context = dc_create_state(dc);
792 struct dc_state *current_ctx;
793
794 if (dangling_context == NULL)
795 return;
796
797 dc_resource_state_copy_construct(dc->current_state, dangling_context);
798
799 for (i = 0; i < dc->res_pool->pipe_count; i++) {
800 struct dc_stream_state *old_stream =
801 dc->current_state->res_ctx.pipe_ctx[i].stream;
802 bool should_disable = true;
803
804 for (j = 0; j < context->stream_count; j++) {
805 if (old_stream == context->streams[j]) {
806 should_disable = false;
807 break;
808 }
809 }
810 if (should_disable && old_stream) {
811 dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
812 disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
813
814 if (dc->hwss.apply_ctx_for_surface) {
815 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, true);
816 dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
817 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, false);
818 dc->hwss.post_unlock_program_front_end(dc, dangling_context);
819 }
820 if (dc->hwss.program_front_end_for_ctx) {
821 dc->hwss.interdependent_update_lock(dc, dc->current_state, true);
822 dc->hwss.program_front_end_for_ctx(dc, dangling_context);
823 dc->hwss.interdependent_update_lock(dc, dc->current_state, false);
824 dc->hwss.post_unlock_program_front_end(dc, dangling_context);
825 }
826 }
827 }
828
829 current_ctx = dc->current_state;
830 dc->current_state = dangling_context;
831 dc_release_state(current_ctx);
832}
833
834static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
835{
836 int i;
837 PERF_TRACE();
838 for (i = 0; i < MAX_PIPES; i++) {
839 int count = 0;
840 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
841
842 if (!pipe->plane_state)
843 continue;
844
845
846 while (count < 100000) {
847
848 pipe->plane_state->status.is_flip_pending = false;
849 dc->hwss.update_pending_status(pipe);
850 if (!pipe->plane_state->status.is_flip_pending)
851 break;
852 udelay(1);
853 count++;
854 }
855 ASSERT(!pipe->plane_state->status.is_flip_pending);
856 }
857 PERF_TRACE();
858}
859
860
861
862
863
864struct dc *dc_create(const struct dc_init_data *init_params)
865{
866 struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
867 unsigned int full_pipe_count;
868
869 if (NULL == dc)
870 goto alloc_fail;
871
872 if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) {
873 if (false == dc_construct_ctx(dc, init_params)) {
874 dc_destruct(dc);
875 goto construct_fail;
876 }
877 } else {
878 if (false == dc_construct(dc, init_params)) {
879 dc_destruct(dc);
880 goto construct_fail;
881 }
882
883 full_pipe_count = dc->res_pool->pipe_count;
884 if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE)
885 full_pipe_count--;
886 dc->caps.max_streams = min(
887 full_pipe_count,
888 dc->res_pool->stream_enc_count);
889
890 dc->optimize_seamless_boot_streams = 0;
891 dc->caps.max_links = dc->link_count;
892 dc->caps.max_audios = dc->res_pool->audio_count;
893 dc->caps.linear_pitch_alignment = 64;
894
895 dc->caps.max_dp_protocol_version = DP_VERSION_1_4;
896
897 if (dc->res_pool->dmcu != NULL)
898 dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version;
899 }
900
901
902 dc->versions.dc_ver = DC_VER;
903
904 dc->build_id = DC_BUILD_ID;
905
906 DC_LOG_DC("Display Core initialized\n");
907
908
909
910 return dc;
911
912construct_fail:
913 kfree(dc);
914
915alloc_fail:
916 return NULL;
917}
918
919void dc_hardware_init(struct dc *dc)
920{
921 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW)
922 dc->hwss.init_hw(dc);
923}
924
925void dc_init_callbacks(struct dc *dc,
926 const struct dc_callback_init *init_params)
927{
928#ifdef CONFIG_DRM_AMD_DC_HDCP
929 dc->ctx->cp_psp = init_params->cp_psp;
930#endif
931}
932
933void dc_deinit_callbacks(struct dc *dc)
934{
935#ifdef CONFIG_DRM_AMD_DC_HDCP
936 memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp));
937#endif
938}
939
940void dc_destroy(struct dc **dc)
941{
942 dc_destruct(*dc);
943 kfree(*dc);
944 *dc = NULL;
945}
946
947static void enable_timing_multisync(
948 struct dc *dc,
949 struct dc_state *ctx)
950{
951 int i = 0, multisync_count = 0;
952 int pipe_count = dc->res_pool->pipe_count;
953 struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL };
954
955 for (i = 0; i < pipe_count; i++) {
956 if (!ctx->res_ctx.pipe_ctx[i].stream ||
957 !ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled)
958 continue;
959 if (ctx->res_ctx.pipe_ctx[i].stream == ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.event_source)
960 continue;
961 multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i];
962 multisync_count++;
963 }
964
965 if (multisync_count > 0) {
966 dc->hwss.enable_per_frame_crtc_position_reset(
967 dc, multisync_count, multisync_pipes);
968 }
969}
970
971static void program_timing_sync(
972 struct dc *dc,
973 struct dc_state *ctx)
974{
975 int i, j, k;
976 int group_index = 0;
977 int num_group = 0;
978 int pipe_count = dc->res_pool->pipe_count;
979 struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
980
981 for (i = 0; i < pipe_count; i++) {
982 if (!ctx->res_ctx.pipe_ctx[i].stream || ctx->res_ctx.pipe_ctx[i].top_pipe)
983 continue;
984
985 unsynced_pipes[i] = &ctx->res_ctx.pipe_ctx[i];
986 }
987
988 for (i = 0; i < pipe_count; i++) {
989 int group_size = 1;
990 struct pipe_ctx *pipe_set[MAX_PIPES];
991
992 if (!unsynced_pipes[i])
993 continue;
994
995 pipe_set[0] = unsynced_pipes[i];
996 unsynced_pipes[i] = NULL;
997
998
999
1000
1001 for (j = i + 1; j < pipe_count; j++) {
1002 if (!unsynced_pipes[j])
1003 continue;
1004
1005 if (resource_are_streams_timing_synchronizable(
1006 unsynced_pipes[j]->stream,
1007 pipe_set[0]->stream)) {
1008 pipe_set[group_size] = unsynced_pipes[j];
1009 unsynced_pipes[j] = NULL;
1010 group_size++;
1011 }
1012 }
1013
1014
1015 for (j = 0; j < group_size; j++) {
1016 if (pipe_set[j]->plane_state) {
1017 if (j == 0)
1018 break;
1019
1020 swap(pipe_set[0], pipe_set[j]);
1021 break;
1022 }
1023 }
1024
1025
1026 for (k = 0; k < group_size; k++) {
1027 struct dc_stream_status *status = dc_stream_get_status_from_state(ctx, pipe_set[k]->stream);
1028
1029 status->timing_sync_info.group_id = num_group;
1030 status->timing_sync_info.group_size = group_size;
1031 if (k == 0)
1032 status->timing_sync_info.master = true;
1033 else
1034 status->timing_sync_info.master = false;
1035
1036 }
1037
1038 for (j = j + 1; j < group_size; j++) {
1039 if (pipe_set[j]->plane_state) {
1040 group_size--;
1041 pipe_set[j] = pipe_set[group_size];
1042 j--;
1043 }
1044 }
1045
1046 if (group_size > 1) {
1047 dc->hwss.enable_timing_synchronization(
1048 dc, group_index, group_size, pipe_set);
1049 group_index++;
1050 }
1051 num_group++;
1052 }
1053}
1054
1055static bool context_changed(
1056 struct dc *dc,
1057 struct dc_state *context)
1058{
1059 uint8_t i;
1060
1061 if (context->stream_count != dc->current_state->stream_count)
1062 return true;
1063
1064 for (i = 0; i < dc->current_state->stream_count; i++) {
1065 if (dc->current_state->streams[i] != context->streams[i])
1066 return true;
1067 }
1068
1069 return false;
1070}
1071
1072bool dc_validate_seamless_boot_timing(const struct dc *dc,
1073 const struct dc_sink *sink,
1074 struct dc_crtc_timing *crtc_timing)
1075{
1076 struct timing_generator *tg;
1077 struct stream_encoder *se = NULL;
1078
1079 struct dc_crtc_timing hw_crtc_timing = {0};
1080
1081 struct dc_link *link = sink->link;
1082 unsigned int i, enc_inst, tg_inst = 0;
1083
1084
1085 if (sink->sink_signal != SIGNAL_TYPE_DISPLAY_PORT &&
1086 sink->sink_signal != SIGNAL_TYPE_EDP)
1087 return false;
1088
1089
1090 if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
1091 return false;
1092
1093 enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
1094
1095 if (enc_inst == ENGINE_ID_UNKNOWN)
1096 return false;
1097
1098 for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
1099 if (dc->res_pool->stream_enc[i]->id == enc_inst) {
1100
1101 se = dc->res_pool->stream_enc[i];
1102
1103 tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg(
1104 dc->res_pool->stream_enc[i]);
1105 break;
1106 }
1107 }
1108
1109
1110 if (i == dc->res_pool->stream_enc_count)
1111 return false;
1112
1113 if (tg_inst >= dc->res_pool->timing_generator_count)
1114 return false;
1115
1116 tg = dc->res_pool->timing_generators[tg_inst];
1117
1118 if (!tg->funcs->get_hw_timing)
1119 return false;
1120
1121 if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing))
1122 return false;
1123
1124 if (crtc_timing->h_total != hw_crtc_timing.h_total)
1125 return false;
1126
1127 if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left)
1128 return false;
1129
1130 if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable)
1131 return false;
1132
1133 if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right)
1134 return false;
1135
1136 if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch)
1137 return false;
1138
1139 if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width)
1140 return false;
1141
1142 if (crtc_timing->v_total != hw_crtc_timing.v_total)
1143 return false;
1144
1145 if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top)
1146 return false;
1147
1148 if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable)
1149 return false;
1150
1151 if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom)
1152 return false;
1153
1154 if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch)
1155 return false;
1156
1157 if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width)
1158 return false;
1159
1160 if (dc_is_dp_signal(link->connector_signal)) {
1161 unsigned int pix_clk_100hz;
1162
1163 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1164 dc->res_pool->dp_clock_source,
1165 tg_inst, &pix_clk_100hz);
1166
1167 if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
1168 return false;
1169
1170 if (!se->funcs->dp_get_pixel_format)
1171 return false;
1172
1173 if (!se->funcs->dp_get_pixel_format(
1174 se,
1175 &hw_crtc_timing.pixel_encoding,
1176 &hw_crtc_timing.display_color_depth))
1177 return false;
1178
1179 if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth)
1180 return false;
1181
1182 if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding)
1183 return false;
1184 }
1185
1186 return true;
1187}
1188
1189bool dc_enable_stereo(
1190 struct dc *dc,
1191 struct dc_state *context,
1192 struct dc_stream_state *streams[],
1193 uint8_t stream_count)
1194{
1195 bool ret = true;
1196 int i, j;
1197 struct pipe_ctx *pipe;
1198
1199 for (i = 0; i < MAX_PIPES; i++) {
1200 if (context != NULL)
1201 pipe = &context->res_ctx.pipe_ctx[i];
1202 else
1203 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1204 for (j = 0 ; pipe && j < stream_count; j++) {
1205 if (streams[j] && streams[j] == pipe->stream &&
1206 dc->hwss.setup_stereo)
1207 dc->hwss.setup_stereo(pipe, dc);
1208 }
1209 }
1210
1211 return ret;
1212}
1213
1214
1215
1216
1217
1218static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
1219{
1220 struct dc_bios *dcb = dc->ctx->dc_bios;
1221 enum dc_status result = DC_ERROR_UNEXPECTED;
1222 struct pipe_ctx *pipe;
1223 int i, k, l;
1224 struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
1225
1226 disable_dangling_plane(dc, context);
1227
1228 for (i = 0; i < context->stream_count; i++)
1229 dc_streams[i] = context->streams[i];
1230
1231 if (!dcb->funcs->is_accelerated_mode(dcb))
1232 dc->hwss.enable_accelerated_mode(dc, context);
1233
1234 for (i = 0; i < context->stream_count; i++) {
1235 if (context->streams[i]->apply_seamless_boot_optimization)
1236 dc->optimize_seamless_boot_streams++;
1237 }
1238
1239 if (dc->optimize_seamless_boot_streams == 0)
1240 dc->hwss.prepare_bandwidth(dc, context);
1241
1242
1243
1244
1245 if (dc->hwss.apply_ctx_for_surface) {
1246 for (i = 0; i < context->stream_count; i++) {
1247 if (context->streams[i]->mode_changed)
1248 continue;
1249 apply_ctx_interdependent_lock(dc, context, context->streams[i], true);
1250 dc->hwss.apply_ctx_for_surface(
1251 dc, context->streams[i],
1252 context->stream_status[i].plane_count,
1253 context);
1254 apply_ctx_interdependent_lock(dc, context, context->streams[i], false);
1255 dc->hwss.post_unlock_program_front_end(dc, context);
1256 }
1257 }
1258
1259
1260 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1261 pipe = &context->res_ctx.pipe_ctx[i];
1262 dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
1263 }
1264
1265 result = dc->hwss.apply_ctx_to_hw(dc, context);
1266
1267 if (result != DC_OK)
1268 return result;
1269
1270 if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
1271 enable_timing_multisync(dc, context);
1272 program_timing_sync(dc, context);
1273 }
1274
1275
1276 if (dc->hwss.program_front_end_for_ctx) {
1277 dc->hwss.interdependent_update_lock(dc, context, true);
1278 dc->hwss.program_front_end_for_ctx(dc, context);
1279 dc->hwss.interdependent_update_lock(dc, context, false);
1280 dc->hwss.post_unlock_program_front_end(dc, context);
1281 }
1282 for (i = 0; i < context->stream_count; i++) {
1283 const struct dc_link *link = context->streams[i]->link;
1284
1285 if (!context->streams[i]->mode_changed)
1286 continue;
1287
1288 if (dc->hwss.apply_ctx_for_surface) {
1289 apply_ctx_interdependent_lock(dc, context, context->streams[i], true);
1290 dc->hwss.apply_ctx_for_surface(
1291 dc, context->streams[i],
1292 context->stream_status[i].plane_count,
1293 context);
1294 apply_ctx_interdependent_lock(dc, context, context->streams[i], false);
1295 dc->hwss.post_unlock_program_front_end(dc, context);
1296 }
1297
1298
1299
1300
1301
1302 for (k = 0; k < MAX_PIPES; k++) {
1303 pipe = &context->res_ctx.pipe_ctx[k];
1304
1305 for (l = 0 ; pipe && l < context->stream_count; l++) {
1306 if (context->streams[l] &&
1307 context->streams[l] == pipe->stream &&
1308 dc->hwss.setup_stereo)
1309 dc->hwss.setup_stereo(pipe, dc);
1310 }
1311 }
1312
1313 CONN_MSG_MODE(link, "{%dx%d, %dx%d@%dKhz}",
1314 context->streams[i]->timing.h_addressable,
1315 context->streams[i]->timing.v_addressable,
1316 context->streams[i]->timing.h_total,
1317 context->streams[i]->timing.v_total,
1318 context->streams[i]->timing.pix_clk_100hz / 10);
1319 }
1320
1321 dc_enable_stereo(dc, context, dc_streams, context->stream_count);
1322
1323 if (dc->optimize_seamless_boot_streams == 0) {
1324
1325 wait_for_no_pipes_pending(dc, context);
1326
1327 dc->hwss.optimize_bandwidth(dc, context);
1328 }
1329
1330 for (i = 0; i < context->stream_count; i++)
1331 context->streams[i]->mode_changed = false;
1332
1333 dc_release_state(dc->current_state);
1334
1335 dc->current_state = context;
1336
1337 dc_retain_state(dc->current_state);
1338
1339 return result;
1340}
1341
1342bool dc_commit_state(struct dc *dc, struct dc_state *context)
1343{
1344 enum dc_status result = DC_ERROR_UNEXPECTED;
1345 int i;
1346
1347 if (false == context_changed(dc, context))
1348 return DC_OK;
1349
1350 DC_LOG_DC("%s: %d streams\n",
1351 __func__, context->stream_count);
1352
1353 for (i = 0; i < context->stream_count; i++) {
1354 struct dc_stream_state *stream = context->streams[i];
1355
1356 dc_stream_log(dc, stream);
1357 }
1358
1359 result = dc_commit_state_no_check(dc, context);
1360
1361 return (result == DC_OK);
1362}
1363
1364static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
1365{
1366 int i;
1367 struct pipe_ctx *pipe;
1368
1369 for (i = 0; i < MAX_PIPES; i++) {
1370 pipe = &context->res_ctx.pipe_ctx[i];
1371
1372 if (!pipe->plane_state)
1373 continue;
1374
1375
1376 pipe->plane_state->status.is_flip_pending = false;
1377 dc->hwss.update_pending_status(pipe);
1378 if (pipe->plane_state->status.is_flip_pending)
1379 return true;
1380 }
1381 return false;
1382}
1383
1384bool dc_post_update_surfaces_to_stream(struct dc *dc)
1385{
1386 int i;
1387 struct dc_state *context = dc->current_state;
1388
1389 if ((!dc->optimized_required) || dc->optimize_seamless_boot_streams > 0)
1390 return true;
1391
1392 post_surface_trace(dc);
1393
1394 if (is_flip_pending_in_pipes(dc, context))
1395 return true;
1396
1397 for (i = 0; i < dc->res_pool->pipe_count; i++)
1398 if (context->res_ctx.pipe_ctx[i].stream == NULL ||
1399 context->res_ctx.pipe_ctx[i].plane_state == NULL) {
1400 context->res_ctx.pipe_ctx[i].pipe_idx = i;
1401 dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
1402 }
1403
1404 dc->hwss.optimize_bandwidth(dc, context);
1405
1406 dc->optimized_required = false;
1407 dc->wm_optimized_required = false;
1408
1409 return true;
1410}
1411
1412struct dc_state *dc_create_state(struct dc *dc)
1413{
1414 struct dc_state *context = kvzalloc(sizeof(struct dc_state),
1415 GFP_KERNEL);
1416
1417 if (!context)
1418 return NULL;
1419
1420
1421
1422
1423#ifdef CONFIG_DRM_AMD_DC_DCN
1424 memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib));
1425#endif
1426
1427 kref_init(&context->refcount);
1428
1429 return context;
1430}
1431
1432struct dc_state *dc_copy_state(struct dc_state *src_ctx)
1433{
1434 int i, j;
1435 struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL);
1436
1437 if (!new_ctx)
1438 return NULL;
1439 memcpy(new_ctx, src_ctx, sizeof(struct dc_state));
1440
1441 for (i = 0; i < MAX_PIPES; i++) {
1442 struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i];
1443
1444 if (cur_pipe->top_pipe)
1445 cur_pipe->top_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx];
1446
1447 if (cur_pipe->bottom_pipe)
1448 cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx];
1449
1450 if (cur_pipe->prev_odm_pipe)
1451 cur_pipe->prev_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->prev_odm_pipe->pipe_idx];
1452
1453 if (cur_pipe->next_odm_pipe)
1454 cur_pipe->next_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->next_odm_pipe->pipe_idx];
1455
1456 }
1457
1458 for (i = 0; i < new_ctx->stream_count; i++) {
1459 dc_stream_retain(new_ctx->streams[i]);
1460 for (j = 0; j < new_ctx->stream_status[i].plane_count; j++)
1461 dc_plane_state_retain(
1462 new_ctx->stream_status[i].plane_states[j]);
1463 }
1464
1465 kref_init(&new_ctx->refcount);
1466
1467 return new_ctx;
1468}
1469
1470void dc_retain_state(struct dc_state *context)
1471{
1472 kref_get(&context->refcount);
1473}
1474
1475static void dc_state_free(struct kref *kref)
1476{
1477 struct dc_state *context = container_of(kref, struct dc_state, refcount);
1478 dc_resource_state_destruct(context);
1479 kvfree(context);
1480}
1481
1482void dc_release_state(struct dc_state *context)
1483{
1484 kref_put(&context->refcount, dc_state_free);
1485}
1486
1487bool dc_set_generic_gpio_for_stereo(bool enable,
1488 struct gpio_service *gpio_service)
1489{
1490 enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR;
1491 struct gpio_pin_info pin_info;
1492 struct gpio *generic;
1493 struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config),
1494 GFP_KERNEL);
1495
1496 if (!config)
1497 return false;
1498 pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0);
1499
1500 if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) {
1501 kfree(config);
1502 return false;
1503 } else {
1504 generic = dal_gpio_service_create_generic_mux(
1505 gpio_service,
1506 pin_info.offset,
1507 pin_info.mask);
1508 }
1509
1510 if (!generic) {
1511 kfree(config);
1512 return false;
1513 }
1514
1515 gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT);
1516
1517 config->enable_output_from_mux = enable;
1518 config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC;
1519
1520 if (gpio_result == GPIO_RESULT_OK)
1521 gpio_result = dal_mux_setup_config(generic, config);
1522
1523 if (gpio_result == GPIO_RESULT_OK) {
1524 dal_gpio_close(generic);
1525 dal_gpio_destroy_generic_mux(&generic);
1526 kfree(config);
1527 return true;
1528 } else {
1529 dal_gpio_close(generic);
1530 dal_gpio_destroy_generic_mux(&generic);
1531 kfree(config);
1532 return false;
1533 }
1534}
1535
1536static bool is_surface_in_context(
1537 const struct dc_state *context,
1538 const struct dc_plane_state *plane_state)
1539{
1540 int j;
1541
1542 for (j = 0; j < MAX_PIPES; j++) {
1543 const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1544
1545 if (plane_state == pipe_ctx->plane_state) {
1546 return true;
1547 }
1548 }
1549
1550 return false;
1551}
1552
1553static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
1554{
1555 union surface_update_flags *update_flags = &u->surface->update_flags;
1556 enum surface_update_type update_type = UPDATE_TYPE_FAST;
1557
1558 if (!u->plane_info)
1559 return UPDATE_TYPE_FAST;
1560
1561 if (u->plane_info->color_space != u->surface->color_space) {
1562 update_flags->bits.color_space_change = 1;
1563 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1564 }
1565
1566 if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror) {
1567 update_flags->bits.horizontal_mirror_change = 1;
1568 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1569 }
1570
1571 if (u->plane_info->rotation != u->surface->rotation) {
1572 update_flags->bits.rotation_change = 1;
1573 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1574 }
1575
1576 if (u->plane_info->format != u->surface->format) {
1577 update_flags->bits.pixel_format_change = 1;
1578 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1579 }
1580
1581 if (u->plane_info->stereo_format != u->surface->stereo_format) {
1582 update_flags->bits.stereo_format_change = 1;
1583 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1584 }
1585
1586 if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha) {
1587 update_flags->bits.per_pixel_alpha_change = 1;
1588 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1589 }
1590
1591 if (u->plane_info->global_alpha_value != u->surface->global_alpha_value) {
1592 update_flags->bits.global_alpha_change = 1;
1593 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1594 }
1595
1596 if (u->plane_info->dcc.enable != u->surface->dcc.enable
1597 || u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks
1598 || u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) {
1599 update_flags->bits.dcc_change = 1;
1600 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1601 }
1602
1603 if (resource_pixel_format_to_bpp(u->plane_info->format) !=
1604 resource_pixel_format_to_bpp(u->surface->format)) {
1605
1606
1607
1608 update_flags->bits.bpp_change = 1;
1609 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1610 }
1611
1612 if (u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
1613 || u->plane_info->plane_size.chroma_pitch != u->surface->plane_size.chroma_pitch) {
1614 update_flags->bits.plane_size_change = 1;
1615 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1616 }
1617
1618
1619 if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
1620 sizeof(union dc_tiling_info)) != 0) {
1621 update_flags->bits.swizzle_change = 1;
1622 elevate_update_type(&update_type, UPDATE_TYPE_MED);
1623
1624
1625
1626
1627 if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
1628
1629
1630
1631 update_flags->bits.bandwidth_change = 1;
1632 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1633 }
1634 }
1635
1636
1637 return update_type;
1638}
1639
1640static enum surface_update_type get_scaling_info_update_type(
1641 const struct dc_surface_update *u)
1642{
1643 union surface_update_flags *update_flags = &u->surface->update_flags;
1644
1645 if (!u->scaling_info)
1646 return UPDATE_TYPE_FAST;
1647
1648 if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width
1649 || u->scaling_info->clip_rect.height != u->surface->clip_rect.height
1650 || u->scaling_info->dst_rect.width != u->surface->dst_rect.width
1651 || u->scaling_info->dst_rect.height != u->surface->dst_rect.height
1652 || u->scaling_info->scaling_quality.integer_scaling !=
1653 u->surface->scaling_quality.integer_scaling
1654 ) {
1655 update_flags->bits.scaling_change = 1;
1656
1657 if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width
1658 || u->scaling_info->dst_rect.height < u->surface->dst_rect.height)
1659 && (u->scaling_info->dst_rect.width < u->surface->src_rect.width
1660 || u->scaling_info->dst_rect.height < u->surface->src_rect.height))
1661
1662 update_flags->bits.bandwidth_change = 1;
1663 }
1664
1665 if (u->scaling_info->src_rect.width != u->surface->src_rect.width
1666 || u->scaling_info->src_rect.height != u->surface->src_rect.height) {
1667
1668 update_flags->bits.scaling_change = 1;
1669 if (u->scaling_info->src_rect.width > u->surface->src_rect.width
1670 || u->scaling_info->src_rect.height > u->surface->src_rect.height)
1671
1672 update_flags->bits.clock_change = 1;
1673 }
1674
1675 if (u->scaling_info->src_rect.x != u->surface->src_rect.x
1676 || u->scaling_info->src_rect.y != u->surface->src_rect.y
1677 || u->scaling_info->clip_rect.x != u->surface->clip_rect.x
1678 || u->scaling_info->clip_rect.y != u->surface->clip_rect.y
1679 || u->scaling_info->dst_rect.x != u->surface->dst_rect.x
1680 || u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
1681 update_flags->bits.position_change = 1;
1682
1683 if (update_flags->bits.clock_change
1684 || update_flags->bits.bandwidth_change
1685 || update_flags->bits.scaling_change)
1686 return UPDATE_TYPE_FULL;
1687
1688 if (update_flags->bits.position_change)
1689 return UPDATE_TYPE_MED;
1690
1691 return UPDATE_TYPE_FAST;
1692}
1693
1694static enum surface_update_type det_surface_update(const struct dc *dc,
1695 const struct dc_surface_update *u)
1696{
1697 const struct dc_state *context = dc->current_state;
1698 enum surface_update_type type;
1699 enum surface_update_type overall_type = UPDATE_TYPE_FAST;
1700 union surface_update_flags *update_flags = &u->surface->update_flags;
1701
1702 if (u->flip_addr)
1703 update_flags->bits.addr_update = 1;
1704
1705 if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) {
1706 update_flags->raw = 0xFFFFFFFF;
1707 return UPDATE_TYPE_FULL;
1708 }
1709
1710 update_flags->raw = 0;
1711
1712 type = get_plane_info_update_type(u);
1713 elevate_update_type(&overall_type, type);
1714
1715 type = get_scaling_info_update_type(u);
1716 elevate_update_type(&overall_type, type);
1717
1718 if (u->flip_addr)
1719 update_flags->bits.addr_update = 1;
1720
1721 if (u->in_transfer_func)
1722 update_flags->bits.in_transfer_func_change = 1;
1723
1724 if (u->input_csc_color_matrix)
1725 update_flags->bits.input_csc_change = 1;
1726
1727 if (u->coeff_reduction_factor)
1728 update_flags->bits.coeff_reduction_change = 1;
1729
1730 if (u->gamut_remap_matrix)
1731 update_flags->bits.gamut_remap_change = 1;
1732
1733 if (u->gamma) {
1734 enum surface_pixel_format format = SURFACE_PIXEL_FORMAT_GRPH_BEGIN;
1735
1736 if (u->plane_info)
1737 format = u->plane_info->format;
1738 else if (u->surface)
1739 format = u->surface->format;
1740
1741 if (dce_use_lut(format))
1742 update_flags->bits.gamma_change = 1;
1743 }
1744
1745 if (u->hdr_mult.value)
1746 if (u->hdr_mult.value != u->surface->hdr_mult.value) {
1747 update_flags->bits.hdr_mult = 1;
1748 elevate_update_type(&overall_type, UPDATE_TYPE_MED);
1749 }
1750
1751 if (update_flags->bits.in_transfer_func_change) {
1752 type = UPDATE_TYPE_MED;
1753 elevate_update_type(&overall_type, type);
1754 }
1755
1756 if (update_flags->bits.input_csc_change
1757 || update_flags->bits.coeff_reduction_change
1758 || update_flags->bits.gamma_change
1759 || update_flags->bits.gamut_remap_change) {
1760 type = UPDATE_TYPE_FULL;
1761 elevate_update_type(&overall_type, type);
1762 }
1763
1764 return overall_type;
1765}
1766
1767static enum surface_update_type check_update_surfaces_for_stream(
1768 struct dc *dc,
1769 struct dc_surface_update *updates,
1770 int surface_count,
1771 struct dc_stream_update *stream_update,
1772 const struct dc_stream_status *stream_status)
1773{
1774 int i;
1775 enum surface_update_type overall_type = UPDATE_TYPE_FAST;
1776
1777 if (stream_status == NULL || stream_status->plane_count != surface_count)
1778 overall_type = UPDATE_TYPE_FULL;
1779
1780
1781 if (stream_update) {
1782 union stream_update_flags *su_flags = &stream_update->stream->update_flags;
1783
1784 if ((stream_update->src.height != 0 && stream_update->src.width != 0) ||
1785 (stream_update->dst.height != 0 && stream_update->dst.width != 0) ||
1786 stream_update->integer_scaling_update)
1787 su_flags->bits.scaling = 1;
1788
1789 if (stream_update->out_transfer_func)
1790 su_flags->bits.out_tf = 1;
1791
1792 if (stream_update->abm_level)
1793 su_flags->bits.abm_level = 1;
1794
1795 if (stream_update->dpms_off)
1796 su_flags->bits.dpms_off = 1;
1797
1798 if (stream_update->gamut_remap)
1799 su_flags->bits.gamut_remap = 1;
1800
1801 if (stream_update->wb_update)
1802 su_flags->bits.wb_update = 1;
1803
1804 if (stream_update->dsc_config)
1805 su_flags->bits.dsc_changed = 1;
1806
1807 if (su_flags->raw != 0)
1808 overall_type = UPDATE_TYPE_FULL;
1809
1810 if (stream_update->output_csc_transform || stream_update->output_color_space)
1811 su_flags->bits.out_csc = 1;
1812 }
1813
1814 for (i = 0 ; i < surface_count; i++) {
1815 enum surface_update_type type =
1816 det_surface_update(dc, &updates[i]);
1817
1818 elevate_update_type(&overall_type, type);
1819 }
1820
1821 return overall_type;
1822}
1823
1824
1825
1826
1827
1828
1829enum surface_update_type dc_check_update_surfaces_for_stream(
1830 struct dc *dc,
1831 struct dc_surface_update *updates,
1832 int surface_count,
1833 struct dc_stream_update *stream_update,
1834 const struct dc_stream_status *stream_status)
1835{
1836 int i;
1837 enum surface_update_type type;
1838
1839 if (stream_update)
1840 stream_update->stream->update_flags.raw = 0;
1841 for (i = 0; i < surface_count; i++)
1842 updates[i].surface->update_flags.raw = 0;
1843
1844 type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
1845 if (type == UPDATE_TYPE_FULL) {
1846 if (stream_update) {
1847 uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed;
1848 stream_update->stream->update_flags.raw = 0xFFFFFFFF;
1849 stream_update->stream->update_flags.bits.dsc_changed = dsc_changed;
1850 }
1851 for (i = 0; i < surface_count; i++)
1852 updates[i].surface->update_flags.raw = 0xFFFFFFFF;
1853 }
1854
1855 if (type == UPDATE_TYPE_FAST) {
1856
1857 if (dc->clk_mgr->funcs->are_clock_states_equal) {
1858 if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk))
1859 dc->optimized_required = true;
1860
1861 } 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) {
1862 dc->optimized_required = true;
1863 }
1864
1865 dc->optimized_required |= dc->wm_optimized_required;
1866 }
1867
1868 return type;
1869}
1870
1871static struct dc_stream_status *stream_get_status(
1872 struct dc_state *ctx,
1873 struct dc_stream_state *stream)
1874{
1875 uint8_t i;
1876
1877 for (i = 0; i < ctx->stream_count; i++) {
1878 if (stream == ctx->streams[i]) {
1879 return &ctx->stream_status[i];
1880 }
1881 }
1882
1883 return NULL;
1884}
1885
1886static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
1887
1888static void copy_surface_update_to_plane(
1889 struct dc_plane_state *surface,
1890 struct dc_surface_update *srf_update)
1891{
1892 if (srf_update->flip_addr) {
1893 surface->address = srf_update->flip_addr->address;
1894 surface->flip_immediate =
1895 srf_update->flip_addr->flip_immediate;
1896 surface->time.time_elapsed_in_us[surface->time.index] =
1897 srf_update->flip_addr->flip_timestamp_in_us -
1898 surface->time.prev_update_time_in_us;
1899 surface->time.prev_update_time_in_us =
1900 srf_update->flip_addr->flip_timestamp_in_us;
1901 surface->time.index++;
1902 if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
1903 surface->time.index = 0;
1904
1905 surface->triplebuffer_flips = srf_update->flip_addr->triplebuffer_flips;
1906 }
1907
1908 if (srf_update->scaling_info) {
1909 surface->scaling_quality =
1910 srf_update->scaling_info->scaling_quality;
1911 surface->dst_rect =
1912 srf_update->scaling_info->dst_rect;
1913 surface->src_rect =
1914 srf_update->scaling_info->src_rect;
1915 surface->clip_rect =
1916 srf_update->scaling_info->clip_rect;
1917 }
1918
1919 if (srf_update->plane_info) {
1920 surface->color_space =
1921 srf_update->plane_info->color_space;
1922 surface->format =
1923 srf_update->plane_info->format;
1924 surface->plane_size =
1925 srf_update->plane_info->plane_size;
1926 surface->rotation =
1927 srf_update->plane_info->rotation;
1928 surface->horizontal_mirror =
1929 srf_update->plane_info->horizontal_mirror;
1930 surface->stereo_format =
1931 srf_update->plane_info->stereo_format;
1932 surface->tiling_info =
1933 srf_update->plane_info->tiling_info;
1934 surface->visible =
1935 srf_update->plane_info->visible;
1936 surface->per_pixel_alpha =
1937 srf_update->plane_info->per_pixel_alpha;
1938 surface->global_alpha =
1939 srf_update->plane_info->global_alpha;
1940 surface->global_alpha_value =
1941 srf_update->plane_info->global_alpha_value;
1942 surface->dcc =
1943 srf_update->plane_info->dcc;
1944 surface->layer_index =
1945 srf_update->plane_info->layer_index;
1946 }
1947
1948 if (srf_update->gamma &&
1949 (surface->gamma_correction !=
1950 srf_update->gamma)) {
1951 memcpy(&surface->gamma_correction->entries,
1952 &srf_update->gamma->entries,
1953 sizeof(struct dc_gamma_entries));
1954 surface->gamma_correction->is_identity =
1955 srf_update->gamma->is_identity;
1956 surface->gamma_correction->num_entries =
1957 srf_update->gamma->num_entries;
1958 surface->gamma_correction->type =
1959 srf_update->gamma->type;
1960 }
1961
1962 if (srf_update->in_transfer_func &&
1963 (surface->in_transfer_func !=
1964 srf_update->in_transfer_func)) {
1965 surface->in_transfer_func->sdr_ref_white_level =
1966 srf_update->in_transfer_func->sdr_ref_white_level;
1967 surface->in_transfer_func->tf =
1968 srf_update->in_transfer_func->tf;
1969 surface->in_transfer_func->type =
1970 srf_update->in_transfer_func->type;
1971 memcpy(&surface->in_transfer_func->tf_pts,
1972 &srf_update->in_transfer_func->tf_pts,
1973 sizeof(struct dc_transfer_func_distributed_points));
1974 }
1975
1976 if (srf_update->func_shaper &&
1977 (surface->in_shaper_func !=
1978 srf_update->func_shaper))
1979 memcpy(surface->in_shaper_func, srf_update->func_shaper,
1980 sizeof(*surface->in_shaper_func));
1981
1982 if (srf_update->lut3d_func &&
1983 (surface->lut3d_func !=
1984 srf_update->lut3d_func))
1985 memcpy(surface->lut3d_func, srf_update->lut3d_func,
1986 sizeof(*surface->lut3d_func));
1987
1988 if (srf_update->hdr_mult.value)
1989 surface->hdr_mult =
1990 srf_update->hdr_mult;
1991
1992 if (srf_update->blend_tf &&
1993 (surface->blend_tf !=
1994 srf_update->blend_tf))
1995 memcpy(surface->blend_tf, srf_update->blend_tf,
1996 sizeof(*surface->blend_tf));
1997
1998 if (srf_update->input_csc_color_matrix)
1999 surface->input_csc_color_matrix =
2000 *srf_update->input_csc_color_matrix;
2001
2002 if (srf_update->coeff_reduction_factor)
2003 surface->coeff_reduction_factor =
2004 *srf_update->coeff_reduction_factor;
2005
2006 if (srf_update->gamut_remap_matrix)
2007 surface->gamut_remap_matrix =
2008 *srf_update->gamut_remap_matrix;
2009}
2010
2011static void copy_stream_update_to_stream(struct dc *dc,
2012 struct dc_state *context,
2013 struct dc_stream_state *stream,
2014 struct dc_stream_update *update)
2015{
2016 struct dc_context *dc_ctx = dc->ctx;
2017
2018 if (update == NULL || stream == NULL)
2019 return;
2020
2021 if (update->src.height && update->src.width)
2022 stream->src = update->src;
2023
2024 if (update->dst.height && update->dst.width)
2025 stream->dst = update->dst;
2026
2027 if (update->out_transfer_func &&
2028 stream->out_transfer_func != update->out_transfer_func) {
2029 stream->out_transfer_func->sdr_ref_white_level =
2030 update->out_transfer_func->sdr_ref_white_level;
2031 stream->out_transfer_func->tf = update->out_transfer_func->tf;
2032 stream->out_transfer_func->type =
2033 update->out_transfer_func->type;
2034 memcpy(&stream->out_transfer_func->tf_pts,
2035 &update->out_transfer_func->tf_pts,
2036 sizeof(struct dc_transfer_func_distributed_points));
2037 }
2038
2039 if (update->hdr_static_metadata)
2040 stream->hdr_static_metadata = *update->hdr_static_metadata;
2041
2042 if (update->abm_level)
2043 stream->abm_level = *update->abm_level;
2044
2045 if (update->periodic_interrupt0)
2046 stream->periodic_interrupt0 = *update->periodic_interrupt0;
2047
2048 if (update->periodic_interrupt1)
2049 stream->periodic_interrupt1 = *update->periodic_interrupt1;
2050
2051 if (update->gamut_remap)
2052 stream->gamut_remap_matrix = *update->gamut_remap;
2053
2054
2055
2056
2057
2058 if (update->output_color_space)
2059 stream->output_color_space = *update->output_color_space;
2060
2061 if (update->output_csc_transform)
2062 stream->csc_color_matrix = *update->output_csc_transform;
2063
2064 if (update->vrr_infopacket)
2065 stream->vrr_infopacket = *update->vrr_infopacket;
2066
2067 if (update->dpms_off)
2068 stream->dpms_off = *update->dpms_off;
2069
2070 if (update->vsc_infopacket)
2071 stream->vsc_infopacket = *update->vsc_infopacket;
2072
2073 if (update->vsp_infopacket)
2074 stream->vsp_infopacket = *update->vsp_infopacket;
2075
2076 if (update->dither_option)
2077 stream->dither_option = *update->dither_option;
2078
2079 if (update->wb_update) {
2080 int i;
2081
2082 stream->num_wb_info = update->wb_update->num_wb_info;
2083 ASSERT(stream->num_wb_info <= MAX_DWB_PIPES);
2084 for (i = 0; i < stream->num_wb_info; i++)
2085 stream->writeback_info[i] =
2086 update->wb_update->writeback_info[i];
2087 }
2088 if (update->dsc_config) {
2089 struct dc_dsc_config old_dsc_cfg = stream->timing.dsc_cfg;
2090 uint32_t old_dsc_enabled = stream->timing.flags.DSC;
2091 uint32_t enable_dsc = (update->dsc_config->num_slices_h != 0 &&
2092 update->dsc_config->num_slices_v != 0);
2093
2094
2095 struct dc_state *dsc_validate_context = dc_create_state(dc);
2096
2097 if (dsc_validate_context) {
2098 dc_resource_state_copy_construct(dc->current_state, dsc_validate_context);
2099
2100 stream->timing.dsc_cfg = *update->dsc_config;
2101 stream->timing.flags.DSC = enable_dsc;
2102 if (!dc->res_pool->funcs->validate_bandwidth(dc, dsc_validate_context, true)) {
2103 stream->timing.dsc_cfg = old_dsc_cfg;
2104 stream->timing.flags.DSC = old_dsc_enabled;
2105 update->dsc_config = NULL;
2106 }
2107
2108 dc_release_state(dsc_validate_context);
2109 } else {
2110 DC_ERROR("Failed to allocate new validate context for DSC change\n");
2111 update->dsc_config = NULL;
2112 }
2113 }
2114}
2115
2116static void commit_planes_do_stream_update(struct dc *dc,
2117 struct dc_stream_state *stream,
2118 struct dc_stream_update *stream_update,
2119 enum surface_update_type update_type,
2120 struct dc_state *context)
2121{
2122 int j;
2123 bool should_program_abm;
2124
2125
2126 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2127 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2128
2129 if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) {
2130
2131 if (stream_update->periodic_interrupt0 &&
2132 dc->hwss.setup_periodic_interrupt)
2133 dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE0);
2134
2135 if (stream_update->periodic_interrupt1 &&
2136 dc->hwss.setup_periodic_interrupt)
2137 dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE1);
2138
2139 if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
2140 stream_update->vrr_infopacket ||
2141 stream_update->vsc_infopacket ||
2142 stream_update->vsp_infopacket) {
2143 resource_build_info_frame(pipe_ctx);
2144 dc->hwss.update_info_frame(pipe_ctx);
2145 }
2146
2147 if (stream_update->hdr_static_metadata &&
2148 stream->use_dynamic_meta &&
2149 dc->hwss.set_dmdata_attributes &&
2150 pipe_ctx->stream->dmdata_address.quad_part != 0)
2151 dc->hwss.set_dmdata_attributes(pipe_ctx);
2152
2153 if (stream_update->gamut_remap)
2154 dc_stream_set_gamut_remap(dc, stream);
2155
2156 if (stream_update->output_csc_transform)
2157 dc_stream_program_csc_matrix(dc, stream);
2158
2159 if (stream_update->dither_option) {
2160 struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
2161 resource_build_bit_depth_reduction_params(pipe_ctx->stream,
2162 &pipe_ctx->stream->bit_depth_params);
2163 pipe_ctx->stream_res.opp->funcs->opp_program_fmt(pipe_ctx->stream_res.opp,
2164 &stream->bit_depth_params,
2165 &stream->clamping);
2166 while (odm_pipe) {
2167 odm_pipe->stream_res.opp->funcs->opp_program_fmt(odm_pipe->stream_res.opp,
2168 &stream->bit_depth_params,
2169 &stream->clamping);
2170 odm_pipe = odm_pipe->next_odm_pipe;
2171 }
2172 }
2173
2174
2175 if (update_type == UPDATE_TYPE_FAST)
2176 continue;
2177
2178 if (stream_update->dsc_config)
2179 dp_update_dsc_config(pipe_ctx);
2180
2181 if (stream_update->dpms_off) {
2182 if (*stream_update->dpms_off) {
2183 core_link_disable_stream(pipe_ctx);
2184
2185 if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
2186 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
2187
2188 dc->hwss.optimize_bandwidth(dc, dc->current_state);
2189 } else {
2190 if (dc->optimize_seamless_boot_streams == 0)
2191 dc->hwss.prepare_bandwidth(dc, dc->current_state);
2192
2193 core_link_enable_stream(dc->current_state, pipe_ctx);
2194 }
2195 }
2196
2197 if (stream_update->abm_level && pipe_ctx->stream_res.abm) {
2198 should_program_abm = true;
2199
2200
2201 if (pipe_ctx->stream_res.tg->funcs->is_blanked)
2202 if (pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg))
2203 should_program_abm = false;
2204
2205 if (should_program_abm) {
2206 if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
2207 pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm);
2208 } else {
2209 pipe_ctx->stream_res.abm->funcs->set_abm_level(
2210 pipe_ctx->stream_res.abm, stream->abm_level);
2211 }
2212 }
2213 }
2214 }
2215 }
2216}
2217
2218static void commit_planes_for_stream(struct dc *dc,
2219 struct dc_surface_update *srf_updates,
2220 int surface_count,
2221 struct dc_stream_state *stream,
2222 struct dc_stream_update *stream_update,
2223 enum surface_update_type update_type,
2224 struct dc_state *context)
2225{
2226 int i, j;
2227 struct pipe_ctx *top_pipe_to_program = NULL;
2228
2229 if (dc->optimize_seamless_boot_streams > 0 && surface_count > 0) {
2230
2231
2232
2233
2234
2235
2236 if (stream->apply_seamless_boot_optimization) {
2237 stream->apply_seamless_boot_optimization = false;
2238 dc->optimize_seamless_boot_streams--;
2239
2240 if (dc->optimize_seamless_boot_streams == 0)
2241 dc->optimized_required = true;
2242 }
2243 }
2244
2245 if (update_type == UPDATE_TYPE_FULL && dc->optimize_seamless_boot_streams == 0) {
2246 dc->hwss.prepare_bandwidth(dc, context);
2247 context_clock_trace(dc, context);
2248 }
2249
2250 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2251 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2252
2253 if (!pipe_ctx->top_pipe &&
2254 !pipe_ctx->prev_odm_pipe &&
2255 pipe_ctx->stream &&
2256 pipe_ctx->stream == stream) {
2257 top_pipe_to_program = pipe_ctx;
2258 }
2259 }
2260
2261 if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
2262 if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable)
2263 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable(
2264 top_pipe_to_program->stream_res.tg);
2265
2266 if ((update_type != UPDATE_TYPE_FAST) && dc->hwss.interdependent_update_lock)
2267 dc->hwss.interdependent_update_lock(dc, context, true);
2268 else
2269
2270
2271
2272
2273 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
2274
2275
2276
2277 if (stream_update)
2278 commit_planes_do_stream_update(dc, stream, stream_update, update_type, context);
2279
2280 if (surface_count == 0) {
2281
2282
2283
2284
2285 if (dc->hwss.apply_ctx_for_surface)
2286 dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
2287 if (dc->hwss.program_front_end_for_ctx)
2288 dc->hwss.program_front_end_for_ctx(dc, context);
2289
2290 if ((update_type != UPDATE_TYPE_FAST) && dc->hwss.interdependent_update_lock)
2291 dc->hwss.interdependent_update_lock(dc, context, false);
2292 else
2293 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
2294
2295 dc->hwss.post_unlock_program_front_end(dc, context);
2296 return;
2297 }
2298
2299 if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
2300 for (i = 0; i < surface_count; i++) {
2301 struct dc_plane_state *plane_state = srf_updates[i].surface;
2302
2303 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2304 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2305 if (!pipe_ctx->plane_state)
2306 continue;
2307 if (pipe_ctx->plane_state != plane_state)
2308 continue;
2309 plane_state->triplebuffer_flips = false;
2310 if (update_type == UPDATE_TYPE_FAST &&
2311 dc->hwss.program_triplebuffer != NULL &&
2312 !plane_state->flip_immediate &&
2313 !dc->debug.disable_tri_buf) {
2314
2315 plane_state->triplebuffer_flips = true;
2316 }
2317 }
2318 }
2319 }
2320
2321
2322 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2323 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2324
2325 if (!pipe_ctx->top_pipe &&
2326 !pipe_ctx->prev_odm_pipe &&
2327 pipe_ctx->stream &&
2328 pipe_ctx->stream == stream) {
2329 struct dc_stream_status *stream_status = NULL;
2330
2331 if (!pipe_ctx->plane_state)
2332 continue;
2333
2334
2335 if (update_type == UPDATE_TYPE_FAST)
2336 continue;
2337
2338 ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
2339
2340 if (dc->hwss.program_triplebuffer != NULL &&
2341 !dc->debug.disable_tri_buf) {
2342
2343 dc->hwss.program_triplebuffer(
2344 dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
2345 }
2346 stream_status =
2347 stream_get_status(context, pipe_ctx->stream);
2348
2349 if (dc->hwss.apply_ctx_for_surface)
2350 dc->hwss.apply_ctx_for_surface(
2351 dc, pipe_ctx->stream, stream_status->plane_count, context);
2352 }
2353 }
2354 if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) {
2355 dc->hwss.program_front_end_for_ctx(dc, context);
2356#ifdef CONFIG_DRM_AMD_DC_DCN
2357 if (dc->debug.validate_dml_output) {
2358 for (i = 0; i < dc->res_pool->pipe_count; i++) {
2359 struct pipe_ctx cur_pipe = context->res_ctx.pipe_ctx[i];
2360 if (cur_pipe.stream == NULL)
2361 continue;
2362
2363 cur_pipe.plane_res.hubp->funcs->validate_dml_output(
2364 cur_pipe.plane_res.hubp, dc->ctx,
2365 &context->res_ctx.pipe_ctx[i].rq_regs,
2366 &context->res_ctx.pipe_ctx[i].dlg_regs,
2367 &context->res_ctx.pipe_ctx[i].ttu_regs);
2368 }
2369 }
2370#endif
2371 }
2372
2373
2374 if (update_type == UPDATE_TYPE_FAST) {
2375 if (dc->hwss.set_flip_control_gsl)
2376 for (i = 0; i < surface_count; i++) {
2377 struct dc_plane_state *plane_state = srf_updates[i].surface;
2378
2379 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2380 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2381
2382 if (pipe_ctx->stream != stream)
2383 continue;
2384
2385 if (pipe_ctx->plane_state != plane_state)
2386 continue;
2387
2388
2389 dc->hwss.set_flip_control_gsl(pipe_ctx,
2390 plane_state->flip_immediate);
2391 }
2392 }
2393
2394 for (i = 0; i < surface_count; i++) {
2395 struct dc_plane_state *plane_state = srf_updates[i].surface;
2396
2397 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2398 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2399
2400 if (pipe_ctx->stream != stream)
2401 continue;
2402
2403 if (pipe_ctx->plane_state != plane_state)
2404 continue;
2405
2406 if (dc->hwss.program_triplebuffer != NULL &&
2407 !dc->debug.disable_tri_buf) {
2408
2409 dc->hwss.program_triplebuffer(
2410 dc, pipe_ctx, plane_state->triplebuffer_flips);
2411 }
2412 if (srf_updates[i].flip_addr)
2413 dc->hwss.update_plane_addr(dc, pipe_ctx);
2414 }
2415 }
2416 }
2417
2418 if ((update_type != UPDATE_TYPE_FAST) && dc->hwss.interdependent_update_lock)
2419 dc->hwss.interdependent_update_lock(dc, context, false);
2420 else
2421 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
2422
2423 if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
2424 if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
2425 top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
2426 top_pipe_to_program->stream_res.tg,
2427 CRTC_STATE_VACTIVE);
2428 top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
2429 top_pipe_to_program->stream_res.tg,
2430 CRTC_STATE_VBLANK);
2431 top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
2432 top_pipe_to_program->stream_res.tg,
2433 CRTC_STATE_VACTIVE);
2434 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_disable(
2435 top_pipe_to_program->stream_res.tg);
2436 }
2437
2438 if (update_type != UPDATE_TYPE_FAST)
2439 dc->hwss.post_unlock_program_front_end(dc, context);
2440
2441
2442 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2443 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2444
2445 if (pipe_ctx->bottom_pipe ||
2446 !pipe_ctx->stream ||
2447 pipe_ctx->stream != stream ||
2448 !pipe_ctx->plane_state->update_flags.bits.addr_update)
2449 continue;
2450
2451 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger)
2452 pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
2453 }
2454}
2455
2456void dc_commit_updates_for_stream(struct dc *dc,
2457 struct dc_surface_update *srf_updates,
2458 int surface_count,
2459 struct dc_stream_state *stream,
2460 struct dc_stream_update *stream_update,
2461 struct dc_state *state)
2462{
2463 const struct dc_stream_status *stream_status;
2464 enum surface_update_type update_type;
2465 struct dc_state *context;
2466 struct dc_context *dc_ctx = dc->ctx;
2467 int i, j;
2468
2469 stream_status = dc_stream_get_status(stream);
2470 context = dc->current_state;
2471
2472 update_type = dc_check_update_surfaces_for_stream(
2473 dc, srf_updates, surface_count, stream_update, stream_status);
2474
2475 if (update_type >= update_surface_trace_level)
2476 update_surface_trace(dc, srf_updates, surface_count);
2477
2478
2479 if (update_type >= UPDATE_TYPE_FULL) {
2480
2481
2482 context = dc_create_state(dc);
2483 if (context == NULL) {
2484 DC_ERROR("Failed to allocate new validate context!\n");
2485 return;
2486 }
2487
2488 dc_resource_state_copy_construct(state, context);
2489
2490 for (i = 0; i < dc->res_pool->pipe_count; i++) {
2491 struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
2492 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
2493
2494 if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
2495 new_pipe->plane_state->force_full_update = true;
2496 }
2497 }
2498
2499
2500 for (i = 0; i < surface_count; i++) {
2501 struct dc_plane_state *surface = srf_updates[i].surface;
2502
2503 copy_surface_update_to_plane(surface, &srf_updates[i]);
2504
2505 if (update_type >= UPDATE_TYPE_MED) {
2506 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2507 struct pipe_ctx *pipe_ctx =
2508 &context->res_ctx.pipe_ctx[j];
2509
2510 if (pipe_ctx->plane_state != surface)
2511 continue;
2512
2513 resource_build_scaling_params(pipe_ctx);
2514 }
2515 }
2516 }
2517
2518 copy_stream_update_to_stream(dc, context, stream, stream_update);
2519
2520 commit_planes_for_stream(
2521 dc,
2522 srf_updates,
2523 surface_count,
2524 stream,
2525 stream_update,
2526 update_type,
2527 context);
2528
2529 if (dc->current_state != context) {
2530
2531 struct dc_state *old = dc->current_state;
2532
2533 dc->current_state = context;
2534 dc_release_state(old);
2535
2536 for (i = 0; i < dc->res_pool->pipe_count; i++) {
2537 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2538
2539 if (pipe_ctx->plane_state && pipe_ctx->stream == stream)
2540 pipe_ctx->plane_state->force_full_update = false;
2541 }
2542 }
2543
2544 if (update_type >= UPDATE_TYPE_FULL)
2545 dc_post_update_surfaces_to_stream(dc);
2546
2547 return;
2548
2549}
2550
2551uint8_t dc_get_current_stream_count(struct dc *dc)
2552{
2553 return dc->current_state->stream_count;
2554}
2555
2556struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
2557{
2558 if (i < dc->current_state->stream_count)
2559 return dc->current_state->streams[i];
2560 return NULL;
2561}
2562
2563enum dc_irq_source dc_interrupt_to_irq_source(
2564 struct dc *dc,
2565 uint32_t src_id,
2566 uint32_t ext_id)
2567{
2568 return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
2569}
2570
2571
2572
2573
2574bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
2575{
2576
2577 if (dc == NULL)
2578 return false;
2579
2580 return dal_irq_service_set(dc->res_pool->irqs, src, enable);
2581}
2582
2583void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
2584{
2585 dal_irq_service_ack(dc->res_pool->irqs, src);
2586}
2587
2588void dc_set_power_state(
2589 struct dc *dc,
2590 enum dc_acpi_cm_power_state power_state)
2591{
2592 struct kref refcount;
2593 struct display_mode_lib *dml;
2594
2595 switch (power_state) {
2596 case DC_ACPI_CM_POWER_STATE_D0:
2597 dc_resource_state_construct(dc, dc->current_state);
2598
2599 if (dc->ctx->dmub_srv)
2600 dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv);
2601
2602 dc->hwss.init_hw(dc);
2603
2604 if (dc->hwss.init_sys_ctx != NULL &&
2605 dc->vm_pa_config.valid) {
2606 dc->hwss.init_sys_ctx(dc->hwseq, dc, &dc->vm_pa_config);
2607 }
2608
2609 break;
2610 default:
2611 ASSERT(dc->current_state->stream_count == 0);
2612
2613
2614
2615
2616 dml = kzalloc(sizeof(struct display_mode_lib),
2617 GFP_KERNEL);
2618
2619 ASSERT(dml);
2620 if (!dml)
2621 return;
2622
2623
2624 refcount = dc->current_state->refcount;
2625
2626 memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib));
2627
2628 dc_resource_state_destruct(dc->current_state);
2629 memset(dc->current_state, 0,
2630 sizeof(*dc->current_state));
2631
2632 dc->current_state->refcount = refcount;
2633 dc->current_state->bw_ctx.dml = *dml;
2634
2635 kfree(dml);
2636
2637 break;
2638 }
2639}
2640
2641void dc_resume(struct dc *dc)
2642{
2643
2644 uint32_t i;
2645
2646 for (i = 0; i < dc->link_count; i++)
2647 core_link_resume(dc->links[i]);
2648}
2649
2650unsigned int dc_get_current_backlight_pwm(struct dc *dc)
2651{
2652 struct abm *abm = dc->res_pool->abm;
2653
2654 if (abm)
2655 return abm->funcs->get_current_backlight(abm);
2656
2657 return 0;
2658}
2659
2660unsigned int dc_get_target_backlight_pwm(struct dc *dc)
2661{
2662 struct abm *abm = dc->res_pool->abm;
2663
2664 if (abm)
2665 return abm->funcs->get_target_backlight(abm);
2666
2667 return 0;
2668}
2669
2670bool dc_is_dmcu_initialized(struct dc *dc)
2671{
2672 struct dmcu *dmcu = dc->res_pool->dmcu;
2673
2674 if (dmcu)
2675 return dmcu->funcs->is_dmcu_initialized(dmcu);
2676 return false;
2677}
2678
2679bool dc_submit_i2c(
2680 struct dc *dc,
2681 uint32_t link_index,
2682 struct i2c_command *cmd)
2683{
2684
2685 struct dc_link *link = dc->links[link_index];
2686 struct ddc_service *ddc = link->ddc;
2687 return dce_i2c_submit_command(
2688 dc->res_pool,
2689 ddc->ddc_pin,
2690 cmd);
2691}
2692
2693bool dc_submit_i2c_oem(
2694 struct dc *dc,
2695 struct i2c_command *cmd)
2696{
2697 struct ddc_service *ddc = dc->res_pool->oem_device;
2698 return dce_i2c_submit_command(
2699 dc->res_pool,
2700 ddc->ddc_pin,
2701 cmd);
2702}
2703
2704static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
2705{
2706 if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
2707 BREAK_TO_DEBUGGER();
2708 return false;
2709 }
2710
2711 dc_sink_retain(sink);
2712
2713 dc_link->remote_sinks[dc_link->sink_count] = sink;
2714 dc_link->sink_count++;
2715
2716 return true;
2717}
2718
2719
2720
2721
2722
2723
2724struct dc_sink *dc_link_add_remote_sink(
2725 struct dc_link *link,
2726 const uint8_t *edid,
2727 int len,
2728 struct dc_sink_init_data *init_data)
2729{
2730 struct dc_sink *dc_sink;
2731 enum dc_edid_status edid_status;
2732
2733 if (len > DC_MAX_EDID_BUFFER_SIZE) {
2734 dm_error("Max EDID buffer size breached!\n");
2735 return NULL;
2736 }
2737
2738 if (!init_data) {
2739 BREAK_TO_DEBUGGER();
2740 return NULL;
2741 }
2742
2743 if (!init_data->link) {
2744 BREAK_TO_DEBUGGER();
2745 return NULL;
2746 }
2747
2748 dc_sink = dc_sink_create(init_data);
2749
2750 if (!dc_sink)
2751 return NULL;
2752
2753 memmove(dc_sink->dc_edid.raw_edid, edid, len);
2754 dc_sink->dc_edid.length = len;
2755
2756 if (!link_add_remote_sink_helper(
2757 link,
2758 dc_sink))
2759 goto fail_add_sink;
2760
2761 edid_status = dm_helpers_parse_edid_caps(
2762 link->ctx,
2763 &dc_sink->dc_edid,
2764 &dc_sink->edid_caps);
2765
2766
2767
2768
2769
2770 if (edid_status != EDID_OK) {
2771 dc_sink->dc_edid.length = 0;
2772 dm_error("Bad EDID, status%d!\n", edid_status);
2773 }
2774
2775 return dc_sink;
2776
2777fail_add_sink:
2778 dc_sink_release(dc_sink);
2779 return NULL;
2780}
2781
2782
2783
2784
2785
2786
2787
2788void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
2789{
2790 int i;
2791
2792 if (!link->sink_count) {
2793 BREAK_TO_DEBUGGER();
2794 return;
2795 }
2796
2797 for (i = 0; i < link->sink_count; i++) {
2798 if (link->remote_sinks[i] == sink) {
2799 dc_sink_release(sink);
2800 link->remote_sinks[i] = NULL;
2801
2802
2803 while (i < link->sink_count - 1) {
2804 link->remote_sinks[i] = link->remote_sinks[i+1];
2805 i++;
2806 }
2807 link->remote_sinks[i] = NULL;
2808 link->sink_count--;
2809 return;
2810 }
2811 }
2812}
2813
2814void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
2815{
2816 info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
2817 info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz;
2818 info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz;
2819 info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz;
2820 info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz;
2821 info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz;
2822 info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz;
2823 info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz;
2824 info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz;
2825}
2826enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping)
2827{
2828 if (dc->hwss.set_clock)
2829 return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping);
2830 return DC_ERROR_UNEXPECTED;
2831}
2832void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg)
2833{
2834 if (dc->hwss.get_clock)
2835 dc->hwss.get_clock(dc, clock_type, clock_cfg);
2836}
2837