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