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