drm/amd/display: revert dc_get_validate_context re-entrancy fix
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / core / dc.c
1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  */
24
25 #include "dm_services.h"
26
27 #include "dc.h"
28
29 #include "core_status.h"
30 #include "core_types.h"
31 #include "hw_sequencer.h"
32
33 #include "resource.h"
34
35 #include "clock_source.h"
36 #include "dc_bios_types.h"
37
38 #include "dce_calcs.h"
39 #include "bios_parser_interface.h"
40 #include "include/irq_service_interface.h"
41 #include "transform.h"
42 #include "timing_generator.h"
43 #include "virtual/virtual_link_encoder.h"
44
45 #include "link_hwss.h"
46 #include "link_encoder.h"
47
48 #include "dc_link_ddc.h"
49 #include "dm_helpers.h"
50 #include "mem_input.h"
51
52 /*******************************************************************************
53  * Private functions
54  ******************************************************************************/
55 static void destroy_links(struct core_dc *dc)
56 {
57         uint32_t i;
58
59         for (i = 0; i < dc->link_count; i++) {
60                 if (NULL != dc->links[i])
61                         link_destroy(&dc->links[i]);
62         }
63 }
64
65 static bool create_links(
66                 struct core_dc *dc,
67                 uint32_t num_virtual_links)
68 {
69         int i;
70         int connectors_num;
71         struct dc_bios *bios = dc->ctx->dc_bios;
72
73         dc->link_count = 0;
74
75         connectors_num = bios->funcs->get_connectors_number(bios);
76
77         if (connectors_num > ENUM_ID_COUNT) {
78                 dm_error(
79                         "DC: Number of connectors %d exceeds maximum of %d!\n",
80                         connectors_num,
81                         ENUM_ID_COUNT);
82                 return false;
83         }
84
85         if (connectors_num == 0 && num_virtual_links == 0) {
86                 dm_error("DC: Number of connectors is zero!\n");
87         }
88
89         dm_output_to_console(
90                 "DC: %s: connectors_num: physical:%d, virtual:%d\n",
91                 __func__,
92                 connectors_num,
93                 num_virtual_links);
94
95         for (i = 0; i < connectors_num; i++) {
96                 struct link_init_data link_init_params = {0};
97                 struct core_link *link;
98
99                 link_init_params.ctx = dc->ctx;
100                 link_init_params.connector_index = i;
101                 link_init_params.link_index = dc->link_count;
102                 link_init_params.dc = dc;
103                 link = link_create(&link_init_params);
104
105                 if (link) {
106                         dc->links[dc->link_count] = link;
107                         link->dc = dc;
108                         ++dc->link_count;
109                 } else {
110                         dm_error("DC: failed to create link!\n");
111                 }
112         }
113
114         for (i = 0; i < num_virtual_links; i++) {
115                 struct core_link *link = dm_alloc(sizeof(*link));
116                 struct encoder_init_data enc_init = {0};
117
118                 if (link == NULL) {
119                         BREAK_TO_DEBUGGER();
120                         goto failed_alloc;
121                 }
122
123                 link->ctx = dc->ctx;
124                 link->dc = dc;
125                 link->public.connector_signal = SIGNAL_TYPE_VIRTUAL;
126                 link->link_id.type = OBJECT_TYPE_CONNECTOR;
127                 link->link_id.id = CONNECTOR_ID_VIRTUAL;
128                 link->link_id.enum_id = ENUM_ID_1;
129                 link->link_enc = dm_alloc(sizeof(*link->link_enc));
130
131                 enc_init.ctx = dc->ctx;
132                 enc_init.channel = CHANNEL_ID_UNKNOWN;
133                 enc_init.hpd_source = HPD_SOURCEID_UNKNOWN;
134                 enc_init.transmitter = TRANSMITTER_UNKNOWN;
135                 enc_init.connector = link->link_id;
136                 enc_init.encoder.type = OBJECT_TYPE_ENCODER;
137                 enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL;
138                 enc_init.encoder.enum_id = ENUM_ID_1;
139                 virtual_link_encoder_construct(link->link_enc, &enc_init);
140
141                 link->public.link_index = dc->link_count;
142                 dc->links[dc->link_count] = link;
143                 dc->link_count++;
144         }
145
146         return true;
147
148 failed_alloc:
149         return false;
150 }
151
152 static bool stream_adjust_vmin_vmax(struct dc *dc,
153                 const struct dc_stream **stream, int num_streams,
154                 int vmin, int vmax)
155 {
156         /* TODO: Support multiple streams */
157         struct core_dc *core_dc = DC_TO_CORE(dc);
158         struct core_stream *core_stream = DC_STREAM_TO_CORE(stream[0]);
159         int i = 0;
160         bool ret = false;
161
162         for (i = 0; i < MAX_PIPES; i++) {
163                 struct pipe_ctx *pipe = &core_dc->current_context->res_ctx.pipe_ctx[i];
164
165                 if (pipe->stream == core_stream && pipe->stream_enc) {
166                         core_dc->hwss.set_drr(&pipe, 1, vmin, vmax);
167
168                         /* build and update the info frame */
169                         resource_build_info_frame(pipe);
170                         core_dc->hwss.update_info_frame(pipe);
171
172                         ret = true;
173                 }
174         }
175         return ret;
176 }
177
178 static bool stream_get_crtc_position(struct dc *dc,
179                 const struct dc_stream **stream, int num_streams,
180                 unsigned int *v_pos, unsigned int *nom_v_pos)
181 {
182         /* TODO: Support multiple streams */
183         struct core_dc *core_dc = DC_TO_CORE(dc);
184         struct core_stream *core_stream = DC_STREAM_TO_CORE(stream[0]);
185         int i = 0;
186         bool ret = false;
187         struct crtc_position position;
188
189         for (i = 0; i < MAX_PIPES; i++) {
190                 struct pipe_ctx *pipe =
191                                 &core_dc->current_context->res_ctx.pipe_ctx[i];
192
193                 if (pipe->stream == core_stream && pipe->stream_enc) {
194                         core_dc->hwss.get_position(&pipe, 1, &position);
195
196                         *v_pos = position.vertical_count;
197                         *nom_v_pos = position.nominal_vcount;
198                         ret = true;
199                 }
200         }
201         return ret;
202 }
203
204 static bool set_gamut_remap(struct dc *dc, const struct dc_stream *stream)
205 {
206         struct core_dc *core_dc = DC_TO_CORE(dc);
207         struct core_stream *core_stream = DC_STREAM_TO_CORE(stream);
208         int i = 0;
209         bool ret = false;
210         struct pipe_ctx *pipes;
211
212         for (i = 0; i < MAX_PIPES; i++) {
213                 if (core_dc->current_context->res_ctx.pipe_ctx[i].stream
214                                 == core_stream) {
215
216                         pipes = &core_dc->current_context->res_ctx.pipe_ctx[i];
217                         core_dc->hwss.set_plane_config(core_dc, pipes,
218                                         &core_dc->current_context->res_ctx);
219                         ret = true;
220                 }
221         }
222
223         return ret;
224 }
225
226 static void set_static_screen_events(struct dc *dc,
227                 const struct dc_stream **stream,
228                 int num_streams,
229                 const struct dc_static_screen_events *events)
230 {
231         struct core_dc *core_dc = DC_TO_CORE(dc);
232         int i = 0;
233         int j = 0;
234         struct pipe_ctx *pipes_affected[MAX_PIPES];
235         int num_pipes_affected = 0;
236
237         for (i = 0; i < num_streams; i++) {
238                 struct core_stream *core_stream = DC_STREAM_TO_CORE(stream[i]);
239
240                 for (j = 0; j < MAX_PIPES; j++) {
241                         if (core_dc->current_context->res_ctx.pipe_ctx[j].stream
242                                         == core_stream) {
243                                 pipes_affected[num_pipes_affected++] =
244                                                 &core_dc->current_context->res_ctx.pipe_ctx[j];
245                         }
246                 }
247         }
248
249         core_dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events);
250 }
251
252 /* This function is not expected to fail, proper implementation of
253  * validation will prevent this from ever being called for unsupported
254  * configurations.
255  */
256 static void stream_update_scaling(
257                 const struct dc *dc,
258                 const struct dc_stream *dc_stream,
259                 const struct rect *src,
260                 const struct rect *dst)
261 {
262         struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
263         struct core_dc *core_dc = DC_TO_CORE(dc);
264         struct validate_context *cur_ctx = core_dc->current_context;
265         int i;
266
267         if (src)
268                 stream->public.src = *src;
269
270         if (dst)
271                 stream->public.dst = *dst;
272
273         for (i = 0; i < cur_ctx->stream_count; i++) {
274                 struct core_stream *cur_stream = cur_ctx->streams[i];
275
276                 if (stream == cur_stream) {
277                         struct dc_stream_status *status = &cur_ctx->stream_status[i];
278
279                         if (status->surface_count)
280                                 if (!dc_commit_surfaces_to_stream(
281                                                 &core_dc->public,
282                                                 status->surfaces,
283                                                 status->surface_count,
284                                                 &cur_stream->public))
285                                         /* Need to debug validation */
286                                         BREAK_TO_DEBUGGER();
287
288                         return;
289                 }
290         }
291 }
292
293 static void set_drive_settings(struct dc *dc,
294                 struct link_training_settings *lt_settings,
295                 const struct dc_link *link)
296 {
297         struct core_dc *core_dc = DC_TO_CORE(dc);
298         int i;
299
300         for (i = 0; i < core_dc->link_count; i++) {
301                 if (&core_dc->links[i]->public == link)
302                         break;
303         }
304
305         if (i >= core_dc->link_count)
306                 ASSERT_CRITICAL(false);
307
308         dc_link_dp_set_drive_settings(&core_dc->links[i]->public, lt_settings);
309 }
310
311 static void perform_link_training(struct dc *dc,
312                 struct dc_link_settings *link_setting,
313                 bool skip_video_pattern)
314 {
315         struct core_dc *core_dc = DC_TO_CORE(dc);
316         int i;
317
318         for (i = 0; i < core_dc->link_count; i++)
319                 dc_link_dp_perform_link_training(
320                         &core_dc->links[i]->public,
321                         link_setting,
322                         skip_video_pattern);
323 }
324
325 static void set_preferred_link_settings(struct dc *dc,
326                 struct dc_link_settings *link_setting,
327                 const struct dc_link *link)
328 {
329         struct core_link *core_link = DC_LINK_TO_CORE(link);
330
331         core_link->public.verified_link_cap.lane_count =
332                                 link_setting->lane_count;
333         core_link->public.verified_link_cap.link_rate =
334                                 link_setting->link_rate;
335         dp_retrain_link_dp_test(core_link, link_setting, false);
336 }
337
338 static void enable_hpd(const struct dc_link *link)
339 {
340         dc_link_dp_enable_hpd(link);
341 }
342
343 static void disable_hpd(const struct dc_link *link)
344 {
345         dc_link_dp_disable_hpd(link);
346 }
347
348
349 static void set_test_pattern(
350                 const struct dc_link *link,
351                 enum dp_test_pattern test_pattern,
352                 const struct link_training_settings *p_link_settings,
353                 const unsigned char *p_custom_pattern,
354                 unsigned int cust_pattern_size)
355 {
356         if (link != NULL)
357                 dc_link_dp_set_test_pattern(
358                         link,
359                         test_pattern,
360                         p_link_settings,
361                         p_custom_pattern,
362                         cust_pattern_size);
363 }
364
365 void set_dither_option(const struct dc_stream *dc_stream,
366                 enum dc_dither_option option)
367 {
368         struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
369         struct bit_depth_reduction_params params;
370         struct core_link *core_link = DC_LINK_TO_CORE(stream->status.link);
371         struct pipe_ctx *pipes =
372                         core_link->dc->current_context->res_ctx.pipe_ctx;
373
374         memset(&params, 0, sizeof(params));
375         if (!stream)
376                 return;
377         if (option > DITHER_OPTION_MAX)
378                 return;
379         if (option == DITHER_OPTION_DEFAULT) {
380                 switch (stream->public.timing.display_color_depth) {
381                 case COLOR_DEPTH_666:
382                         stream->public.dither_option = DITHER_OPTION_SPATIAL6;
383                         break;
384                 case COLOR_DEPTH_888:
385                         stream->public.dither_option = DITHER_OPTION_SPATIAL8;
386                         break;
387                 case COLOR_DEPTH_101010:
388                         stream->public.dither_option = DITHER_OPTION_SPATIAL10;
389                         break;
390                 default:
391                         option = DITHER_OPTION_DISABLE;
392                 }
393         } else {
394                 stream->public.dither_option = option;
395         }
396         resource_build_bit_depth_reduction_params(stream,
397                                 &params);
398         stream->bit_depth_params = params;
399         pipes->opp->funcs->
400                 opp_program_bit_depth_reduction(pipes->opp, &params);
401 }
402
403 static void allocate_dc_stream_funcs(struct core_dc *core_dc)
404 {
405         core_dc->public.stream_funcs.stream_update_scaling = stream_update_scaling;
406         if (core_dc->hwss.set_drr != NULL) {
407                 core_dc->public.stream_funcs.adjust_vmin_vmax =
408                                 stream_adjust_vmin_vmax;
409         }
410
411         core_dc->public.stream_funcs.set_static_screen_events =
412                         set_static_screen_events;
413
414         core_dc->public.stream_funcs.get_crtc_position =
415                         stream_get_crtc_position;
416
417         core_dc->public.stream_funcs.set_gamut_remap =
418                         set_gamut_remap;
419
420         core_dc->public.stream_funcs.set_dither_option =
421                         set_dither_option;
422
423         core_dc->public.link_funcs.set_drive_settings =
424                         set_drive_settings;
425
426         core_dc->public.link_funcs.perform_link_training =
427                         perform_link_training;
428
429         core_dc->public.link_funcs.set_preferred_link_settings =
430                         set_preferred_link_settings;
431
432         core_dc->public.link_funcs.enable_hpd =
433                         enable_hpd;
434
435         core_dc->public.link_funcs.disable_hpd =
436                         disable_hpd;
437
438         core_dc->public.link_funcs.set_test_pattern =
439                         set_test_pattern;
440 }
441
442 static void destruct(struct core_dc *dc)
443 {
444         dc_resource_validate_ctx_destruct(dc->current_context);
445
446         destroy_links(dc);
447
448         dc_destroy_resource_pool(dc);
449
450         if (dc->ctx->gpio_service)
451                 dal_gpio_service_destroy(&dc->ctx->gpio_service);
452
453         if (dc->ctx->i2caux)
454                 dal_i2caux_destroy(&dc->ctx->i2caux);
455
456         if (dc->ctx->created_bios)
457                 dal_bios_parser_destroy(&dc->ctx->dc_bios);
458
459         if (dc->ctx->logger)
460                 dal_logger_destroy(&dc->ctx->logger);
461
462         dm_free(dc->current_context);
463         dc->current_context = NULL;
464
465         dm_free(dc->ctx);
466         dc->ctx = NULL;
467 }
468
469 static bool construct(struct core_dc *dc,
470                 const struct dc_init_data *init_params)
471 {
472         struct dal_logger *logger;
473         struct dc_context *dc_ctx = dm_alloc(sizeof(*dc_ctx));
474         enum dce_version dc_version = DCE_VERSION_UNKNOWN;
475
476         if (!dc_ctx) {
477                 dm_error("%s: failed to create ctx\n", __func__);
478                 goto ctx_fail;
479         }
480
481         dc->current_context = dm_alloc(sizeof(*dc->current_context));
482
483         if (!dc->current_context) {
484                 dm_error("%s: failed to create validate ctx\n", __func__);
485                 goto val_ctx_fail;
486         }
487
488         dc_ctx->cgs_device = init_params->cgs_device;
489         dc_ctx->driver_context = init_params->driver;
490         dc_ctx->dc = &dc->public;
491         dc_ctx->asic_id = init_params->asic_id;
492
493         /* Create logger */
494         logger = dal_logger_create(dc_ctx);
495
496         if (!logger) {
497                 /* can *not* call logger. call base driver 'print error' */
498                 dm_error("%s: failed to create Logger!\n", __func__);
499                 goto logger_fail;
500         }
501         dc_ctx->logger = logger;
502         dc->ctx = dc_ctx;
503         dc->ctx->dce_environment = init_params->dce_environment;
504
505         dc_version = resource_parse_asic_id(init_params->asic_id);
506         dc->ctx->dce_version = dc_version;
507
508         /* Resource should construct all asic specific resources.
509          * This should be the only place where we need to parse the asic id
510          */
511         if (init_params->vbios_override)
512                 dc_ctx->dc_bios = init_params->vbios_override;
513         else {
514                 /* Create BIOS parser */
515                 struct bp_init_data bp_init_data;
516
517                 bp_init_data.ctx = dc_ctx;
518                 bp_init_data.bios = init_params->asic_id.atombios_base_address;
519
520                 dc_ctx->dc_bios = dal_bios_parser_create(
521                                 &bp_init_data, dc_version);
522
523                 if (!dc_ctx->dc_bios) {
524                         ASSERT_CRITICAL(false);
525                         goto bios_fail;
526                 }
527
528                 dc_ctx->created_bios = true;
529                 }
530
531         /* Create I2C AUX */
532         dc_ctx->i2caux = dal_i2caux_create(dc_ctx);
533
534         if (!dc_ctx->i2caux) {
535                 ASSERT_CRITICAL(false);
536                 goto failed_to_create_i2caux;
537         }
538
539         /* Create GPIO service */
540         dc_ctx->gpio_service = dal_gpio_service_create(
541                         dc_version,
542                         dc_ctx->dce_environment,
543                         dc_ctx);
544
545         if (!dc_ctx->gpio_service) {
546                 ASSERT_CRITICAL(false);
547                 goto gpio_fail;
548         }
549
550         dc->res_pool = dc_create_resource_pool(
551                         dc,
552                         init_params->num_virtual_links,
553                         dc_version,
554                         init_params->asic_id);
555         if (!dc->res_pool)
556                 goto create_resource_fail;
557
558         if (!create_links(dc, init_params->num_virtual_links))
559                 goto create_links_fail;
560
561         allocate_dc_stream_funcs(dc);
562
563         return true;
564
565         /**** error handling here ****/
566 create_links_fail:
567 create_resource_fail:
568 gpio_fail:
569 failed_to_create_i2caux:
570 bios_fail:
571 logger_fail:
572 val_ctx_fail:
573 ctx_fail:
574         destruct(dc);
575         return false;
576 }
577
578 /*
579 void ProgramPixelDurationV(unsigned int pixelClockInKHz )
580 {
581         fixed31_32 pixel_duration = Fixed31_32(100000000, pixelClockInKHz) * 10;
582         unsigned int pixDurationInPico = round(pixel_duration);
583
584         DPG_PIPE_ARBITRATION_CONTROL1 arb_control;
585
586         arb_control.u32All = ReadReg (mmDPGV0_PIPE_ARBITRATION_CONTROL1);
587         arb_control.bits.PIXEL_DURATION = pixDurationInPico;
588         WriteReg (mmDPGV0_PIPE_ARBITRATION_CONTROL1, arb_control.u32All);
589
590         arb_control.u32All = ReadReg (mmDPGV1_PIPE_ARBITRATION_CONTROL1);
591         arb_control.bits.PIXEL_DURATION = pixDurationInPico;
592         WriteReg (mmDPGV1_PIPE_ARBITRATION_CONTROL1, arb_control.u32All);
593
594         WriteReg (mmDPGV0_PIPE_ARBITRATION_CONTROL2, 0x4000800);
595         WriteReg (mmDPGV0_REPEATER_PROGRAM, 0x11);
596
597         WriteReg (mmDPGV1_PIPE_ARBITRATION_CONTROL2, 0x4000800);
598         WriteReg (mmDPGV1_REPEATER_PROGRAM, 0x11);
599 }
600 */
601
602 /*******************************************************************************
603  * Public functions
604  ******************************************************************************/
605
606 struct dc *dc_create(const struct dc_init_data *init_params)
607  {
608         struct core_dc *core_dc = dm_alloc(sizeof(*core_dc));
609         unsigned int full_pipe_count;
610
611         if (NULL == core_dc)
612                 goto alloc_fail;
613
614         if (false == construct(core_dc, init_params))
615                 goto construct_fail;
616
617         /*TODO: separate HW and SW initialization*/
618         core_dc->hwss.init_hw(core_dc);
619
620         full_pipe_count = core_dc->res_pool->pipe_count;
621         if (core_dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE)
622                 full_pipe_count--;
623         core_dc->public.caps.max_streams = min(
624                         full_pipe_count,
625                         core_dc->res_pool->stream_enc_count);
626
627         core_dc->public.caps.max_links = core_dc->link_count;
628         core_dc->public.caps.max_audios = core_dc->res_pool->audio_count;
629
630         core_dc->public.config = init_params->flags;
631
632         dm_logger_write(core_dc->ctx->logger, LOG_DC,
633                         "Display Core initialized\n");
634
635
636         /* TODO: missing feature to be enabled */
637         core_dc->public.debug.disable_dfs_bypass = true;
638
639         return &core_dc->public;
640
641 construct_fail:
642         dm_free(core_dc);
643
644 alloc_fail:
645         return NULL;
646 }
647
648 void dc_destroy(struct dc **dc)
649 {
650         struct core_dc *core_dc = DC_TO_CORE(*dc);
651         destruct(core_dc);
652         dm_free(core_dc);
653         *dc = NULL;
654 }
655
656 static bool is_validation_required(
657                 const struct core_dc *dc,
658                 const struct dc_validation_set set[],
659                 int set_count)
660 {
661         const struct validate_context *context = dc->current_context;
662         int i, j;
663
664         if (context->stream_count != set_count)
665                 return true;
666
667         for (i = 0; i < set_count; i++) {
668
669                 if (set[i].surface_count != context->stream_status[i].surface_count)
670                         return true;
671                 if (!is_stream_unchanged(DC_STREAM_TO_CORE(set[i].stream), context->streams[i]))
672                         return true;
673
674                 for (j = 0; j < set[i].surface_count; j++) {
675                         struct dc_surface temp_surf = { 0 };
676
677                         temp_surf = *context->stream_status[i].surfaces[j];
678                         temp_surf.clip_rect = set[i].surfaces[j]->clip_rect;
679                         temp_surf.dst_rect.x = set[i].surfaces[j]->dst_rect.x;
680                         temp_surf.dst_rect.y = set[i].surfaces[j]->dst_rect.y;
681
682                         if (memcmp(&temp_surf, set[i].surfaces[j], sizeof(temp_surf)) != 0)
683                                 return true;
684                 }
685         }
686
687         return false;
688 }
689
690 struct validate_context *dc_get_validate_context(
691                 const struct dc *dc,
692                 const struct dc_validation_set set[],
693                 uint8_t set_count)
694 {
695         struct core_dc *core_dc = DC_TO_CORE(dc);
696         enum dc_status result = DC_ERROR_UNEXPECTED;
697         struct validate_context *context;
698
699         context = dm_alloc(sizeof(struct validate_context));
700         if (context == NULL)
701                 goto context_alloc_fail;
702
703         if (!is_validation_required(core_dc, set, set_count)) {
704                 dc_resource_validate_ctx_copy_construct(core_dc->current_context, context);
705                 return context;
706         }
707
708         result = core_dc->res_pool->funcs->validate_with_context(
709                         core_dc, set, set_count, context, core_dc->current_context);
710
711 context_alloc_fail:
712         if (result != DC_OK) {
713                 dm_logger_write(core_dc->ctx->logger, LOG_WARNING,
714                                 "%s:resource validation failed, dc_status:%d\n",
715                                 __func__,
716                                 result);
717
718                 dc_resource_validate_ctx_destruct(context);
719                 dm_free(context);
720                 context = NULL;
721         }
722
723         return context;
724
725 }
726
727 bool dc_validate_resources(
728                 const struct dc *dc,
729                 const struct dc_validation_set set[],
730                 uint8_t set_count)
731 {
732         struct core_dc *core_dc = DC_TO_CORE(dc);
733         enum dc_status result = DC_ERROR_UNEXPECTED;
734         struct validate_context *context;
735
736         context = dm_alloc(sizeof(struct validate_context));
737         if (context == NULL)
738                 goto context_alloc_fail;
739
740         result = core_dc->res_pool->funcs->validate_with_context(
741                                 core_dc, set, set_count, context, NULL);
742
743 context_alloc_fail:
744         if (result != DC_OK) {
745                 dm_logger_write(core_dc->ctx->logger, LOG_WARNING,
746                                 "%s:resource validation failed, dc_status:%d\n",
747                                 __func__,
748                                 result);
749         }
750
751         dc_resource_validate_ctx_destruct(context);
752         dm_free(context);
753         context = NULL;
754
755         return result == DC_OK;
756 }
757
758 bool dc_validate_guaranteed(
759                 const struct dc *dc,
760                 const struct dc_stream *stream)
761 {
762         struct core_dc *core_dc = DC_TO_CORE(dc);
763         enum dc_status result = DC_ERROR_UNEXPECTED;
764         struct validate_context *context;
765
766         context = dm_alloc(sizeof(struct validate_context));
767         if (context == NULL)
768                 goto context_alloc_fail;
769
770         result = core_dc->res_pool->funcs->validate_guaranteed(
771                                         core_dc, stream, context);
772
773         dc_resource_validate_ctx_destruct(context);
774         dm_free(context);
775
776 context_alloc_fail:
777         if (result != DC_OK) {
778                 dm_logger_write(core_dc->ctx->logger, LOG_WARNING,
779                         "%s:guaranteed validation failed, dc_status:%d\n",
780                         __func__,
781                         result);
782                 }
783
784         return (result == DC_OK);
785 }
786
787 static void program_timing_sync(
788                 struct core_dc *core_dc,
789                 struct validate_context *ctx)
790 {
791         int i, j;
792         int group_index = 0;
793         int pipe_count = core_dc->res_pool->pipe_count;
794         struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
795
796         for (i = 0; i < pipe_count; i++) {
797                 if (!ctx->res_ctx.pipe_ctx[i].stream || ctx->res_ctx.pipe_ctx[i].top_pipe)
798                         continue;
799
800                 unsynced_pipes[i] = &ctx->res_ctx.pipe_ctx[i];
801         }
802
803         for (i = 0; i < pipe_count; i++) {
804                 int group_size = 1;
805                 struct pipe_ctx *pipe_set[MAX_PIPES];
806
807                 if (!unsynced_pipes[i])
808                         continue;
809
810                 pipe_set[0] = unsynced_pipes[i];
811                 unsynced_pipes[i] = NULL;
812
813                 /* Add tg to the set, search rest of the tg's for ones with
814                  * same timing, add all tgs with same timing to the group
815                  */
816                 for (j = i + 1; j < pipe_count; j++) {
817                         if (!unsynced_pipes[j])
818                                 continue;
819
820                         if (resource_are_streams_timing_synchronizable(
821                                         unsynced_pipes[j]->stream,
822                                         pipe_set[0]->stream)) {
823                                 pipe_set[group_size] = unsynced_pipes[j];
824                                 unsynced_pipes[j] = NULL;
825                                 group_size++;
826                         }
827                 }
828
829                 /* set first unblanked pipe as master */
830                 for (j = 0; j < group_size; j++) {
831                         struct pipe_ctx *temp;
832
833                         if (!pipe_set[j]->tg->funcs->is_blanked(pipe_set[j]->tg)) {
834                                 if (j == 0)
835                                         break;
836
837                                 temp = pipe_set[0];
838                                 pipe_set[0] = pipe_set[j];
839                                 pipe_set[j] = temp;
840                                 break;
841                         }
842                 }
843
844                 /* remove any other unblanked pipes as they have already been synced */
845                 for (j = j + 1; j < group_size; j++) {
846                         if (!pipe_set[j]->tg->funcs->is_blanked(pipe_set[j]->tg)) {
847                                 group_size--;
848                                 pipe_set[j] = pipe_set[group_size];
849                                 j--;
850                         }
851                 }
852
853                 if (group_size > 1) {
854                         core_dc->hwss.enable_timing_synchronization(
855                                 core_dc, group_index, group_size, pipe_set);
856                         group_index++;
857                 }
858         }
859 }
860
861 static bool streams_changed(
862                 struct core_dc *dc,
863                 const struct dc_stream *streams[],
864                 uint8_t stream_count)
865 {
866         uint8_t i;
867
868         if (stream_count != dc->current_context->stream_count)
869                 return true;
870
871         for (i = 0; i < dc->current_context->stream_count; i++) {
872                 if (&dc->current_context->streams[i]->public != streams[i])
873                         return true;
874         }
875
876         return false;
877 }
878
879 bool dc_commit_streams(
880         struct dc *dc,
881         const struct dc_stream *streams[],
882         uint8_t stream_count)
883 {
884         struct core_dc *core_dc = DC_TO_CORE(dc);
885         struct dc_bios *dcb = core_dc->ctx->dc_bios;
886         enum dc_status result = DC_ERROR_UNEXPECTED;
887         struct validate_context *context;
888         struct dc_validation_set set[MAX_STREAMS] = { {0, {0} } };
889         int i, j;
890
891         if (false == streams_changed(core_dc, streams, stream_count))
892                 return DC_OK;
893
894         dm_logger_write(core_dc->ctx->logger, LOG_DC, "%s: %d streams\n",
895                                 __func__, stream_count);
896
897         for (i = 0; i < stream_count; i++) {
898                 const struct dc_stream *stream = streams[i];
899                 const struct dc_stream_status *status = dc_stream_get_status(stream);
900                 int j;
901
902                 dc_stream_log(stream,
903                                 core_dc->ctx->logger,
904                                 LOG_DC);
905
906                 set[i].stream = stream;
907
908                 if (status) {
909                         set[i].surface_count = status->surface_count;
910                         for (j = 0; j < status->surface_count; j++)
911                                 set[i].surfaces[j] = status->surfaces[j];
912                 }
913
914         }
915
916         context = dm_alloc(sizeof(struct validate_context));
917         if (context == NULL)
918                 goto context_alloc_fail;
919
920         result = core_dc->res_pool->funcs->validate_with_context(
921                         core_dc, set, stream_count, context, core_dc->current_context);
922         if (result != DC_OK){
923                 dm_logger_write(core_dc->ctx->logger, LOG_ERROR,
924                                         "%s: Context validation failed! dc_status:%d\n",
925                                         __func__,
926                                         result);
927                 BREAK_TO_DEBUGGER();
928                 dc_resource_validate_ctx_destruct(context);
929                 goto fail;
930         }
931
932         if (!dcb->funcs->is_accelerated_mode(dcb)) {
933                 core_dc->hwss.enable_accelerated_mode(core_dc);
934         }
935
936         if (result == DC_OK) {
937                 result = core_dc->hwss.apply_ctx_to_hw(core_dc, context);
938         }
939
940         program_timing_sync(core_dc, context);
941
942         for (i = 0; i < context->stream_count; i++) {
943                 const struct core_sink *sink = context->streams[i]->sink;
944
945                 for (j = 0; j < context->stream_status[i].surface_count; j++) {
946                         struct core_surface *surface =
947                                         DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]);
948
949                         core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
950                 }
951
952                 CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
953                                 context->streams[i]->public.timing.h_addressable,
954                                 context->streams[i]->public.timing.v_addressable,
955                                 context->streams[i]->public.timing.h_total,
956                                 context->streams[i]->public.timing.v_total,
957                                 context->streams[i]->public.timing.pix_clk_khz);
958         }
959
960         dc_resource_validate_ctx_destruct(core_dc->current_context);
961         dm_free(core_dc->current_context);
962
963         core_dc->current_context = context;
964
965         return (result == DC_OK);
966
967 fail:
968         dm_free(context);
969
970 context_alloc_fail:
971         return (result == DC_OK);
972 }
973
974 bool dc_pre_update_surfaces_to_stream(
975                 struct dc *dc,
976                 const struct dc_surface *const *new_surfaces,
977                 uint8_t new_surface_count,
978                 const struct dc_stream *dc_stream)
979 {
980         return true;
981 }
982
983 bool dc_post_update_surfaces_to_stream(struct dc *dc)
984 {
985         int i;
986         struct core_dc *core_dc = DC_TO_CORE(dc);
987         struct validate_context *context = core_dc->current_context;
988
989         post_surface_trace(dc);
990
991         for (i = 0; i < core_dc->res_pool->pipe_count; i++)
992                 if (context->res_ctx.pipe_ctx[i].stream == NULL) {
993                         context->res_ctx.pipe_ctx[i].pipe_idx = i;
994                         core_dc->hwss.power_down_front_end(
995                                         core_dc, &context->res_ctx.pipe_ctx[i]);
996                 }
997
998         core_dc->hwss.set_bandwidth(core_dc, context, true);
999
1000         return true;
1001 }
1002
1003 bool dc_commit_surfaces_to_stream(
1004                 struct dc *dc,
1005                 const struct dc_surface **new_surfaces,
1006                 uint8_t new_surface_count,
1007                 const struct dc_stream *dc_stream)
1008 {
1009         struct dc_surface_update updates[MAX_SURFACES];
1010         struct dc_flip_addrs flip_addr[MAX_SURFACES];
1011         struct dc_plane_info plane_info[MAX_SURFACES];
1012         struct dc_scaling_info scaling_info[MAX_SURFACES];
1013         int i;
1014
1015         memset(updates, 0, sizeof(updates));
1016         memset(flip_addr, 0, sizeof(flip_addr));
1017         memset(plane_info, 0, sizeof(plane_info));
1018         memset(scaling_info, 0, sizeof(scaling_info));
1019
1020         for (i = 0; i < new_surface_count; i++) {
1021                 updates[i].surface = new_surfaces[i];
1022                 updates[i].gamma =
1023                         (struct dc_gamma *)new_surfaces[i]->gamma_correction;
1024                 flip_addr[i].address = new_surfaces[i]->address;
1025                 flip_addr[i].flip_immediate = new_surfaces[i]->flip_immediate;
1026                 plane_info[i].color_space = new_surfaces[i]->color_space;
1027                 plane_info[i].format = new_surfaces[i]->format;
1028                 plane_info[i].plane_size = new_surfaces[i]->plane_size;
1029                 plane_info[i].rotation = new_surfaces[i]->rotation;
1030                 plane_info[i].horizontal_mirror = new_surfaces[i]->horizontal_mirror;
1031                 plane_info[i].stereo_format = new_surfaces[i]->stereo_format;
1032                 plane_info[i].tiling_info = new_surfaces[i]->tiling_info;
1033                 plane_info[i].visible = new_surfaces[i]->visible;
1034                 plane_info[i].dcc = new_surfaces[i]->dcc;
1035                 scaling_info[i].scaling_quality = new_surfaces[i]->scaling_quality;
1036                 scaling_info[i].src_rect = new_surfaces[i]->src_rect;
1037                 scaling_info[i].dst_rect = new_surfaces[i]->dst_rect;
1038                 scaling_info[i].clip_rect = new_surfaces[i]->clip_rect;
1039
1040                 updates[i].flip_addr = &flip_addr[i];
1041                 updates[i].plane_info = &plane_info[i];
1042                 updates[i].scaling_info = &scaling_info[i];
1043         }
1044         dc_update_surfaces_for_stream(dc, updates, new_surface_count, dc_stream);
1045
1046         return dc_post_update_surfaces_to_stream(dc);
1047 }
1048
1049 static bool is_surface_in_context(
1050                 const struct validate_context *context,
1051                 const struct dc_surface *surface)
1052 {
1053         int j;
1054
1055         for (j = 0; j < MAX_PIPES; j++) {
1056                 const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1057
1058                 if (surface == &pipe_ctx->surface->public) {
1059                         return true;
1060                 }
1061         }
1062
1063         return false;
1064 }
1065
1066 static unsigned int pixel_format_to_bpp(enum surface_pixel_format format)
1067 {
1068         switch (format) {
1069         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
1070         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
1071                 return 12;
1072         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
1073         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
1074         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
1075         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
1076                 return 16;
1077         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
1078         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
1079         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
1080         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
1081                 return 32;
1082         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
1083         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
1084         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
1085                 return 64;
1086         default:
1087                 ASSERT_CRITICAL(false);
1088                 return -1;
1089         }
1090 }
1091
1092 static enum surface_update_type get_plane_info_update_type(
1093                 const struct dc_surface_update *u,
1094                 int surface_index)
1095 {
1096         struct dc_plane_info temp_plane_info = { { { { 0 } } } };
1097
1098         if (!u->plane_info)
1099                 return UPDATE_TYPE_FAST;
1100
1101         /* Copy all parameters that will cause a full update
1102          * from current surface, the rest of the parameters
1103          * from provided plane configuration.
1104          * Perform memory compare and special validation
1105          * for those that can cause fast/medium updates
1106          */
1107
1108         /* Full update parameters */
1109         temp_plane_info.color_space = u->surface->color_space;
1110         temp_plane_info.dcc = u->surface->dcc;
1111         temp_plane_info.horizontal_mirror = u->surface->horizontal_mirror;
1112         temp_plane_info.plane_size = u->surface->plane_size;
1113         temp_plane_info.rotation = u->surface->rotation;
1114         temp_plane_info.stereo_format = u->surface->stereo_format;
1115         temp_plane_info.tiling_info = u->surface->tiling_info;
1116
1117         /* Special Validation parameters */
1118         temp_plane_info.format = u->plane_info->format;
1119
1120         if (surface_index == 0)
1121                 temp_plane_info.visible = u->plane_info->visible;
1122         else
1123                 temp_plane_info.visible = u->surface->visible;
1124
1125         if (memcmp(u->plane_info, &temp_plane_info,
1126                         sizeof(struct dc_plane_info)) != 0)
1127                 return UPDATE_TYPE_FULL;
1128
1129         if (pixel_format_to_bpp(u->plane_info->format) !=
1130                         pixel_format_to_bpp(u->surface->format)) {
1131                 return UPDATE_TYPE_FULL;
1132         } else {
1133                 return UPDATE_TYPE_MED;
1134         }
1135 }
1136
1137 static enum surface_update_type  get_scaling_info_update_type(
1138                 const struct dc_surface_update *u)
1139 {
1140         if (!u->scaling_info)
1141                 return UPDATE_TYPE_FAST;
1142
1143         if (u->scaling_info->src_rect.width != u->surface->src_rect.width
1144                         || u->scaling_info->src_rect.height != u->surface->src_rect.height
1145                         || u->scaling_info->clip_rect.width != u->surface->clip_rect.width
1146                         || u->scaling_info->clip_rect.height != u->surface->clip_rect.height
1147                         || u->scaling_info->dst_rect.width != u->surface->dst_rect.width
1148                         || u->scaling_info->dst_rect.height != u->surface->dst_rect.height)
1149                 return UPDATE_TYPE_FULL;
1150
1151         if (u->scaling_info->src_rect.x != u->surface->src_rect.x
1152                         || u->scaling_info->src_rect.y != u->surface->src_rect.y
1153                         || u->scaling_info->clip_rect.x != u->surface->clip_rect.x
1154                         || u->scaling_info->clip_rect.y != u->surface->clip_rect.y
1155                         || u->scaling_info->dst_rect.x != u->surface->dst_rect.x
1156                         || u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
1157                 return UPDATE_TYPE_MED;
1158
1159         return UPDATE_TYPE_FAST;
1160 }
1161
1162 static enum surface_update_type det_surface_update(
1163                 const struct core_dc *dc,
1164                 const struct dc_surface_update *u,
1165                 int surface_index)
1166 {
1167         const struct validate_context *context = dc->current_context;
1168         enum surface_update_type type = UPDATE_TYPE_FAST;
1169         enum surface_update_type overall_type = UPDATE_TYPE_FAST;
1170
1171         if (!is_surface_in_context(context, u->surface))
1172                 return UPDATE_TYPE_FULL;
1173
1174         type = get_plane_info_update_type(u, surface_index);
1175         if (overall_type < type)
1176                 overall_type = type;
1177
1178         type = get_scaling_info_update_type(u);
1179         if (overall_type < type)
1180                 overall_type = type;
1181
1182         if (u->in_transfer_func ||
1183                 u->hdr_static_metadata) {
1184                 if (overall_type < UPDATE_TYPE_MED)
1185                         overall_type = UPDATE_TYPE_MED;
1186         }
1187
1188         return overall_type;
1189 }
1190
1191 enum surface_update_type dc_check_update_surfaces_for_stream(
1192                 struct dc *dc,
1193                 struct dc_surface_update *updates,
1194                 int surface_count,
1195                 struct dc_stream_update *stream_update,
1196                 const struct dc_stream_status *stream_status)
1197 {
1198         struct core_dc *core_dc = DC_TO_CORE(dc);
1199         int i;
1200         enum surface_update_type overall_type = UPDATE_TYPE_FAST;
1201
1202         if (stream_status == NULL || stream_status->surface_count != surface_count)
1203                 return UPDATE_TYPE_FULL;
1204
1205         if (stream_update)
1206                 return UPDATE_TYPE_FULL;
1207
1208         for (i = 0 ; i < surface_count; i++) {
1209                 enum surface_update_type type =
1210                                 det_surface_update(core_dc, &updates[i], i);
1211
1212                 if (type == UPDATE_TYPE_FULL)
1213                         return type;
1214
1215                 if (overall_type < type)
1216                         overall_type = type;
1217         }
1218
1219         return overall_type;
1220 }
1221
1222 void dc_update_surfaces_for_stream(struct dc *dc,
1223                 struct dc_surface_update *surface_updates, int surface_count,
1224                 const struct dc_stream *dc_stream)
1225 {
1226         dc_update_surfaces_and_stream(dc, surface_updates, surface_count,
1227                         dc_stream, NULL);
1228 }
1229
1230 enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
1231
1232 void dc_update_surfaces_and_stream(struct dc *dc,
1233                 struct dc_surface_update *srf_updates, int surface_count,
1234                 const struct dc_stream *dc_stream,
1235                 struct dc_stream_update *stream_update)
1236 {
1237         struct core_dc *core_dc = DC_TO_CORE(dc);
1238         struct validate_context *context;
1239         int i, j;
1240         enum surface_update_type update_type;
1241         const struct dc_stream_status *stream_status;
1242         struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
1243
1244         stream_status = dc_stream_get_status(dc_stream);
1245         ASSERT(stream_status);
1246         if (!stream_status)
1247                 return; /* Cannot commit surface to stream that is not committed */
1248
1249         update_type = dc_check_update_surfaces_for_stream(
1250                         dc, srf_updates, surface_count, stream_update, stream_status);
1251
1252         if (update_type >= update_surface_trace_level)
1253                 update_surface_trace(dc, srf_updates, surface_count);
1254
1255         if (update_type >= UPDATE_TYPE_FULL) {
1256                 const struct dc_surface *new_surfaces[MAX_SURFACES] = { 0 };
1257
1258                 for (i = 0; i < surface_count; i++)
1259                         new_surfaces[i] = srf_updates[i].surface;
1260
1261                 /* initialize scratch memory for building context */
1262                 context = dm_alloc(sizeof(*context));
1263                 dc_resource_validate_ctx_copy_construct(
1264                                 core_dc->current_context, context);
1265
1266                 /* add surface to context */
1267                 if (!resource_attach_surfaces_to_context(
1268                                 new_surfaces, surface_count, dc_stream,
1269                                 context, core_dc->res_pool)) {
1270                         BREAK_TO_DEBUGGER();
1271                         goto fail;
1272                 }
1273         } else {
1274                 context = core_dc->current_context;
1275         }
1276
1277         /* update current stream with the new updates */
1278         if (stream_update) {
1279                 if ((stream_update->src.height != 0) &&
1280                                 (stream_update->src.width != 0))
1281                         stream->public.src = stream_update->src;
1282
1283                 if ((stream_update->dst.height != 0) &&
1284                                 (stream_update->dst.width != 0))
1285                         stream->public.dst = stream_update->dst;
1286
1287                 if (stream_update->out_transfer_func &&
1288                                 stream_update->out_transfer_func !=
1289                                 dc_stream->out_transfer_func) {
1290                         if (stream_update->out_transfer_func->type !=
1291                                         TF_TYPE_UNKNOWN) {
1292                                 if (dc_stream->out_transfer_func != NULL)
1293                                         dc_transfer_func_release
1294                                         (dc_stream->out_transfer_func);
1295                                 dc_transfer_func_retain(stream_update->
1296                                         out_transfer_func);
1297                                 stream->public.out_transfer_func =
1298                                         stream_update->out_transfer_func;
1299                         }
1300                 }
1301         }
1302
1303         /* save update parameters into surface */
1304         for (i = 0; i < surface_count; i++) {
1305                 struct core_surface *surface =
1306                                 DC_SURFACE_TO_CORE(srf_updates[i].surface);
1307
1308                 if (srf_updates[i].flip_addr) {
1309                         surface->public.address = srf_updates[i].flip_addr->address;
1310                         surface->public.flip_immediate =
1311                                         srf_updates[i].flip_addr->flip_immediate;
1312                 }
1313
1314                 if (srf_updates[i].scaling_info) {
1315                         surface->public.scaling_quality =
1316                                         srf_updates[i].scaling_info->scaling_quality;
1317                         surface->public.dst_rect =
1318                                         srf_updates[i].scaling_info->dst_rect;
1319                         surface->public.src_rect =
1320                                         srf_updates[i].scaling_info->src_rect;
1321                         surface->public.clip_rect =
1322                                         srf_updates[i].scaling_info->clip_rect;
1323                 }
1324
1325                 if (srf_updates[i].plane_info) {
1326                         surface->public.color_space =
1327                                         srf_updates[i].plane_info->color_space;
1328                         surface->public.format =
1329                                         srf_updates[i].plane_info->format;
1330                         surface->public.plane_size =
1331                                         srf_updates[i].plane_info->plane_size;
1332                         surface->public.rotation =
1333                                         srf_updates[i].plane_info->rotation;
1334                         surface->public.horizontal_mirror =
1335                                         srf_updates[i].plane_info->horizontal_mirror;
1336                         surface->public.stereo_format =
1337                                         srf_updates[i].plane_info->stereo_format;
1338                         surface->public.tiling_info =
1339                                         srf_updates[i].plane_info->tiling_info;
1340                         surface->public.visible =
1341                                         srf_updates[i].plane_info->visible;
1342                         surface->public.dcc =
1343                                         srf_updates[i].plane_info->dcc;
1344                 }
1345
1346                 if (update_type >= UPDATE_TYPE_MED) {
1347                         for (j = 0; j < core_dc->res_pool->pipe_count; j++) {
1348                                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1349
1350                                 if (pipe_ctx->surface != surface)
1351                                         continue;
1352
1353                                 resource_build_scaling_params(pipe_ctx);
1354                         }
1355                 }
1356
1357                 if (srf_updates[i].gamma &&
1358                         srf_updates[i].gamma != surface->public.gamma_correction) {
1359                         if (surface->public.gamma_correction != NULL)
1360                                 dc_gamma_release(&surface->public.
1361                                                 gamma_correction);
1362
1363                         dc_gamma_retain(srf_updates[i].gamma);
1364                         surface->public.gamma_correction =
1365                                                 srf_updates[i].gamma;
1366                 }
1367
1368                 if (srf_updates[i].in_transfer_func &&
1369                         srf_updates[i].in_transfer_func != surface->public.in_transfer_func) {
1370                         if (surface->public.in_transfer_func != NULL)
1371                                 dc_transfer_func_release(
1372                                                 surface->public.
1373                                                 in_transfer_func);
1374
1375                         dc_transfer_func_retain(
1376                                         srf_updates[i].in_transfer_func);
1377                         surface->public.in_transfer_func =
1378                                         srf_updates[i].in_transfer_func;
1379                 }
1380
1381                 if (srf_updates[i].hdr_static_metadata)
1382                         surface->public.hdr_static_ctx =
1383                                 *(srf_updates[i].hdr_static_metadata);
1384         }
1385
1386         if (update_type == UPDATE_TYPE_FULL) {
1387                 if (!core_dc->res_pool->funcs->validate_bandwidth(core_dc, context)) {
1388                         BREAK_TO_DEBUGGER();
1389                         goto fail;
1390                 } else
1391                         core_dc->hwss.set_bandwidth(core_dc, context, false);
1392         }
1393
1394         if (!surface_count)  /* reset */
1395                 core_dc->hwss.apply_ctx_for_surface(core_dc, NULL, context);
1396
1397         /* Lock pipes for provided surfaces */
1398         for (i = 0; i < surface_count; i++) {
1399                 struct core_surface *surface = DC_SURFACE_TO_CORE(srf_updates[i].surface);
1400
1401                 for (j = 0; j < core_dc->res_pool->pipe_count; j++) {
1402                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1403
1404                         if (pipe_ctx->surface != surface)
1405                                 continue;
1406                         if (!pipe_ctx->tg->funcs->is_blanked(pipe_ctx->tg)) {
1407                                 core_dc->hwss.pipe_control_lock(
1408                                                 core_dc,
1409                                                 pipe_ctx,
1410                                                 true);
1411                         }
1412                 }
1413         }
1414
1415         /* Perform requested Updates */
1416         for (i = 0; i < surface_count; i++) {
1417                 struct core_surface *surface = DC_SURFACE_TO_CORE(srf_updates[i].surface);
1418
1419                 if (update_type >= UPDATE_TYPE_MED) {
1420                                 core_dc->hwss.apply_ctx_for_surface(
1421                                                 core_dc, surface, context);
1422                                 context_timing_trace(dc, &context->res_ctx);
1423                 }
1424
1425                 for (j = 0; j < core_dc->res_pool->pipe_count; j++) {
1426                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1427                         struct pipe_ctx *cur_pipe_ctx;
1428                         bool is_new_pipe_surface = true;
1429
1430                         if (pipe_ctx->surface != surface)
1431                                 continue;
1432
1433                         if (srf_updates[i].flip_addr)
1434                                 core_dc->hwss.update_plane_addr(core_dc, pipe_ctx);
1435
1436                         if (update_type == UPDATE_TYPE_FAST)
1437                                 continue;
1438
1439                         cur_pipe_ctx = &core_dc->current_context->res_ctx.pipe_ctx[j];
1440                         if (cur_pipe_ctx->surface == pipe_ctx->surface)
1441                                 is_new_pipe_surface = false;
1442
1443                         if (is_new_pipe_surface ||
1444                                         srf_updates[i].in_transfer_func)
1445                                 core_dc->hwss.set_input_transfer_func(
1446                                                 pipe_ctx, pipe_ctx->surface);
1447
1448                         if (is_new_pipe_surface ||
1449                                 (stream_update != NULL &&
1450                                         stream_update->out_transfer_func !=
1451                                                         NULL)) {
1452                                 core_dc->hwss.set_output_transfer_func(
1453                                                 pipe_ctx, pipe_ctx->stream);
1454                         }
1455
1456                         if (srf_updates[i].hdr_static_metadata) {
1457                                 resource_build_info_frame(pipe_ctx);
1458                                 core_dc->hwss.update_info_frame(pipe_ctx);
1459                         }
1460                 }
1461         }
1462
1463         /* Unlock pipes */
1464         for (i = core_dc->res_pool->pipe_count - 1; i >= 0; i--) {
1465                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1466
1467                 for (j = 0; j < surface_count; j++) {
1468                         if (srf_updates[j].surface == &pipe_ctx->surface->public) {
1469                                 if (!pipe_ctx->tg->funcs->is_blanked(pipe_ctx->tg)) {
1470                                         core_dc->hwss.pipe_control_lock(
1471                                                         core_dc,
1472                                                         pipe_ctx,
1473                                                         false);
1474                                 }
1475                                 break;
1476                         }
1477                 }
1478         }
1479
1480         if (core_dc->current_context != context) {
1481                 dc_resource_validate_ctx_destruct(core_dc->current_context);
1482                 dm_free(core_dc->current_context);
1483
1484                 core_dc->current_context = context;
1485         }
1486         return;
1487
1488 fail:
1489         dc_resource_validate_ctx_destruct(context);
1490         dm_free(context);
1491 }
1492
1493 uint8_t dc_get_current_stream_count(const struct dc *dc)
1494 {
1495         struct core_dc *core_dc = DC_TO_CORE(dc);
1496         return core_dc->current_context->stream_count;
1497 }
1498
1499 struct dc_stream *dc_get_stream_at_index(const struct dc *dc, uint8_t i)
1500 {
1501         struct core_dc *core_dc = DC_TO_CORE(dc);
1502         if (i < core_dc->current_context->stream_count)
1503                 return &(core_dc->current_context->streams[i]->public);
1504         return NULL;
1505 }
1506
1507 const struct dc_link *dc_get_link_at_index(const struct dc *dc, uint32_t link_index)
1508 {
1509         struct core_dc *core_dc = DC_TO_CORE(dc);
1510         return &core_dc->links[link_index]->public;
1511 }
1512
1513 const struct graphics_object_id dc_get_link_id_at_index(
1514         struct dc *dc, uint32_t link_index)
1515 {
1516         struct core_dc *core_dc = DC_TO_CORE(dc);
1517         return core_dc->links[link_index]->link_id;
1518 }
1519
1520 enum dc_irq_source dc_get_hpd_irq_source_at_index(
1521         struct dc *dc, uint32_t link_index)
1522 {
1523         struct core_dc *core_dc = DC_TO_CORE(dc);
1524         return core_dc->links[link_index]->public.irq_source_hpd;
1525 }
1526
1527 const struct audio **dc_get_audios(struct dc *dc)
1528 {
1529         struct core_dc *core_dc = DC_TO_CORE(dc);
1530         return (const struct audio **)core_dc->res_pool->audios;
1531 }
1532
1533 enum dc_irq_source dc_interrupt_to_irq_source(
1534                 struct dc *dc,
1535                 uint32_t src_id,
1536                 uint32_t ext_id)
1537 {
1538         struct core_dc *core_dc = DC_TO_CORE(dc);
1539         return dal_irq_service_to_irq_source(core_dc->res_pool->irqs, src_id, ext_id);
1540 }
1541
1542 void dc_interrupt_set(const struct dc *dc, enum dc_irq_source src, bool enable)
1543 {
1544         struct core_dc *core_dc = DC_TO_CORE(dc);
1545         dal_irq_service_set(core_dc->res_pool->irqs, src, enable);
1546 }
1547
1548 void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
1549 {
1550         struct core_dc *core_dc = DC_TO_CORE(dc);
1551         dal_irq_service_ack(core_dc->res_pool->irqs, src);
1552 }
1553
1554 void dc_set_power_state(
1555         struct dc *dc,
1556         enum dc_acpi_cm_power_state power_state)
1557 {
1558         struct core_dc *core_dc = DC_TO_CORE(dc);
1559
1560         switch (power_state) {
1561         case DC_ACPI_CM_POWER_STATE_D0:
1562                 core_dc->hwss.init_hw(core_dc);
1563                 break;
1564         default:
1565
1566                 core_dc->hwss.power_down(core_dc);
1567
1568                 /* Zero out the current context so that on resume we start with
1569                  * clean state, and dc hw programming optimizations will not
1570                  * cause any trouble.
1571                  */
1572                 memset(core_dc->current_context, 0,
1573                                 sizeof(*core_dc->current_context));
1574
1575                 break;
1576         }
1577
1578 }
1579
1580 void dc_resume(const struct dc *dc)
1581 {
1582         struct core_dc *core_dc = DC_TO_CORE(dc);
1583
1584         uint32_t i;
1585
1586         for (i = 0; i < core_dc->link_count; i++)
1587                 core_link_resume(core_dc->links[i]);
1588 }
1589
1590 bool dc_read_aux_dpcd(
1591                 struct dc *dc,
1592                 uint32_t link_index,
1593                 uint32_t address,
1594                 uint8_t *data,
1595                 uint32_t size)
1596 {
1597         struct core_dc *core_dc = DC_TO_CORE(dc);
1598
1599         struct core_link *link = core_dc->links[link_index];
1600         enum ddc_result r = dal_ddc_service_read_dpcd_data(
1601                         link->public.ddc,
1602                         false,
1603                         I2C_MOT_UNDEF,
1604                         address,
1605                         data,
1606                         size);
1607         return r == DDC_RESULT_SUCESSFULL;
1608 }
1609
1610 bool dc_write_aux_dpcd(
1611                 struct dc *dc,
1612                 uint32_t link_index,
1613                 uint32_t address,
1614                 const uint8_t *data,
1615                 uint32_t size)
1616 {
1617         struct core_dc *core_dc = DC_TO_CORE(dc);
1618         struct core_link *link = core_dc->links[link_index];
1619
1620         enum ddc_result r = dal_ddc_service_write_dpcd_data(
1621                         link->public.ddc,
1622                         false,
1623                         I2C_MOT_UNDEF,
1624                         address,
1625                         data,
1626                         size);
1627         return r == DDC_RESULT_SUCESSFULL;
1628 }
1629
1630 bool dc_read_aux_i2c(
1631                 struct dc *dc,
1632                 uint32_t link_index,
1633                 enum i2c_mot_mode mot,
1634                 uint32_t address,
1635                 uint8_t *data,
1636                 uint32_t size)
1637 {
1638         struct core_dc *core_dc = DC_TO_CORE(dc);
1639
1640                 struct core_link *link = core_dc->links[link_index];
1641                 enum ddc_result r = dal_ddc_service_read_dpcd_data(
1642                         link->public.ddc,
1643                         true,
1644                         mot,
1645                         address,
1646                         data,
1647                         size);
1648                 return r == DDC_RESULT_SUCESSFULL;
1649 }
1650
1651 bool dc_write_aux_i2c(
1652                 struct dc *dc,
1653                 uint32_t link_index,
1654                 enum i2c_mot_mode mot,
1655                 uint32_t address,
1656                 const uint8_t *data,
1657                 uint32_t size)
1658 {
1659         struct core_dc *core_dc = DC_TO_CORE(dc);
1660         struct core_link *link = core_dc->links[link_index];
1661
1662         enum ddc_result r = dal_ddc_service_write_dpcd_data(
1663                         link->public.ddc,
1664                         true,
1665                         mot,
1666                         address,
1667                         data,
1668                         size);
1669         return r == DDC_RESULT_SUCESSFULL;
1670 }
1671
1672 bool dc_query_ddc_data(
1673                 struct dc *dc,
1674                 uint32_t link_index,
1675                 uint32_t address,
1676                 uint8_t *write_buf,
1677                 uint32_t write_size,
1678                 uint8_t *read_buf,
1679                 uint32_t read_size) {
1680
1681         struct core_dc *core_dc = DC_TO_CORE(dc);
1682
1683         struct core_link *link = core_dc->links[link_index];
1684
1685         bool result = dal_ddc_service_query_ddc_data(
1686                         link->public.ddc,
1687                         address,
1688                         write_buf,
1689                         write_size,
1690                         read_buf,
1691                         read_size);
1692
1693         return result;
1694 }
1695
1696 bool dc_submit_i2c(
1697                 struct dc *dc,
1698                 uint32_t link_index,
1699                 struct i2c_command *cmd)
1700 {
1701         struct core_dc *core_dc = DC_TO_CORE(dc);
1702
1703         struct core_link *link = core_dc->links[link_index];
1704         struct ddc_service *ddc = link->public.ddc;
1705
1706         return dal_i2caux_submit_i2c_command(
1707                 ddc->ctx->i2caux,
1708                 ddc->ddc_pin,
1709                 cmd);
1710 }
1711
1712 static bool link_add_remote_sink_helper(struct core_link *core_link, struct dc_sink *sink)
1713 {
1714         struct dc_link *dc_link = &core_link->public;
1715
1716         if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
1717                 BREAK_TO_DEBUGGER();
1718                 return false;
1719         }
1720
1721         dc_sink_retain(sink);
1722
1723         dc_link->remote_sinks[dc_link->sink_count] = sink;
1724         dc_link->sink_count++;
1725
1726         return true;
1727 }
1728
1729 struct dc_sink *dc_link_add_remote_sink(
1730                 const struct dc_link *link,
1731                 const uint8_t *edid,
1732                 int len,
1733                 struct dc_sink_init_data *init_data)
1734 {
1735         struct dc_sink *dc_sink;
1736         enum dc_edid_status edid_status;
1737         struct core_link *core_link = DC_LINK_TO_LINK(link);
1738
1739         if (len > MAX_EDID_BUFFER_SIZE) {
1740                 dm_error("Max EDID buffer size breached!\n");
1741                 return NULL;
1742         }
1743
1744         if (!init_data) {
1745                 BREAK_TO_DEBUGGER();
1746                 return NULL;
1747         }
1748
1749         if (!init_data->link) {
1750                 BREAK_TO_DEBUGGER();
1751                 return NULL;
1752         }
1753
1754         dc_sink = dc_sink_create(init_data);
1755
1756         if (!dc_sink)
1757                 return NULL;
1758
1759         memmove(dc_sink->dc_edid.raw_edid, edid, len);
1760         dc_sink->dc_edid.length = len;
1761
1762         if (!link_add_remote_sink_helper(
1763                         core_link,
1764                         dc_sink))
1765                 goto fail_add_sink;
1766
1767         edid_status = dm_helpers_parse_edid_caps(
1768                         core_link->ctx,
1769                         &dc_sink->dc_edid,
1770                         &dc_sink->edid_caps);
1771
1772         if (edid_status != EDID_OK)
1773                 goto fail;
1774
1775         return dc_sink;
1776 fail:
1777         dc_link_remove_remote_sink(link, dc_sink);
1778 fail_add_sink:
1779         dc_sink_release(dc_sink);
1780         return NULL;
1781 }
1782
1783 void dc_link_set_sink(const struct dc_link *link, struct dc_sink *sink)
1784 {
1785         struct core_link *core_link = DC_LINK_TO_LINK(link);
1786         struct dc_link *dc_link = &core_link->public;
1787
1788         dc_link->local_sink = sink;
1789
1790         if (sink == NULL) {
1791                 dc_link->type = dc_connection_none;
1792         } else {
1793                 dc_link->type = dc_connection_single;
1794         }
1795 }
1796
1797 void dc_link_remove_remote_sink(const struct dc_link *link, const struct dc_sink *sink)
1798 {
1799         int i;
1800         struct core_link *core_link = DC_LINK_TO_LINK(link);
1801         struct dc_link *dc_link = &core_link->public;
1802
1803         if (!link->sink_count) {
1804                 BREAK_TO_DEBUGGER();
1805                 return;
1806         }
1807
1808         for (i = 0; i < dc_link->sink_count; i++) {
1809                 if (dc_link->remote_sinks[i] == sink) {
1810                         dc_sink_release(sink);
1811                         dc_link->remote_sinks[i] = NULL;
1812
1813                         /* shrink array to remove empty place */
1814                         while (i < dc_link->sink_count - 1) {
1815                                 dc_link->remote_sinks[i] = dc_link->remote_sinks[i+1];
1816                                 i++;
1817                         }
1818                         dc_link->remote_sinks[i] = NULL;
1819                         dc_link->sink_count--;
1820                         return;
1821                 }
1822         }
1823 }
1824
1825 bool dc_init_dchub(struct dc *dc, struct dchub_init_data *dh_data)
1826 {
1827         int i;
1828         struct core_dc *core_dc = DC_TO_CORE(dc);
1829         struct mem_input *mi = NULL;
1830
1831         for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
1832                 if (core_dc->res_pool->mis[i] != NULL) {
1833                         mi = core_dc->res_pool->mis[i];
1834                         break;
1835                 }
1836         }
1837         if (mi == NULL) {
1838                 dm_error("no mem_input!\n");
1839                 return false;
1840         }
1841
1842         if (mi->funcs->mem_input_update_dchub)
1843                 mi->funcs->mem_input_update_dchub(mi, dh_data);
1844         else
1845                 ASSERT(mi->funcs->mem_input_update_dchub);
1846
1847
1848         return true;
1849
1850 }
1851