]> Git Repo - J-linux.git/blob - drivers/gpu/drm/amd/display/dc/core/dc.c
Merge tag 'drm-intel-gt-next-2022-11-03' of git://anongit.freedesktop.org/drm/drm...
[J-linux.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 #include "dce/dce_hwseq.h"
33
34 #include "resource.h"
35
36 #include "clk_mgr.h"
37 #include "clock_source.h"
38 #include "dc_bios_types.h"
39
40 #include "bios_parser_interface.h"
41 #include "bios/bios_parser_helper.h"
42 #include "include/irq_service_interface.h"
43 #include "transform.h"
44 #include "dmcu.h"
45 #include "dpp.h"
46 #include "timing_generator.h"
47 #include "abm.h"
48 #include "virtual/virtual_link_encoder.h"
49 #include "hubp.h"
50
51 #include "link_hwss.h"
52 #include "link_encoder.h"
53 #include "link_enc_cfg.h"
54
55 #include "dc_link.h"
56 #include "dc_link_ddc.h"
57 #include "dm_helpers.h"
58 #include "mem_input.h"
59
60 #include "dc_link_dp.h"
61 #include "dc_dmub_srv.h"
62
63 #include "dsc.h"
64
65 #include "vm_helper.h"
66
67 #include "dce/dce_i2c.h"
68
69 #include "dmub/dmub_srv.h"
70
71 #include "i2caux_interface.h"
72
73 #include "dce/dmub_psr.h"
74
75 #include "dce/dmub_hw_lock_mgr.h"
76
77 #include "dc_trace.h"
78
79 #include "dce/dmub_outbox.h"
80
81 #define CTX \
82         dc->ctx
83
84 #define DC_LOGGER \
85         dc->ctx->logger
86
87 static const char DC_BUILD_ID[] = "production-build";
88
89 /**
90  * DOC: Overview
91  *
92  * DC is the OS-agnostic component of the amdgpu DC driver.
93  *
94  * DC maintains and validates a set of structs representing the state of the
95  * driver and writes that state to AMD hardware
96  *
97  * Main DC HW structs:
98  *
99  * struct dc - The central struct.  One per driver.  Created on driver load,
100  * destroyed on driver unload.
101  *
102  * struct dc_context - One per driver.
103  * Used as a backpointer by most other structs in dc.
104  *
105  * struct dc_link - One per connector (the physical DP, HDMI, miniDP, or eDP
106  * plugpoints).  Created on driver load, destroyed on driver unload.
107  *
108  * struct dc_sink - One per display.  Created on boot or hotplug.
109  * Destroyed on shutdown or hotunplug.  A dc_link can have a local sink
110  * (the display directly attached).  It may also have one or more remote
111  * sinks (in the Multi-Stream Transport case)
112  *
113  * struct resource_pool - One per driver.  Represents the hw blocks not in the
114  * main pipeline.  Not directly accessible by dm.
115  *
116  * Main dc state structs:
117  *
118  * These structs can be created and destroyed as needed.  There is a full set of
119  * these structs in dc->current_state representing the currently programmed state.
120  *
121  * struct dc_state - The global DC state to track global state information,
122  * such as bandwidth values.
123  *
124  * struct dc_stream_state - Represents the hw configuration for the pipeline from
125  * a framebuffer to a display.  Maps one-to-one with dc_sink.
126  *
127  * struct dc_plane_state - Represents a framebuffer.  Each stream has at least one,
128  * and may have more in the Multi-Plane Overlay case.
129  *
130  * struct resource_context - Represents the programmable state of everything in
131  * the resource_pool.  Not directly accessible by dm.
132  *
133  * struct pipe_ctx - A member of struct resource_context.  Represents the
134  * internal hardware pipeline components.  Each dc_plane_state has either
135  * one or two (in the pipe-split case).
136  */
137
138 /*******************************************************************************
139  * Private functions
140  ******************************************************************************/
141
142 static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
143 {
144         if (new > *original)
145                 *original = new;
146 }
147
148 static void destroy_links(struct dc *dc)
149 {
150         uint32_t i;
151
152         for (i = 0; i < dc->link_count; i++) {
153                 if (NULL != dc->links[i])
154                         link_destroy(&dc->links[i]);
155         }
156 }
157
158 static uint32_t get_num_of_internal_disp(struct dc_link **links, uint32_t num_links)
159 {
160         int i;
161         uint32_t count = 0;
162
163         for (i = 0; i < num_links; i++) {
164                 if (links[i]->connector_signal == SIGNAL_TYPE_EDP ||
165                                 links[i]->is_internal_display)
166                         count++;
167         }
168
169         return count;
170 }
171
172 static int get_seamless_boot_stream_count(struct dc_state *ctx)
173 {
174         uint8_t i;
175         uint8_t seamless_boot_stream_count = 0;
176
177         for (i = 0; i < ctx->stream_count; i++)
178                 if (ctx->streams[i]->apply_seamless_boot_optimization)
179                         seamless_boot_stream_count++;
180
181         return seamless_boot_stream_count;
182 }
183
184 static bool create_links(
185                 struct dc *dc,
186                 uint32_t num_virtual_links)
187 {
188         int i;
189         int connectors_num;
190         struct dc_bios *bios = dc->ctx->dc_bios;
191
192         dc->link_count = 0;
193
194         connectors_num = bios->funcs->get_connectors_number(bios);
195
196         DC_LOG_DC("BIOS object table - number of connectors: %d", connectors_num);
197
198         if (connectors_num > ENUM_ID_COUNT) {
199                 dm_error(
200                         "DC: Number of connectors %d exceeds maximum of %d!\n",
201                         connectors_num,
202                         ENUM_ID_COUNT);
203                 return false;
204         }
205
206         dm_output_to_console(
207                 "DC: %s: connectors_num: physical:%d, virtual:%d\n",
208                 __func__,
209                 connectors_num,
210                 num_virtual_links);
211
212         for (i = 0; i < connectors_num; i++) {
213                 struct link_init_data link_init_params = {0};
214                 struct dc_link *link;
215
216                 DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count);
217
218                 link_init_params.ctx = dc->ctx;
219                 /* next BIOS object table connector */
220                 link_init_params.connector_index = i;
221                 link_init_params.link_index = dc->link_count;
222                 link_init_params.dc = dc;
223                 link = link_create(&link_init_params);
224
225                 if (link) {
226                         dc->links[dc->link_count] = link;
227                         link->dc = dc;
228                         ++dc->link_count;
229                 }
230         }
231
232         DC_LOG_DC("BIOS object table - end");
233
234         /* Create a link for each usb4 dpia port */
235         for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) {
236                 struct link_init_data link_init_params = {0};
237                 struct dc_link *link;
238
239                 link_init_params.ctx = dc->ctx;
240                 link_init_params.connector_index = i;
241                 link_init_params.link_index = dc->link_count;
242                 link_init_params.dc = dc;
243                 link_init_params.is_dpia_link = true;
244
245                 link = link_create(&link_init_params);
246                 if (link) {
247                         dc->links[dc->link_count] = link;
248                         link->dc = dc;
249                         ++dc->link_count;
250                 }
251         }
252
253         for (i = 0; i < num_virtual_links; i++) {
254                 struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
255                 struct encoder_init_data enc_init = {0};
256
257                 if (link == NULL) {
258                         BREAK_TO_DEBUGGER();
259                         goto failed_alloc;
260                 }
261
262                 link->link_index = dc->link_count;
263                 dc->links[dc->link_count] = link;
264                 dc->link_count++;
265
266                 link->ctx = dc->ctx;
267                 link->dc = dc;
268                 link->connector_signal = SIGNAL_TYPE_VIRTUAL;
269                 link->link_id.type = OBJECT_TYPE_CONNECTOR;
270                 link->link_id.id = CONNECTOR_ID_VIRTUAL;
271                 link->link_id.enum_id = ENUM_ID_1;
272                 link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL);
273
274                 if (!link->link_enc) {
275                         BREAK_TO_DEBUGGER();
276                         goto failed_alloc;
277                 }
278
279                 link->link_status.dpcd_caps = &link->dpcd_caps;
280
281                 enc_init.ctx = dc->ctx;
282                 enc_init.channel = CHANNEL_ID_UNKNOWN;
283                 enc_init.hpd_source = HPD_SOURCEID_UNKNOWN;
284                 enc_init.transmitter = TRANSMITTER_UNKNOWN;
285                 enc_init.connector = link->link_id;
286                 enc_init.encoder.type = OBJECT_TYPE_ENCODER;
287                 enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL;
288                 enc_init.encoder.enum_id = ENUM_ID_1;
289                 virtual_link_encoder_construct(link->link_enc, &enc_init);
290         }
291
292         dc->caps.num_of_internal_disp = get_num_of_internal_disp(dc->links, dc->link_count);
293
294         return true;
295
296 failed_alloc:
297         return false;
298 }
299
300 /* Create additional DIG link encoder objects if fewer than the platform
301  * supports were created during link construction. This can happen if the
302  * number of physical connectors is less than the number of DIGs.
303  */
304 static bool create_link_encoders(struct dc *dc)
305 {
306         bool res = true;
307         unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia;
308         unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc;
309         int i;
310
311         /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG
312          * link encoders and physical display endpoints and does not require
313          * additional link encoder objects.
314          */
315         if (num_usb4_dpia == 0)
316                 return res;
317
318         /* Create as many link encoder objects as the platform supports. DPIA
319          * endpoints can be programmably mapped to any DIG.
320          */
321         if (num_dig_link_enc > dc->res_pool->dig_link_enc_count) {
322                 for (i = 0; i < num_dig_link_enc; i++) {
323                         struct link_encoder *link_enc = dc->res_pool->link_encoders[i];
324
325                         if (!link_enc && dc->res_pool->funcs->link_enc_create_minimal) {
326                                 link_enc = dc->res_pool->funcs->link_enc_create_minimal(dc->ctx,
327                                                 (enum engine_id)(ENGINE_ID_DIGA + i));
328                                 if (link_enc) {
329                                         dc->res_pool->link_encoders[i] = link_enc;
330                                         dc->res_pool->dig_link_enc_count++;
331                                 } else {
332                                         res = false;
333                                 }
334                         }
335                 }
336         }
337
338         return res;
339 }
340
341 /* Destroy any additional DIG link encoder objects created by
342  * create_link_encoders().
343  * NB: Must only be called after destroy_links().
344  */
345 static void destroy_link_encoders(struct dc *dc)
346 {
347         unsigned int num_usb4_dpia;
348         unsigned int num_dig_link_enc;
349         int i;
350
351         if (!dc->res_pool)
352                 return;
353
354         num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia;
355         num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc;
356
357         /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG
358          * link encoders and physical display endpoints and does not require
359          * additional link encoder objects.
360          */
361         if (num_usb4_dpia == 0)
362                 return;
363
364         for (i = 0; i < num_dig_link_enc; i++) {
365                 struct link_encoder *link_enc = dc->res_pool->link_encoders[i];
366
367                 if (link_enc) {
368                         link_enc->funcs->destroy(&link_enc);
369                         dc->res_pool->link_encoders[i] = NULL;
370                         dc->res_pool->dig_link_enc_count--;
371                 }
372         }
373 }
374
375 static struct dc_perf_trace *dc_perf_trace_create(void)
376 {
377         return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL);
378 }
379
380 static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace)
381 {
382         kfree(*perf_trace);
383         *perf_trace = NULL;
384 }
385
386 /**
387  *  dc_stream_adjust_vmin_vmax:
388  *
389  *  Looks up the pipe context of dc_stream_state and updates the
390  *  vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
391  *  Rate, which is a power-saving feature that targets reducing panel
392  *  refresh rate while the screen is static
393  *
394  *  @dc:     dc reference
395  *  @stream: Initial dc stream state
396  *  @adjust: Updated parameters for vertical_total_min and vertical_total_max
397  */
398 bool dc_stream_adjust_vmin_vmax(struct dc *dc,
399                 struct dc_stream_state *stream,
400                 struct dc_crtc_timing_adjust *adjust)
401 {
402         int i;
403
404         if (memcmp(adjust, &stream->adjust, sizeof(struct dc_crtc_timing_adjust)) == 0)
405                 return true;
406
407         stream->adjust.v_total_max = adjust->v_total_max;
408         stream->adjust.v_total_mid = adjust->v_total_mid;
409         stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
410         stream->adjust.v_total_min = adjust->v_total_min;
411
412         for (i = 0; i < MAX_PIPES; i++) {
413                 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
414
415                 if (pipe->stream == stream && pipe->stream_res.tg) {
416                         dc->hwss.set_drr(&pipe,
417                                         1,
418                                         *adjust);
419
420                         return true;
421                 }
422         }
423         return false;
424 }
425
426 /**
427  *****************************************************************************
428  *  Function: dc_stream_get_last_vrr_vtotal
429  *
430  *  @brief
431  *     Looks up the pipe context of dc_stream_state and gets the
432  *     last VTOTAL used by DRR (Dynamic Refresh Rate)
433  *
434  *  @param [in] dc: dc reference
435  *  @param [in] stream: Initial dc stream state
436  *  @param [in] adjust: Updated parameters for vertical_total_min and
437  *  vertical_total_max
438  *****************************************************************************
439  */
440 bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
441                 struct dc_stream_state *stream,
442                 uint32_t *refresh_rate)
443 {
444         bool status = false;
445
446         int i = 0;
447
448         for (i = 0; i < MAX_PIPES; i++) {
449                 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
450
451                 if (pipe->stream == stream && pipe->stream_res.tg) {
452                         /* Only execute if a function pointer has been defined for
453                          * the DC version in question
454                          */
455                         if (pipe->stream_res.tg->funcs->get_last_used_drr_vtotal) {
456                                 pipe->stream_res.tg->funcs->get_last_used_drr_vtotal(pipe->stream_res.tg, refresh_rate);
457
458                                 status = true;
459
460                                 break;
461                         }
462                 }
463         }
464
465         return status;
466 }
467
468 bool dc_stream_get_crtc_position(struct dc *dc,
469                 struct dc_stream_state **streams, int num_streams,
470                 unsigned int *v_pos, unsigned int *nom_v_pos)
471 {
472         /* TODO: Support multiple streams */
473         const struct dc_stream_state *stream = streams[0];
474         int i;
475         bool ret = false;
476         struct crtc_position position;
477
478         for (i = 0; i < MAX_PIPES; i++) {
479                 struct pipe_ctx *pipe =
480                                 &dc->current_state->res_ctx.pipe_ctx[i];
481
482                 if (pipe->stream == stream && pipe->stream_res.stream_enc) {
483                         dc->hwss.get_position(&pipe, 1, &position);
484
485                         *v_pos = position.vertical_count;
486                         *nom_v_pos = position.nominal_vcount;
487                         ret = true;
488                 }
489         }
490         return ret;
491 }
492
493 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
494 bool dc_stream_forward_dmcu_crc_window(struct dc *dc, struct dc_stream_state *stream,
495                              struct crc_params *crc_window)
496 {
497         int i;
498         struct dmcu *dmcu = dc->res_pool->dmcu;
499         struct pipe_ctx *pipe;
500         struct crc_region tmp_win, *crc_win;
501         struct otg_phy_mux mapping_tmp, *mux_mapping;
502
503         /*crc window can't be null*/
504         if (!crc_window)
505                 return false;
506
507         if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) {
508                 crc_win = &tmp_win;
509                 mux_mapping = &mapping_tmp;
510                 /*set crc window*/
511                 tmp_win.x_start = crc_window->windowa_x_start;
512                 tmp_win.y_start = crc_window->windowa_y_start;
513                 tmp_win.x_end = crc_window->windowa_x_end;
514                 tmp_win.y_end = crc_window->windowa_y_end;
515
516                 for (i = 0; i < MAX_PIPES; i++) {
517                         pipe = &dc->current_state->res_ctx.pipe_ctx[i];
518                         if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
519                                 break;
520                 }
521
522                 /* Stream not found */
523                 if (i == MAX_PIPES)
524                         return false;
525
526
527                 /*set mux routing info*/
528                 mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst;
529                 mapping_tmp.otg_output_num = pipe->stream_res.tg->inst;
530
531                 dmcu->funcs->forward_crc_window(dmcu, crc_win, mux_mapping);
532         } else {
533                 DC_LOG_DC("dmcu is not initialized");
534                 return false;
535         }
536
537         return true;
538 }
539
540 bool dc_stream_stop_dmcu_crc_win_update(struct dc *dc, struct dc_stream_state *stream)
541 {
542         int i;
543         struct dmcu *dmcu = dc->res_pool->dmcu;
544         struct pipe_ctx *pipe;
545         struct otg_phy_mux mapping_tmp, *mux_mapping;
546
547         if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) {
548                 mux_mapping = &mapping_tmp;
549
550                 for (i = 0; i < MAX_PIPES; i++) {
551                         pipe = &dc->current_state->res_ctx.pipe_ctx[i];
552                         if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
553                                 break;
554                 }
555
556                 /* Stream not found */
557                 if (i == MAX_PIPES)
558                         return false;
559
560
561                 /*set mux routing info*/
562                 mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst;
563                 mapping_tmp.otg_output_num = pipe->stream_res.tg->inst;
564
565                 dmcu->funcs->stop_crc_win_update(dmcu, mux_mapping);
566         } else {
567                 DC_LOG_DC("dmcu is not initialized");
568                 return false;
569         }
570
571         return true;
572 }
573 #endif
574
575 /**
576  * dc_stream_configure_crc() - Configure CRC capture for the given stream.
577  * @dc: DC Object
578  * @stream: The stream to configure CRC on.
579  * @enable: Enable CRC if true, disable otherwise.
580  * @crc_window: CRC window (x/y start/end) information
581  * @continuous: Capture CRC on every frame if true. Otherwise, only capture
582  *              once.
583  *
584  * By default, only CRC0 is configured, and the entire frame is used to
585  * calculate the crc.
586  */
587 bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
588                              struct crc_params *crc_window, bool enable, bool continuous)
589 {
590         int i;
591         struct pipe_ctx *pipe;
592         struct crc_params param;
593         struct timing_generator *tg;
594
595         for (i = 0; i < MAX_PIPES; i++) {
596                 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
597                 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
598                         break;
599         }
600         /* Stream not found */
601         if (i == MAX_PIPES)
602                 return false;
603
604         /* By default, capture the full frame */
605         param.windowa_x_start = 0;
606         param.windowa_y_start = 0;
607         param.windowa_x_end = pipe->stream->timing.h_addressable;
608         param.windowa_y_end = pipe->stream->timing.v_addressable;
609         param.windowb_x_start = 0;
610         param.windowb_y_start = 0;
611         param.windowb_x_end = pipe->stream->timing.h_addressable;
612         param.windowb_y_end = pipe->stream->timing.v_addressable;
613
614         if (crc_window) {
615                 param.windowa_x_start = crc_window->windowa_x_start;
616                 param.windowa_y_start = crc_window->windowa_y_start;
617                 param.windowa_x_end = crc_window->windowa_x_end;
618                 param.windowa_y_end = crc_window->windowa_y_end;
619                 param.windowb_x_start = crc_window->windowb_x_start;
620                 param.windowb_y_start = crc_window->windowb_y_start;
621                 param.windowb_x_end = crc_window->windowb_x_end;
622                 param.windowb_y_end = crc_window->windowb_y_end;
623         }
624
625         param.dsc_mode = pipe->stream->timing.flags.DSC ? 1:0;
626         param.odm_mode = pipe->next_odm_pipe ? 1:0;
627
628         /* Default to the union of both windows */
629         param.selection = UNION_WINDOW_A_B;
630         param.continuous_mode = continuous;
631         param.enable = enable;
632
633         tg = pipe->stream_res.tg;
634
635         /* Only call if supported */
636         if (tg->funcs->configure_crc)
637                 return tg->funcs->configure_crc(tg, &param);
638         DC_LOG_WARNING("CRC capture not supported.");
639         return false;
640 }
641
642 /**
643  * dc_stream_get_crc() - Get CRC values for the given stream.
644  *
645  * @dc: DC object.
646  * @stream: The DC stream state of the stream to get CRCs from.
647  * @r_cr: CRC value for the red component.
648  * @g_y:  CRC value for the green component.
649  * @b_cb: CRC value for the blue component.
650  *
651  * dc_stream_configure_crc needs to be called beforehand to enable CRCs.
652  *
653  * Return:
654  * false if stream is not found, or if CRCs are not enabled.
655  */
656 bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
657                        uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
658 {
659         int i;
660         struct pipe_ctx *pipe;
661         struct timing_generator *tg;
662
663         for (i = 0; i < MAX_PIPES; i++) {
664                 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
665                 if (pipe->stream == stream)
666                         break;
667         }
668         /* Stream not found */
669         if (i == MAX_PIPES)
670                 return false;
671
672         tg = pipe->stream_res.tg;
673
674         if (tg->funcs->get_crc)
675                 return tg->funcs->get_crc(tg, r_cr, g_y, b_cb);
676         DC_LOG_WARNING("CRC capture not supported.");
677         return false;
678 }
679
680 void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
681                 enum dc_dynamic_expansion option)
682 {
683         /* OPP FMT dyn expansion updates*/
684         int i;
685         struct pipe_ctx *pipe_ctx;
686
687         for (i = 0; i < MAX_PIPES; i++) {
688                 if (dc->current_state->res_ctx.pipe_ctx[i].stream
689                                 == stream) {
690                         pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
691                         pipe_ctx->stream_res.opp->dyn_expansion = option;
692                         pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
693                                         pipe_ctx->stream_res.opp,
694                                         COLOR_SPACE_YCBCR601,
695                                         stream->timing.display_color_depth,
696                                         stream->signal);
697                 }
698         }
699 }
700
701 void dc_stream_set_dither_option(struct dc_stream_state *stream,
702                 enum dc_dither_option option)
703 {
704         struct bit_depth_reduction_params params;
705         struct dc_link *link = stream->link;
706         struct pipe_ctx *pipes = NULL;
707         int i;
708
709         for (i = 0; i < MAX_PIPES; i++) {
710                 if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
711                                 stream) {
712                         pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
713                         break;
714                 }
715         }
716
717         if (!pipes)
718                 return;
719         if (option > DITHER_OPTION_MAX)
720                 return;
721
722         stream->dither_option = option;
723
724         memset(&params, 0, sizeof(params));
725         resource_build_bit_depth_reduction_params(stream, &params);
726         stream->bit_depth_params = params;
727
728         if (pipes->plane_res.xfm &&
729             pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) {
730                 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
731                         pipes->plane_res.xfm,
732                         pipes->plane_res.scl_data.lb_params.depth,
733                         &stream->bit_depth_params);
734         }
735
736         pipes->stream_res.opp->funcs->
737                 opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
738 }
739
740 bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
741 {
742         int i;
743         bool ret = false;
744         struct pipe_ctx *pipes;
745
746         for (i = 0; i < MAX_PIPES; i++) {
747                 if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
748                         pipes = &dc->current_state->res_ctx.pipe_ctx[i];
749                         dc->hwss.program_gamut_remap(pipes);
750                         ret = true;
751                 }
752         }
753
754         return ret;
755 }
756
757 bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
758 {
759         int i;
760         bool ret = false;
761         struct pipe_ctx *pipes;
762
763         for (i = 0; i < MAX_PIPES; i++) {
764                 if (dc->current_state->res_ctx.pipe_ctx[i].stream
765                                 == stream) {
766
767                         pipes = &dc->current_state->res_ctx.pipe_ctx[i];
768                         dc->hwss.program_output_csc(dc,
769                                         pipes,
770                                         stream->output_color_space,
771                                         stream->csc_color_matrix.matrix,
772                                         pipes->stream_res.opp->inst);
773                         ret = true;
774                 }
775         }
776
777         return ret;
778 }
779
780 void dc_stream_set_static_screen_params(struct dc *dc,
781                 struct dc_stream_state **streams,
782                 int num_streams,
783                 const struct dc_static_screen_params *params)
784 {
785         int i, j;
786         struct pipe_ctx *pipes_affected[MAX_PIPES];
787         int num_pipes_affected = 0;
788
789         for (i = 0; i < num_streams; i++) {
790                 struct dc_stream_state *stream = streams[i];
791
792                 for (j = 0; j < MAX_PIPES; j++) {
793                         if (dc->current_state->res_ctx.pipe_ctx[j].stream
794                                         == stream) {
795                                 pipes_affected[num_pipes_affected++] =
796                                                 &dc->current_state->res_ctx.pipe_ctx[j];
797                         }
798                 }
799         }
800
801         dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, params);
802 }
803
804 static void dc_destruct(struct dc *dc)
805 {
806         // reset link encoder assignment table on destruct
807         if (dc->res_pool && dc->res_pool->funcs->link_encs_assign)
808                 link_enc_cfg_init(dc, dc->current_state);
809
810         if (dc->current_state) {
811                 dc_release_state(dc->current_state);
812                 dc->current_state = NULL;
813         }
814
815         destroy_links(dc);
816
817         destroy_link_encoders(dc);
818
819         if (dc->clk_mgr) {
820                 dc_destroy_clk_mgr(dc->clk_mgr);
821                 dc->clk_mgr = NULL;
822         }
823
824         dc_destroy_resource_pool(dc);
825
826         if (dc->ctx->gpio_service)
827                 dal_gpio_service_destroy(&dc->ctx->gpio_service);
828
829         if (dc->ctx->created_bios)
830                 dal_bios_parser_destroy(&dc->ctx->dc_bios);
831
832         dc_perf_trace_destroy(&dc->ctx->perf_trace);
833
834         kfree(dc->ctx);
835         dc->ctx = NULL;
836
837         kfree(dc->bw_vbios);
838         dc->bw_vbios = NULL;
839
840         kfree(dc->bw_dceip);
841         dc->bw_dceip = NULL;
842
843         kfree(dc->dcn_soc);
844         dc->dcn_soc = NULL;
845
846         kfree(dc->dcn_ip);
847         dc->dcn_ip = NULL;
848
849         kfree(dc->vm_helper);
850         dc->vm_helper = NULL;
851
852 }
853
854 static bool dc_construct_ctx(struct dc *dc,
855                 const struct dc_init_data *init_params)
856 {
857         struct dc_context *dc_ctx;
858         enum dce_version dc_version = DCE_VERSION_UNKNOWN;
859
860         dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL);
861         if (!dc_ctx)
862                 return false;
863
864         dc_ctx->cgs_device = init_params->cgs_device;
865         dc_ctx->driver_context = init_params->driver;
866         dc_ctx->dc = dc;
867         dc_ctx->asic_id = init_params->asic_id;
868         dc_ctx->dc_sink_id_count = 0;
869         dc_ctx->dc_stream_id_count = 0;
870         dc_ctx->dce_environment = init_params->dce_environment;
871         dc_ctx->dcn_reg_offsets = init_params->dcn_reg_offsets;
872         dc_ctx->nbio_reg_offsets = init_params->nbio_reg_offsets;
873
874         /* Create logger */
875
876         dc_version = resource_parse_asic_id(init_params->asic_id);
877         dc_ctx->dce_version = dc_version;
878
879         dc_ctx->perf_trace = dc_perf_trace_create();
880         if (!dc_ctx->perf_trace) {
881                 ASSERT_CRITICAL(false);
882                 return false;
883         }
884
885         dc->ctx = dc_ctx;
886
887         return true;
888 }
889
890 static bool dc_construct(struct dc *dc,
891                 const struct dc_init_data *init_params)
892 {
893         struct dc_context *dc_ctx;
894         struct bw_calcs_dceip *dc_dceip;
895         struct bw_calcs_vbios *dc_vbios;
896         struct dcn_soc_bounding_box *dcn_soc;
897         struct dcn_ip_params *dcn_ip;
898
899         dc->config = init_params->flags;
900
901         // Allocate memory for the vm_helper
902         dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
903         if (!dc->vm_helper) {
904                 dm_error("%s: failed to create dc->vm_helper\n", __func__);
905                 goto fail;
906         }
907
908         memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
909
910         dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL);
911         if (!dc_dceip) {
912                 dm_error("%s: failed to create dceip\n", __func__);
913                 goto fail;
914         }
915
916         dc->bw_dceip = dc_dceip;
917
918         dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL);
919         if (!dc_vbios) {
920                 dm_error("%s: failed to create vbios\n", __func__);
921                 goto fail;
922         }
923
924         dc->bw_vbios = dc_vbios;
925         dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL);
926         if (!dcn_soc) {
927                 dm_error("%s: failed to create dcn_soc\n", __func__);
928                 goto fail;
929         }
930
931         dc->dcn_soc = dcn_soc;
932
933         dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL);
934         if (!dcn_ip) {
935                 dm_error("%s: failed to create dcn_ip\n", __func__);
936                 goto fail;
937         }
938
939         dc->dcn_ip = dcn_ip;
940
941         if (!dc_construct_ctx(dc, init_params)) {
942                 dm_error("%s: failed to create ctx\n", __func__);
943                 goto fail;
944         }
945
946         dc_ctx = dc->ctx;
947
948         /* Resource should construct all asic specific resources.
949          * This should be the only place where we need to parse the asic id
950          */
951         if (init_params->vbios_override)
952                 dc_ctx->dc_bios = init_params->vbios_override;
953         else {
954                 /* Create BIOS parser */
955                 struct bp_init_data bp_init_data;
956
957                 bp_init_data.ctx = dc_ctx;
958                 bp_init_data.bios = init_params->asic_id.atombios_base_address;
959
960                 dc_ctx->dc_bios = dal_bios_parser_create(
961                                 &bp_init_data, dc_ctx->dce_version);
962
963                 if (!dc_ctx->dc_bios) {
964                         ASSERT_CRITICAL(false);
965                         goto fail;
966                 }
967
968                 dc_ctx->created_bios = true;
969         }
970
971         dc->vendor_signature = init_params->vendor_signature;
972
973         /* Create GPIO service */
974         dc_ctx->gpio_service = dal_gpio_service_create(
975                         dc_ctx->dce_version,
976                         dc_ctx->dce_environment,
977                         dc_ctx);
978
979         if (!dc_ctx->gpio_service) {
980                 ASSERT_CRITICAL(false);
981                 goto fail;
982         }
983
984         dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version);
985         if (!dc->res_pool)
986                 goto fail;
987
988         /* set i2c speed if not done by the respective dcnxxx__resource.c */
989         if (dc->caps.i2c_speed_in_khz_hdcp == 0)
990                 dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz;
991
992         dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg);
993         if (!dc->clk_mgr)
994                 goto fail;
995 #ifdef CONFIG_DRM_AMD_DC_DCN
996         dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present;
997
998         if (dc->res_pool->funcs->update_bw_bounding_box) {
999                 DC_FP_START();
1000                 dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
1001                 DC_FP_END();
1002         }
1003 #endif
1004
1005         /* Creation of current_state must occur after dc->dml
1006          * is initialized in dc_create_resource_pool because
1007          * on creation it copies the contents of dc->dml
1008          */
1009
1010         dc->current_state = dc_create_state(dc);
1011
1012         if (!dc->current_state) {
1013                 dm_error("%s: failed to create validate ctx\n", __func__);
1014                 goto fail;
1015         }
1016
1017         if (!create_links(dc, init_params->num_virtual_links))
1018                 goto fail;
1019
1020         /* Create additional DIG link encoder objects if fewer than the platform
1021          * supports were created during link construction.
1022          */
1023         if (!create_link_encoders(dc))
1024                 goto fail;
1025
1026         dc_resource_state_construct(dc, dc->current_state);
1027
1028         return true;
1029
1030 fail:
1031         return false;
1032 }
1033
1034 static void disable_all_writeback_pipes_for_stream(
1035                 const struct dc *dc,
1036                 struct dc_stream_state *stream,
1037                 struct dc_state *context)
1038 {
1039         int i;
1040
1041         for (i = 0; i < stream->num_wb_info; i++)
1042                 stream->writeback_info[i].wb_enabled = false;
1043 }
1044
1045 static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context,
1046                                           struct dc_stream_state *stream, bool lock)
1047 {
1048         int i;
1049
1050         /* Checks if interdependent update function pointer is NULL or not, takes care of DCE110 case */
1051         if (dc->hwss.interdependent_update_lock)
1052                 dc->hwss.interdependent_update_lock(dc, context, lock);
1053         else {
1054                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1055                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1056                         struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
1057
1058                         // Copied conditions that were previously in dce110_apply_ctx_for_surface
1059                         if (stream == pipe_ctx->stream) {
1060                                 if (!pipe_ctx->top_pipe &&
1061                                         (pipe_ctx->plane_state || old_pipe_ctx->plane_state))
1062                                         dc->hwss.pipe_control_lock(dc, pipe_ctx, lock);
1063                         }
1064                 }
1065         }
1066 }
1067
1068 static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
1069 {
1070         int i, j;
1071         struct dc_state *dangling_context = dc_create_state(dc);
1072         struct dc_state *current_ctx;
1073
1074         if (dangling_context == NULL)
1075                 return;
1076
1077         dc_resource_state_copy_construct(dc->current_state, dangling_context);
1078
1079         for (i = 0; i < dc->res_pool->pipe_count; i++) {
1080                 struct dc_stream_state *old_stream =
1081                                 dc->current_state->res_ctx.pipe_ctx[i].stream;
1082                 bool should_disable = true;
1083                 bool pipe_split_change = false;
1084
1085                 if ((context->res_ctx.pipe_ctx[i].top_pipe) &&
1086                         (dc->current_state->res_ctx.pipe_ctx[i].top_pipe))
1087                         pipe_split_change = context->res_ctx.pipe_ctx[i].top_pipe->pipe_idx !=
1088                                 dc->current_state->res_ctx.pipe_ctx[i].top_pipe->pipe_idx;
1089                 else
1090                         pipe_split_change = context->res_ctx.pipe_ctx[i].top_pipe !=
1091                                 dc->current_state->res_ctx.pipe_ctx[i].top_pipe;
1092
1093                 for (j = 0; j < context->stream_count; j++) {
1094                         if (old_stream == context->streams[j]) {
1095                                 should_disable = false;
1096                                 break;
1097                         }
1098                 }
1099                 if (!should_disable && pipe_split_change &&
1100                                 dc->current_state->stream_count != context->stream_count)
1101                         should_disable = true;
1102
1103                 if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe &&
1104                                 !dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe) {
1105                         struct pipe_ctx *old_pipe, *new_pipe;
1106
1107                         old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1108                         new_pipe = &context->res_ctx.pipe_ctx[i];
1109
1110                         if (old_pipe->plane_state && !new_pipe->plane_state)
1111                                 should_disable = true;
1112                 }
1113
1114                 if (should_disable && old_stream) {
1115                         dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
1116                         disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
1117
1118                         if (dc->hwss.apply_ctx_for_surface) {
1119                                 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, true);
1120                                 dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
1121                                 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, false);
1122                                 dc->hwss.post_unlock_program_front_end(dc, dangling_context);
1123                         }
1124                         if (dc->hwss.program_front_end_for_ctx) {
1125                                 dc->hwss.interdependent_update_lock(dc, dc->current_state, true);
1126                                 dc->hwss.program_front_end_for_ctx(dc, dangling_context);
1127                                 dc->hwss.interdependent_update_lock(dc, dc->current_state, false);
1128                                 dc->hwss.post_unlock_program_front_end(dc, dangling_context);
1129                         }
1130                 }
1131         }
1132
1133         current_ctx = dc->current_state;
1134         dc->current_state = dangling_context;
1135         dc_release_state(current_ctx);
1136 }
1137
1138 static void disable_vbios_mode_if_required(
1139                 struct dc *dc,
1140                 struct dc_state *context)
1141 {
1142         unsigned int i, j;
1143
1144         /* check if timing_changed, disable stream*/
1145         for (i = 0; i < dc->res_pool->pipe_count; i++) {
1146                 struct dc_stream_state *stream = NULL;
1147                 struct dc_link *link = NULL;
1148                 struct pipe_ctx *pipe = NULL;
1149
1150                 pipe = &context->res_ctx.pipe_ctx[i];
1151                 stream = pipe->stream;
1152                 if (stream == NULL)
1153                         continue;
1154
1155                 // only looking for first odm pipe
1156                 if (pipe->prev_odm_pipe)
1157                         continue;
1158
1159                 if (stream->link->local_sink &&
1160                         stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1161                         link = stream->link;
1162                 }
1163
1164                 if (link != NULL && link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
1165                         unsigned int enc_inst, tg_inst = 0;
1166                         unsigned int pix_clk_100hz;
1167
1168                         enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
1169                         if (enc_inst != ENGINE_ID_UNKNOWN) {
1170                                 for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
1171                                         if (dc->res_pool->stream_enc[j]->id == enc_inst) {
1172                                                 tg_inst = dc->res_pool->stream_enc[j]->funcs->dig_source_otg(
1173                                                         dc->res_pool->stream_enc[j]);
1174                                                 break;
1175                                         }
1176                                 }
1177
1178                                 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1179                                         dc->res_pool->dp_clock_source,
1180                                         tg_inst, &pix_clk_100hz);
1181
1182                                 if (link->link_status.link_active) {
1183                                         uint32_t requested_pix_clk_100hz =
1184                                                 pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
1185
1186                                         if (pix_clk_100hz != requested_pix_clk_100hz) {
1187                                                 core_link_disable_stream(pipe);
1188                                                 pipe->stream->dpms_off = false;
1189                                         }
1190                                 }
1191                         }
1192                 }
1193         }
1194 }
1195
1196 static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
1197 {
1198         int i;
1199         PERF_TRACE();
1200         for (i = 0; i < MAX_PIPES; i++) {
1201                 int count = 0;
1202                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1203
1204                 if (!pipe->plane_state || pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
1205                         continue;
1206
1207                 /* Timeout 100 ms */
1208                 while (count < 100000) {
1209                         /* Must set to false to start with, due to OR in update function */
1210                         pipe->plane_state->status.is_flip_pending = false;
1211                         dc->hwss.update_pending_status(pipe);
1212                         if (!pipe->plane_state->status.is_flip_pending)
1213                                 break;
1214                         udelay(1);
1215                         count++;
1216                 }
1217                 ASSERT(!pipe->plane_state->status.is_flip_pending);
1218         }
1219         PERF_TRACE();
1220 }
1221
1222 /*******************************************************************************
1223  * Public functions
1224  ******************************************************************************/
1225
1226 struct dc *dc_create(const struct dc_init_data *init_params)
1227 {
1228         struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
1229         unsigned int full_pipe_count;
1230
1231         if (!dc)
1232                 return NULL;
1233
1234         if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) {
1235                 if (!dc_construct_ctx(dc, init_params))
1236                         goto destruct_dc;
1237         } else {
1238                 if (!dc_construct(dc, init_params))
1239                         goto destruct_dc;
1240
1241                 full_pipe_count = dc->res_pool->pipe_count;
1242                 if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE)
1243                         full_pipe_count--;
1244                 dc->caps.max_streams = min(
1245                                 full_pipe_count,
1246                                 dc->res_pool->stream_enc_count);
1247
1248                 dc->caps.max_links = dc->link_count;
1249                 dc->caps.max_audios = dc->res_pool->audio_count;
1250                 dc->caps.linear_pitch_alignment = 64;
1251
1252                 dc->caps.max_dp_protocol_version = DP_VERSION_1_4;
1253
1254                 dc->caps.max_otg_num = dc->res_pool->res_cap->num_timing_generator;
1255
1256                 if (dc->res_pool->dmcu != NULL)
1257                         dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version;
1258         }
1259
1260         dc->dcn_reg_offsets = init_params->dcn_reg_offsets;
1261         dc->nbio_reg_offsets = init_params->nbio_reg_offsets;
1262
1263         /* Populate versioning information */
1264         dc->versions.dc_ver = DC_VER;
1265
1266         dc->build_id = DC_BUILD_ID;
1267
1268         DC_LOG_DC("Display Core initialized\n");
1269
1270
1271
1272         return dc;
1273
1274 destruct_dc:
1275         dc_destruct(dc);
1276         kfree(dc);
1277         return NULL;
1278 }
1279
1280 static void detect_edp_presence(struct dc *dc)
1281 {
1282         struct dc_link *edp_links[MAX_NUM_EDP];
1283         struct dc_link *edp_link = NULL;
1284         enum dc_connection_type type;
1285         int i;
1286         int edp_num;
1287
1288         get_edp_links(dc, edp_links, &edp_num);
1289         if (!edp_num)
1290                 return;
1291
1292         for (i = 0; i < edp_num; i++) {
1293                 edp_link = edp_links[i];
1294                 if (dc->config.edp_not_connected) {
1295                         edp_link->edp_sink_present = false;
1296                 } else {
1297                         dc_link_detect_sink(edp_link, &type);
1298                         edp_link->edp_sink_present = (type != dc_connection_none);
1299                 }
1300         }
1301 }
1302
1303 void dc_hardware_init(struct dc *dc)
1304 {
1305
1306         detect_edp_presence(dc);
1307         if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW)
1308                 dc->hwss.init_hw(dc);
1309 }
1310
1311 void dc_init_callbacks(struct dc *dc,
1312                 const struct dc_callback_init *init_params)
1313 {
1314 #ifdef CONFIG_DRM_AMD_DC_HDCP
1315         dc->ctx->cp_psp = init_params->cp_psp;
1316 #endif
1317 }
1318
1319 void dc_deinit_callbacks(struct dc *dc)
1320 {
1321 #ifdef CONFIG_DRM_AMD_DC_HDCP
1322         memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp));
1323 #endif
1324 }
1325
1326 void dc_destroy(struct dc **dc)
1327 {
1328         dc_destruct(*dc);
1329         kfree(*dc);
1330         *dc = NULL;
1331 }
1332
1333 static void enable_timing_multisync(
1334                 struct dc *dc,
1335                 struct dc_state *ctx)
1336 {
1337         int i, multisync_count = 0;
1338         int pipe_count = dc->res_pool->pipe_count;
1339         struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL };
1340
1341         for (i = 0; i < pipe_count; i++) {
1342                 if (!ctx->res_ctx.pipe_ctx[i].stream ||
1343                                 !ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled)
1344                         continue;
1345                 if (ctx->res_ctx.pipe_ctx[i].stream == ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.event_source)
1346                         continue;
1347                 multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i];
1348                 multisync_count++;
1349         }
1350
1351         if (multisync_count > 0) {
1352                 dc->hwss.enable_per_frame_crtc_position_reset(
1353                         dc, multisync_count, multisync_pipes);
1354         }
1355 }
1356
1357 static void program_timing_sync(
1358                 struct dc *dc,
1359                 struct dc_state *ctx)
1360 {
1361         int i, j, k;
1362         int group_index = 0;
1363         int num_group = 0;
1364         int pipe_count = dc->res_pool->pipe_count;
1365         struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
1366
1367         for (i = 0; i < pipe_count; i++) {
1368                 if (!ctx->res_ctx.pipe_ctx[i].stream
1369                                 || ctx->res_ctx.pipe_ctx[i].top_pipe
1370                                 || ctx->res_ctx.pipe_ctx[i].prev_odm_pipe)
1371                         continue;
1372
1373                 unsynced_pipes[i] = &ctx->res_ctx.pipe_ctx[i];
1374         }
1375
1376         for (i = 0; i < pipe_count; i++) {
1377                 int group_size = 1;
1378                 enum timing_synchronization_type sync_type = NOT_SYNCHRONIZABLE;
1379                 struct pipe_ctx *pipe_set[MAX_PIPES];
1380
1381                 if (!unsynced_pipes[i])
1382                         continue;
1383
1384                 pipe_set[0] = unsynced_pipes[i];
1385                 unsynced_pipes[i] = NULL;
1386
1387                 /* Add tg to the set, search rest of the tg's for ones with
1388                  * same timing, add all tgs with same timing to the group
1389                  */
1390                 for (j = i + 1; j < pipe_count; j++) {
1391                         if (!unsynced_pipes[j])
1392                                 continue;
1393                         if (sync_type != TIMING_SYNCHRONIZABLE &&
1394                                 dc->hwss.enable_vblanks_synchronization &&
1395                                 unsynced_pipes[j]->stream_res.tg->funcs->align_vblanks &&
1396                                 resource_are_vblanks_synchronizable(
1397                                         unsynced_pipes[j]->stream,
1398                                         pipe_set[0]->stream)) {
1399                                 sync_type = VBLANK_SYNCHRONIZABLE;
1400                                 pipe_set[group_size] = unsynced_pipes[j];
1401                                 unsynced_pipes[j] = NULL;
1402                                 group_size++;
1403                         } else
1404                         if (sync_type != VBLANK_SYNCHRONIZABLE &&
1405                                 resource_are_streams_timing_synchronizable(
1406                                         unsynced_pipes[j]->stream,
1407                                         pipe_set[0]->stream)) {
1408                                 sync_type = TIMING_SYNCHRONIZABLE;
1409                                 pipe_set[group_size] = unsynced_pipes[j];
1410                                 unsynced_pipes[j] = NULL;
1411                                 group_size++;
1412                         }
1413                 }
1414
1415                 /* set first unblanked pipe as master */
1416                 for (j = 0; j < group_size; j++) {
1417                         bool is_blanked;
1418
1419                         if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
1420                                 is_blanked =
1421                                         pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
1422                         else
1423                                 is_blanked =
1424                                         pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
1425                         if (!is_blanked) {
1426                                 if (j == 0)
1427                                         break;
1428
1429                                 swap(pipe_set[0], pipe_set[j]);
1430                                 break;
1431                         }
1432                 }
1433
1434                 for (k = 0; k < group_size; k++) {
1435                         struct dc_stream_status *status = dc_stream_get_status_from_state(ctx, pipe_set[k]->stream);
1436
1437                         status->timing_sync_info.group_id = num_group;
1438                         status->timing_sync_info.group_size = group_size;
1439                         if (k == 0)
1440                                 status->timing_sync_info.master = true;
1441                         else
1442                                 status->timing_sync_info.master = false;
1443
1444                 }
1445
1446                 /* remove any other pipes that are already been synced */
1447                 if (dc->config.use_pipe_ctx_sync_logic) {
1448                         /* check pipe's syncd to decide which pipe to be removed */
1449                         for (j = 1; j < group_size; j++) {
1450                                 if (pipe_set[j]->pipe_idx_syncd == pipe_set[0]->pipe_idx_syncd) {
1451                                         group_size--;
1452                                         pipe_set[j] = pipe_set[group_size];
1453                                         j--;
1454                                 } else
1455                                         /* link slave pipe's syncd with master pipe */
1456                                         pipe_set[j]->pipe_idx_syncd = pipe_set[0]->pipe_idx_syncd;
1457                         }
1458                 } else {
1459                         for (j = j + 1; j < group_size; j++) {
1460                                 bool is_blanked;
1461
1462                                 if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
1463                                         is_blanked =
1464                                                 pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
1465                                 else
1466                                         is_blanked =
1467                                                 pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
1468                                 if (!is_blanked) {
1469                                         group_size--;
1470                                         pipe_set[j] = pipe_set[group_size];
1471                                         j--;
1472                                 }
1473                         }
1474                 }
1475
1476                 if (group_size > 1) {
1477                         if (sync_type == TIMING_SYNCHRONIZABLE) {
1478                                 dc->hwss.enable_timing_synchronization(
1479                                         dc, group_index, group_size, pipe_set);
1480                         } else
1481                                 if (sync_type == VBLANK_SYNCHRONIZABLE) {
1482                                 dc->hwss.enable_vblanks_synchronization(
1483                                         dc, group_index, group_size, pipe_set);
1484                                 }
1485                         group_index++;
1486                 }
1487                 num_group++;
1488         }
1489 }
1490
1491 static bool context_changed(
1492                 struct dc *dc,
1493                 struct dc_state *context)
1494 {
1495         uint8_t i;
1496
1497         if (context->stream_count != dc->current_state->stream_count)
1498                 return true;
1499
1500         for (i = 0; i < dc->current_state->stream_count; i++) {
1501                 if (dc->current_state->streams[i] != context->streams[i])
1502                         return true;
1503         }
1504
1505         return false;
1506 }
1507
1508 bool dc_validate_boot_timing(const struct dc *dc,
1509                                 const struct dc_sink *sink,
1510                                 struct dc_crtc_timing *crtc_timing)
1511 {
1512         struct timing_generator *tg;
1513         struct stream_encoder *se = NULL;
1514
1515         struct dc_crtc_timing hw_crtc_timing = {0};
1516
1517         struct dc_link *link = sink->link;
1518         unsigned int i, enc_inst, tg_inst = 0;
1519
1520         /* Support seamless boot on EDP displays only */
1521         if (sink->sink_signal != SIGNAL_TYPE_EDP) {
1522                 return false;
1523         }
1524
1525         /* Check for enabled DIG to identify enabled display */
1526         if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
1527                 return false;
1528
1529         enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
1530
1531         if (enc_inst == ENGINE_ID_UNKNOWN)
1532                 return false;
1533
1534         for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
1535                 if (dc->res_pool->stream_enc[i]->id == enc_inst) {
1536
1537                         se = dc->res_pool->stream_enc[i];
1538
1539                         tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg(
1540                                 dc->res_pool->stream_enc[i]);
1541                         break;
1542                 }
1543         }
1544
1545         // tg_inst not found
1546         if (i == dc->res_pool->stream_enc_count)
1547                 return false;
1548
1549         if (tg_inst >= dc->res_pool->timing_generator_count)
1550                 return false;
1551
1552         tg = dc->res_pool->timing_generators[tg_inst];
1553
1554         if (!tg->funcs->get_hw_timing)
1555                 return false;
1556
1557         if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing))
1558                 return false;
1559
1560         if (crtc_timing->h_total != hw_crtc_timing.h_total)
1561                 return false;
1562
1563         if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left)
1564                 return false;
1565
1566         if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable)
1567                 return false;
1568
1569         if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right)
1570                 return false;
1571
1572         if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch)
1573                 return false;
1574
1575         if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width)
1576                 return false;
1577
1578         if (crtc_timing->v_total != hw_crtc_timing.v_total)
1579                 return false;
1580
1581         if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top)
1582                 return false;
1583
1584         if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable)
1585                 return false;
1586
1587         if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom)
1588                 return false;
1589
1590         if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch)
1591                 return false;
1592
1593         if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width)
1594                 return false;
1595
1596         /* block DSC for now, as VBIOS does not currently support DSC timings */
1597         if (crtc_timing->flags.DSC)
1598                 return false;
1599
1600         if (dc_is_dp_signal(link->connector_signal)) {
1601                 unsigned int pix_clk_100hz;
1602                 uint32_t numOdmPipes = 1;
1603                 uint32_t id_src[4] = {0};
1604
1605                 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1606                         dc->res_pool->dp_clock_source,
1607                         tg_inst, &pix_clk_100hz);
1608
1609                 if (tg->funcs->get_optc_source)
1610                         tg->funcs->get_optc_source(tg,
1611                                                 &numOdmPipes, &id_src[0], &id_src[1]);
1612
1613                 if (numOdmPipes == 2)
1614                         pix_clk_100hz *= 2;
1615                 if (numOdmPipes == 4)
1616                         pix_clk_100hz *= 4;
1617
1618                 // Note: In rare cases, HW pixclk may differ from crtc's pixclk
1619                 // slightly due to rounding issues in 10 kHz units.
1620                 if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
1621                         return false;
1622
1623                 if (!se->funcs->dp_get_pixel_format)
1624                         return false;
1625
1626                 if (!se->funcs->dp_get_pixel_format(
1627                         se,
1628                         &hw_crtc_timing.pixel_encoding,
1629                         &hw_crtc_timing.display_color_depth))
1630                         return false;
1631
1632                 if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth)
1633                         return false;
1634
1635                 if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding)
1636                         return false;
1637         }
1638
1639         if (link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) {
1640                 return false;
1641         }
1642
1643         if (is_edp_ilr_optimization_required(link, crtc_timing)) {
1644                 DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n");
1645                 return false;
1646         }
1647
1648         return true;
1649 }
1650
1651 static inline bool should_update_pipe_for_stream(
1652                 struct dc_state *context,
1653                 struct pipe_ctx *pipe_ctx,
1654                 struct dc_stream_state *stream)
1655 {
1656         return (pipe_ctx->stream && pipe_ctx->stream == stream);
1657 }
1658
1659 static inline bool should_update_pipe_for_plane(
1660                 struct dc_state *context,
1661                 struct pipe_ctx *pipe_ctx,
1662                 struct dc_plane_state *plane_state)
1663 {
1664         return (pipe_ctx->plane_state == plane_state);
1665 }
1666
1667 void dc_enable_stereo(
1668         struct dc *dc,
1669         struct dc_state *context,
1670         struct dc_stream_state *streams[],
1671         uint8_t stream_count)
1672 {
1673         int i, j;
1674         struct pipe_ctx *pipe;
1675
1676         for (i = 0; i < MAX_PIPES; i++) {
1677                 if (context != NULL) {
1678                         pipe = &context->res_ctx.pipe_ctx[i];
1679                 } else {
1680                         context = dc->current_state;
1681                         pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1682                 }
1683
1684                 for (j = 0; pipe && j < stream_count; j++)  {
1685                         if (should_update_pipe_for_stream(context, pipe, streams[j]) &&
1686                                 dc->hwss.setup_stereo)
1687                                 dc->hwss.setup_stereo(pipe, dc);
1688                 }
1689         }
1690 }
1691
1692 void dc_trigger_sync(struct dc *dc, struct dc_state *context)
1693 {
1694         if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
1695                 enable_timing_multisync(dc, context);
1696                 program_timing_sync(dc, context);
1697         }
1698 }
1699
1700 static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context)
1701 {
1702         int i;
1703         unsigned int stream_mask = 0;
1704
1705         for (i = 0; i < dc->res_pool->pipe_count; i++) {
1706                 if (context->res_ctx.pipe_ctx[i].stream)
1707                         stream_mask |= 1 << i;
1708         }
1709
1710         return stream_mask;
1711 }
1712
1713 void dc_z10_restore(const struct dc *dc)
1714 {
1715         if (dc->hwss.z10_restore)
1716                 dc->hwss.z10_restore(dc);
1717 }
1718
1719 void dc_z10_save_init(struct dc *dc)
1720 {
1721         if (dc->hwss.z10_save_init)
1722                 dc->hwss.z10_save_init(dc);
1723 }
1724
1725 /*
1726  * Applies given context to HW and copy it into current context.
1727  * It's up to the user to release the src context afterwards.
1728  */
1729 static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
1730 {
1731         struct dc_bios *dcb = dc->ctx->dc_bios;
1732         enum dc_status result = DC_ERROR_UNEXPECTED;
1733         struct pipe_ctx *pipe;
1734         int i, k, l;
1735         struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
1736         struct dc_state *old_state;
1737         bool subvp_prev_use = false;
1738
1739         dc_z10_restore(dc);
1740         dc_allow_idle_optimizations(dc, false);
1741
1742         for (i = 0; i < dc->res_pool->pipe_count; i++) {
1743                 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1744
1745                 /* Check old context for SubVP */
1746                 subvp_prev_use |= (old_pipe->stream && old_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM);
1747                 if (subvp_prev_use)
1748                         break;
1749         }
1750
1751         for (i = 0; i < context->stream_count; i++)
1752                 dc_streams[i] =  context->streams[i];
1753
1754         if (!dcb->funcs->is_accelerated_mode(dcb)) {
1755                 disable_vbios_mode_if_required(dc, context);
1756                 dc->hwss.enable_accelerated_mode(dc, context);
1757         }
1758
1759         if (context->stream_count > get_seamless_boot_stream_count(context) ||
1760                 context->stream_count == 0)
1761                 dc->hwss.prepare_bandwidth(dc, context);
1762
1763         if (dc->debug.enable_double_buffered_dsc_pg_support)
1764                 dc->hwss.update_dsc_pg(dc, context, false);
1765
1766         disable_dangling_plane(dc, context);
1767         /* re-program planes for existing stream, in case we need to
1768          * free up plane resource for later use
1769          */
1770         if (dc->hwss.apply_ctx_for_surface) {
1771                 for (i = 0; i < context->stream_count; i++) {
1772                         if (context->streams[i]->mode_changed)
1773                                 continue;
1774                         apply_ctx_interdependent_lock(dc, context, context->streams[i], true);
1775                         dc->hwss.apply_ctx_for_surface(
1776                                 dc, context->streams[i],
1777                                 context->stream_status[i].plane_count,
1778                                 context); /* use new pipe config in new context */
1779                         apply_ctx_interdependent_lock(dc, context, context->streams[i], false);
1780                         dc->hwss.post_unlock_program_front_end(dc, context);
1781                 }
1782         }
1783
1784         /* Program hardware */
1785         for (i = 0; i < dc->res_pool->pipe_count; i++) {
1786                 pipe = &context->res_ctx.pipe_ctx[i];
1787                 dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
1788         }
1789
1790         if (dc->hwss.subvp_pipe_control_lock)
1791                 dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);
1792
1793         result = dc->hwss.apply_ctx_to_hw(dc, context);
1794
1795         if (result != DC_OK) {
1796                 /* Application of dc_state to hardware stopped. */
1797                 dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
1798                 return result;
1799         }
1800
1801         dc_trigger_sync(dc, context);
1802
1803         /* Program all planes within new context*/
1804         if (dc->hwss.program_front_end_for_ctx) {
1805                 dc->hwss.interdependent_update_lock(dc, context, true);
1806                 dc->hwss.program_front_end_for_ctx(dc, context);
1807                 dc->hwss.interdependent_update_lock(dc, context, false);
1808                 dc->hwss.post_unlock_program_front_end(dc, context);
1809         }
1810
1811         if (dc->hwss.commit_subvp_config)
1812                 dc->hwss.commit_subvp_config(dc, context);
1813         if (dc->hwss.subvp_pipe_control_lock)
1814                 dc->hwss.subvp_pipe_control_lock(dc, context, false, true, NULL, subvp_prev_use);
1815
1816         for (i = 0; i < context->stream_count; i++) {
1817                 const struct dc_link *link = context->streams[i]->link;
1818
1819                 if (!context->streams[i]->mode_changed)
1820                         continue;
1821
1822                 if (dc->hwss.apply_ctx_for_surface) {
1823                         apply_ctx_interdependent_lock(dc, context, context->streams[i], true);
1824                         dc->hwss.apply_ctx_for_surface(
1825                                         dc, context->streams[i],
1826                                         context->stream_status[i].plane_count,
1827                                         context);
1828                         apply_ctx_interdependent_lock(dc, context, context->streams[i], false);
1829                         dc->hwss.post_unlock_program_front_end(dc, context);
1830                 }
1831
1832                 /*
1833                  * enable stereo
1834                  * TODO rework dc_enable_stereo call to work with validation sets?
1835                  */
1836                 for (k = 0; k < MAX_PIPES; k++) {
1837                         pipe = &context->res_ctx.pipe_ctx[k];
1838
1839                         for (l = 0 ; pipe && l < context->stream_count; l++)  {
1840                                 if (context->streams[l] &&
1841                                         context->streams[l] == pipe->stream &&
1842                                         dc->hwss.setup_stereo)
1843                                         dc->hwss.setup_stereo(pipe, dc);
1844                         }
1845                 }
1846
1847                 CONN_MSG_MODE(link, "{%dx%d, %dx%d@%dKhz}",
1848                                 context->streams[i]->timing.h_addressable,
1849                                 context->streams[i]->timing.v_addressable,
1850                                 context->streams[i]->timing.h_total,
1851                                 context->streams[i]->timing.v_total,
1852                                 context->streams[i]->timing.pix_clk_100hz / 10);
1853         }
1854
1855         dc_enable_stereo(dc, context, dc_streams, context->stream_count);
1856
1857         if (context->stream_count > get_seamless_boot_stream_count(context) ||
1858                 context->stream_count == 0) {
1859                 /* Must wait for no flips to be pending before doing optimize bw */
1860                 wait_for_no_pipes_pending(dc, context);
1861                 /* pplib is notified if disp_num changed */
1862                 dc->hwss.optimize_bandwidth(dc, context);
1863         }
1864
1865         if (dc->debug.enable_double_buffered_dsc_pg_support)
1866                 dc->hwss.update_dsc_pg(dc, context, true);
1867
1868         if (dc->ctx->dce_version >= DCE_VERSION_MAX)
1869                 TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk);
1870         else
1871                 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
1872
1873         context->stream_mask = get_stream_mask(dc, context);
1874
1875         if (context->stream_mask != dc->current_state->stream_mask)
1876                 dc_dmub_srv_notify_stream_mask(dc->ctx->dmub_srv, context->stream_mask);
1877
1878         for (i = 0; i < context->stream_count; i++)
1879                 context->streams[i]->mode_changed = false;
1880
1881         old_state = dc->current_state;
1882         dc->current_state = context;
1883
1884         dc_release_state(old_state);
1885
1886         dc_retain_state(dc->current_state);
1887
1888         return result;
1889 }
1890
1891 bool dc_commit_state(struct dc *dc, struct dc_state *context)
1892 {
1893         enum dc_status result = DC_ERROR_UNEXPECTED;
1894         int i;
1895
1896         if (!context_changed(dc, context))
1897                 return DC_OK;
1898
1899         DC_LOG_DC("%s: %d streams\n",
1900                                 __func__, context->stream_count);
1901
1902         for (i = 0; i < context->stream_count; i++) {
1903                 struct dc_stream_state *stream = context->streams[i];
1904
1905                 dc_stream_log(dc, stream);
1906         }
1907
1908         /*
1909          * Previous validation was perfomred with fast_validation = true and
1910          * the full DML state required for hardware programming was skipped.
1911          *
1912          * Re-validate here to calculate these parameters / watermarks.
1913          */
1914         result = dc_validate_global_state(dc, context, false);
1915         if (result != DC_OK) {
1916                 DC_LOG_ERROR("DC commit global validation failure: %s (%d)",
1917                              dc_status_to_str(result), result);
1918                 return result;
1919         }
1920
1921         result = dc_commit_state_no_check(dc, context);
1922
1923         return (result == DC_OK);
1924 }
1925
1926 bool dc_acquire_release_mpc_3dlut(
1927                 struct dc *dc, bool acquire,
1928                 struct dc_stream_state *stream,
1929                 struct dc_3dlut **lut,
1930                 struct dc_transfer_func **shaper)
1931 {
1932         int pipe_idx;
1933         bool ret = false;
1934         bool found_pipe_idx = false;
1935         const struct resource_pool *pool = dc->res_pool;
1936         struct resource_context *res_ctx = &dc->current_state->res_ctx;
1937         int mpcc_id = 0;
1938
1939         if (pool && res_ctx) {
1940                 if (acquire) {
1941                         /*find pipe idx for the given stream*/
1942                         for (pipe_idx = 0; pipe_idx < pool->pipe_count; pipe_idx++) {
1943                                 if (res_ctx->pipe_ctx[pipe_idx].stream == stream) {
1944                                         found_pipe_idx = true;
1945                                         mpcc_id = res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst;
1946                                         break;
1947                                 }
1948                         }
1949                 } else
1950                         found_pipe_idx = true;/*for release pipe_idx is not required*/
1951
1952                 if (found_pipe_idx) {
1953                         if (acquire && pool->funcs->acquire_post_bldn_3dlut)
1954                                 ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper);
1955                         else if (!acquire && pool->funcs->release_post_bldn_3dlut)
1956                                 ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper);
1957                 }
1958         }
1959         return ret;
1960 }
1961
1962 static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
1963 {
1964         int i;
1965         struct pipe_ctx *pipe;
1966
1967         for (i = 0; i < MAX_PIPES; i++) {
1968                 pipe = &context->res_ctx.pipe_ctx[i];
1969
1970                 // Don't check flip pending on phantom pipes
1971                 if (!pipe->plane_state || (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM))
1972                         continue;
1973
1974                 /* Must set to false to start with, due to OR in update function */
1975                 pipe->plane_state->status.is_flip_pending = false;
1976                 dc->hwss.update_pending_status(pipe);
1977                 if (pipe->plane_state->status.is_flip_pending)
1978                         return true;
1979         }
1980         return false;
1981 }
1982
1983 /* Perform updates here which need to be deferred until next vupdate
1984  *
1985  * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered
1986  * but forcing lut memory to shutdown state is immediate. This causes
1987  * single frame corruption as lut gets disabled mid-frame unless shutdown
1988  * is deferred until after entering bypass.
1989  */
1990 static void process_deferred_updates(struct dc *dc)
1991 {
1992         int i = 0;
1993
1994         if (dc->debug.enable_mem_low_power.bits.cm) {
1995                 ASSERT(dc->dcn_ip->max_num_dpp);
1996                 for (i = 0; i < dc->dcn_ip->max_num_dpp; i++)
1997                         if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update)
1998                                 dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]);
1999         }
2000 }
2001
2002 void dc_post_update_surfaces_to_stream(struct dc *dc)
2003 {
2004         int i;
2005         struct dc_state *context = dc->current_state;
2006
2007         if ((!dc->optimized_required) || get_seamless_boot_stream_count(context) > 0)
2008                 return;
2009
2010         post_surface_trace(dc);
2011
2012         if (dc->ctx->dce_version >= DCE_VERSION_MAX)
2013                 TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk);
2014         else
2015                 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
2016
2017         if (is_flip_pending_in_pipes(dc, context))
2018                 return;
2019
2020         for (i = 0; i < dc->res_pool->pipe_count; i++)
2021                 if (context->res_ctx.pipe_ctx[i].stream == NULL ||
2022                     context->res_ctx.pipe_ctx[i].plane_state == NULL) {
2023                         context->res_ctx.pipe_ctx[i].pipe_idx = i;
2024                         dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
2025                 }
2026
2027         process_deferred_updates(dc);
2028
2029         dc->hwss.optimize_bandwidth(dc, context);
2030
2031         if (dc->debug.enable_double_buffered_dsc_pg_support)
2032                 dc->hwss.update_dsc_pg(dc, context, true);
2033
2034         dc->optimized_required = false;
2035         dc->wm_optimized_required = false;
2036 }
2037
2038 static void init_state(struct dc *dc, struct dc_state *context)
2039 {
2040         /* Each context must have their own instance of VBA and in order to
2041          * initialize and obtain IP and SOC the base DML instance from DC is
2042          * initially copied into every context
2043          */
2044         memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib));
2045 }
2046
2047 struct dc_state *dc_create_state(struct dc *dc)
2048 {
2049         struct dc_state *context = kvzalloc(sizeof(struct dc_state),
2050                                             GFP_KERNEL);
2051
2052         if (!context)
2053                 return NULL;
2054
2055         init_state(dc, context);
2056
2057         kref_init(&context->refcount);
2058
2059         return context;
2060 }
2061
2062 struct dc_state *dc_copy_state(struct dc_state *src_ctx)
2063 {
2064         int i, j;
2065         struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL);
2066
2067         if (!new_ctx)
2068                 return NULL;
2069         memcpy(new_ctx, src_ctx, sizeof(struct dc_state));
2070
2071         for (i = 0; i < MAX_PIPES; i++) {
2072                         struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i];
2073
2074                         if (cur_pipe->top_pipe)
2075                                 cur_pipe->top_pipe =  &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx];
2076
2077                         if (cur_pipe->bottom_pipe)
2078                                 cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx];
2079
2080                         if (cur_pipe->prev_odm_pipe)
2081                                 cur_pipe->prev_odm_pipe =  &new_ctx->res_ctx.pipe_ctx[cur_pipe->prev_odm_pipe->pipe_idx];
2082
2083                         if (cur_pipe->next_odm_pipe)
2084                                 cur_pipe->next_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->next_odm_pipe->pipe_idx];
2085
2086         }
2087
2088         for (i = 0; i < new_ctx->stream_count; i++) {
2089                         dc_stream_retain(new_ctx->streams[i]);
2090                         for (j = 0; j < new_ctx->stream_status[i].plane_count; j++)
2091                                 dc_plane_state_retain(
2092                                         new_ctx->stream_status[i].plane_states[j]);
2093         }
2094
2095         kref_init(&new_ctx->refcount);
2096
2097         return new_ctx;
2098 }
2099
2100 void dc_retain_state(struct dc_state *context)
2101 {
2102         kref_get(&context->refcount);
2103 }
2104
2105 static void dc_state_free(struct kref *kref)
2106 {
2107         struct dc_state *context = container_of(kref, struct dc_state, refcount);
2108         dc_resource_state_destruct(context);
2109         kvfree(context);
2110 }
2111
2112 void dc_release_state(struct dc_state *context)
2113 {
2114         kref_put(&context->refcount, dc_state_free);
2115 }
2116
2117 bool dc_set_generic_gpio_for_stereo(bool enable,
2118                 struct gpio_service *gpio_service)
2119 {
2120         enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR;
2121         struct gpio_pin_info pin_info;
2122         struct gpio *generic;
2123         struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config),
2124                            GFP_KERNEL);
2125
2126         if (!config)
2127                 return false;
2128         pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0);
2129
2130         if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) {
2131                 kfree(config);
2132                 return false;
2133         } else {
2134                 generic = dal_gpio_service_create_generic_mux(
2135                         gpio_service,
2136                         pin_info.offset,
2137                         pin_info.mask);
2138         }
2139
2140         if (!generic) {
2141                 kfree(config);
2142                 return false;
2143         }
2144
2145         gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT);
2146
2147         config->enable_output_from_mux = enable;
2148         config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC;
2149
2150         if (gpio_result == GPIO_RESULT_OK)
2151                 gpio_result = dal_mux_setup_config(generic, config);
2152
2153         if (gpio_result == GPIO_RESULT_OK) {
2154                 dal_gpio_close(generic);
2155                 dal_gpio_destroy_generic_mux(&generic);
2156                 kfree(config);
2157                 return true;
2158         } else {
2159                 dal_gpio_close(generic);
2160                 dal_gpio_destroy_generic_mux(&generic);
2161                 kfree(config);
2162                 return false;
2163         }
2164 }
2165
2166 static bool is_surface_in_context(
2167                 const struct dc_state *context,
2168                 const struct dc_plane_state *plane_state)
2169 {
2170         int j;
2171
2172         for (j = 0; j < MAX_PIPES; j++) {
2173                 const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2174
2175                 if (plane_state == pipe_ctx->plane_state) {
2176                         return true;
2177                 }
2178         }
2179
2180         return false;
2181 }
2182
2183 static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
2184 {
2185         union surface_update_flags *update_flags = &u->surface->update_flags;
2186         enum surface_update_type update_type = UPDATE_TYPE_FAST;
2187
2188         if (!u->plane_info)
2189                 return UPDATE_TYPE_FAST;
2190
2191         if (u->plane_info->color_space != u->surface->color_space) {
2192                 update_flags->bits.color_space_change = 1;
2193                 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2194         }
2195
2196         if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror) {
2197                 update_flags->bits.horizontal_mirror_change = 1;
2198                 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2199         }
2200
2201         if (u->plane_info->rotation != u->surface->rotation) {
2202                 update_flags->bits.rotation_change = 1;
2203                 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2204         }
2205
2206         if (u->plane_info->format != u->surface->format) {
2207                 update_flags->bits.pixel_format_change = 1;
2208                 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2209         }
2210
2211         if (u->plane_info->stereo_format != u->surface->stereo_format) {
2212                 update_flags->bits.stereo_format_change = 1;
2213                 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2214         }
2215
2216         if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha) {
2217                 update_flags->bits.per_pixel_alpha_change = 1;
2218                 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2219         }
2220
2221         if (u->plane_info->global_alpha_value != u->surface->global_alpha_value) {
2222                 update_flags->bits.global_alpha_change = 1;
2223                 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2224         }
2225
2226         if (u->plane_info->dcc.enable != u->surface->dcc.enable
2227                         || u->plane_info->dcc.dcc_ind_blk != u->surface->dcc.dcc_ind_blk
2228                         || u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) {
2229                 /* During DCC on/off, stutter period is calculated before
2230                  * DCC has fully transitioned. This results in incorrect
2231                  * stutter period calculation. Triggering a full update will
2232                  * recalculate stutter period.
2233                  */
2234                 update_flags->bits.dcc_change = 1;
2235                 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2236         }
2237
2238         if (resource_pixel_format_to_bpp(u->plane_info->format) !=
2239                         resource_pixel_format_to_bpp(u->surface->format)) {
2240                 /* different bytes per element will require full bandwidth
2241                  * and DML calculation
2242                  */
2243                 update_flags->bits.bpp_change = 1;
2244                 elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2245         }
2246
2247         if (u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
2248                         || u->plane_info->plane_size.chroma_pitch != u->surface->plane_size.chroma_pitch) {
2249                 update_flags->bits.plane_size_change = 1;
2250                 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2251         }
2252
2253
2254         if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
2255                         sizeof(union dc_tiling_info)) != 0) {
2256                 update_flags->bits.swizzle_change = 1;
2257                 elevate_update_type(&update_type, UPDATE_TYPE_MED);
2258
2259                 /* todo: below are HW dependent, we should add a hook to
2260                  * DCE/N resource and validated there.
2261                  */
2262                 if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
2263                         /* swizzled mode requires RQ to be setup properly,
2264                          * thus need to run DML to calculate RQ settings
2265                          */
2266                         update_flags->bits.bandwidth_change = 1;
2267                         elevate_update_type(&update_type, UPDATE_TYPE_FULL);
2268                 }
2269         }
2270
2271         /* This should be UPDATE_TYPE_FAST if nothing has changed. */
2272         return update_type;
2273 }
2274
2275 static enum surface_update_type get_scaling_info_update_type(
2276                 const struct dc_surface_update *u)
2277 {
2278         union surface_update_flags *update_flags = &u->surface->update_flags;
2279
2280         if (!u->scaling_info)
2281                 return UPDATE_TYPE_FAST;
2282
2283         if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width
2284                         || u->scaling_info->clip_rect.height != u->surface->clip_rect.height
2285                         || u->scaling_info->dst_rect.width != u->surface->dst_rect.width
2286                         || u->scaling_info->dst_rect.height != u->surface->dst_rect.height
2287                         || u->scaling_info->scaling_quality.integer_scaling !=
2288                                 u->surface->scaling_quality.integer_scaling
2289                         ) {
2290                 update_flags->bits.scaling_change = 1;
2291
2292                 if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width
2293                         || u->scaling_info->dst_rect.height < u->surface->dst_rect.height)
2294                                 && (u->scaling_info->dst_rect.width < u->surface->src_rect.width
2295                                         || u->scaling_info->dst_rect.height < u->surface->src_rect.height))
2296                         /* Making dst rect smaller requires a bandwidth change */
2297                         update_flags->bits.bandwidth_change = 1;
2298         }
2299
2300         if (u->scaling_info->src_rect.width != u->surface->src_rect.width
2301                 || u->scaling_info->src_rect.height != u->surface->src_rect.height) {
2302
2303                 update_flags->bits.scaling_change = 1;
2304                 if (u->scaling_info->src_rect.width > u->surface->src_rect.width
2305                                 || u->scaling_info->src_rect.height > u->surface->src_rect.height)
2306                         /* Making src rect bigger requires a bandwidth change */
2307                         update_flags->bits.clock_change = 1;
2308         }
2309
2310         if (u->scaling_info->src_rect.x != u->surface->src_rect.x
2311                         || u->scaling_info->src_rect.y != u->surface->src_rect.y
2312                         || u->scaling_info->clip_rect.x != u->surface->clip_rect.x
2313                         || u->scaling_info->clip_rect.y != u->surface->clip_rect.y
2314                         || u->scaling_info->dst_rect.x != u->surface->dst_rect.x
2315                         || u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
2316                 update_flags->bits.position_change = 1;
2317
2318         if (update_flags->bits.clock_change
2319                         || update_flags->bits.bandwidth_change
2320                         || update_flags->bits.scaling_change)
2321                 return UPDATE_TYPE_FULL;
2322
2323         if (update_flags->bits.position_change)
2324                 return UPDATE_TYPE_MED;
2325
2326         return UPDATE_TYPE_FAST;
2327 }
2328
2329 static enum surface_update_type det_surface_update(const struct dc *dc,
2330                 const struct dc_surface_update *u)
2331 {
2332         const struct dc_state *context = dc->current_state;
2333         enum surface_update_type type;
2334         enum surface_update_type overall_type = UPDATE_TYPE_FAST;
2335         union surface_update_flags *update_flags = &u->surface->update_flags;
2336
2337         if (u->flip_addr)
2338                 update_flags->bits.addr_update = 1;
2339
2340         if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) {
2341                 update_flags->raw = 0xFFFFFFFF;
2342                 return UPDATE_TYPE_FULL;
2343         }
2344
2345         update_flags->raw = 0; // Reset all flags
2346
2347         type = get_plane_info_update_type(u);
2348         elevate_update_type(&overall_type, type);
2349
2350         type = get_scaling_info_update_type(u);
2351         elevate_update_type(&overall_type, type);
2352
2353         if (u->flip_addr) {
2354                 update_flags->bits.addr_update = 1;
2355                 if (u->flip_addr->address.tmz_surface != u->surface->address.tmz_surface) {
2356                         update_flags->bits.tmz_changed = 1;
2357                         elevate_update_type(&overall_type, UPDATE_TYPE_FULL);
2358                 }
2359         }
2360         if (u->in_transfer_func)
2361                 update_flags->bits.in_transfer_func_change = 1;
2362
2363         if (u->input_csc_color_matrix)
2364                 update_flags->bits.input_csc_change = 1;
2365
2366         if (u->coeff_reduction_factor)
2367                 update_flags->bits.coeff_reduction_change = 1;
2368
2369         if (u->gamut_remap_matrix)
2370                 update_flags->bits.gamut_remap_change = 1;
2371
2372         if (u->gamma) {
2373                 enum surface_pixel_format format = SURFACE_PIXEL_FORMAT_GRPH_BEGIN;
2374
2375                 if (u->plane_info)
2376                         format = u->plane_info->format;
2377                 else if (u->surface)
2378                         format = u->surface->format;
2379
2380                 if (dce_use_lut(format))
2381                         update_flags->bits.gamma_change = 1;
2382         }
2383
2384         if (u->lut3d_func || u->func_shaper)
2385                 update_flags->bits.lut_3d = 1;
2386
2387         if (u->hdr_mult.value)
2388                 if (u->hdr_mult.value != u->surface->hdr_mult.value) {
2389                         update_flags->bits.hdr_mult = 1;
2390                         elevate_update_type(&overall_type, UPDATE_TYPE_MED);
2391                 }
2392
2393         if (update_flags->bits.in_transfer_func_change) {
2394                 type = UPDATE_TYPE_MED;
2395                 elevate_update_type(&overall_type, type);
2396         }
2397
2398         if (update_flags->bits.input_csc_change
2399                         || update_flags->bits.coeff_reduction_change
2400                         || update_flags->bits.lut_3d
2401                         || update_flags->bits.gamma_change
2402                         || update_flags->bits.gamut_remap_change) {
2403                 type = UPDATE_TYPE_FULL;
2404                 elevate_update_type(&overall_type, type);
2405         }
2406
2407         return overall_type;
2408 }
2409
2410 static enum surface_update_type check_update_surfaces_for_stream(
2411                 struct dc *dc,
2412                 struct dc_surface_update *updates,
2413                 int surface_count,
2414                 struct dc_stream_update *stream_update,
2415                 const struct dc_stream_status *stream_status)
2416 {
2417         int i;
2418         enum surface_update_type overall_type = UPDATE_TYPE_FAST;
2419
2420         if (dc->idle_optimizations_allowed)
2421                 overall_type = UPDATE_TYPE_FULL;
2422
2423         if (stream_status == NULL || stream_status->plane_count != surface_count)
2424                 overall_type = UPDATE_TYPE_FULL;
2425
2426         if (stream_update && stream_update->pending_test_pattern) {
2427                 overall_type = UPDATE_TYPE_FULL;
2428         }
2429
2430         /* some stream updates require passive update */
2431         if (stream_update) {
2432                 union stream_update_flags *su_flags = &stream_update->stream->update_flags;
2433
2434                 if ((stream_update->src.height != 0 && stream_update->src.width != 0) ||
2435                         (stream_update->dst.height != 0 && stream_update->dst.width != 0) ||
2436                         stream_update->integer_scaling_update)
2437                         su_flags->bits.scaling = 1;
2438
2439                 if (stream_update->out_transfer_func)
2440                         su_flags->bits.out_tf = 1;
2441
2442                 if (stream_update->abm_level)
2443                         su_flags->bits.abm_level = 1;
2444
2445                 if (stream_update->dpms_off)
2446                         su_flags->bits.dpms_off = 1;
2447
2448                 if (stream_update->gamut_remap)
2449                         su_flags->bits.gamut_remap = 1;
2450
2451                 if (stream_update->wb_update)
2452                         su_flags->bits.wb_update = 1;
2453
2454                 if (stream_update->dsc_config)
2455                         su_flags->bits.dsc_changed = 1;
2456
2457                 if (stream_update->mst_bw_update)
2458                         su_flags->bits.mst_bw = 1;
2459                 if (stream_update->crtc_timing_adjust && dc_extended_blank_supported(dc))
2460                         su_flags->bits.crtc_timing_adjust = 1;
2461
2462                 if (su_flags->raw != 0)
2463                         overall_type = UPDATE_TYPE_FULL;
2464
2465                 if (stream_update->output_csc_transform || stream_update->output_color_space)
2466                         su_flags->bits.out_csc = 1;
2467         }
2468
2469         for (i = 0 ; i < surface_count; i++) {
2470                 enum surface_update_type type =
2471                                 det_surface_update(dc, &updates[i]);
2472
2473                 elevate_update_type(&overall_type, type);
2474         }
2475
2476         return overall_type;
2477 }
2478
2479 static bool dc_check_is_fullscreen_video(struct rect src, struct rect clip_rect)
2480 {
2481         int view_height, view_width, clip_x, clip_y, clip_width, clip_height;
2482
2483         view_height = src.height;
2484         view_width = src.width;
2485
2486         clip_x = clip_rect.x;
2487         clip_y = clip_rect.y;
2488
2489         clip_width = clip_rect.width;
2490         clip_height = clip_rect.height;
2491
2492         /* check for centered video accounting for off by 1 scaling truncation */
2493         if ((view_height - clip_y - clip_height <= clip_y + 1) &&
2494                         (view_width - clip_x - clip_width <= clip_x + 1) &&
2495                         (view_height - clip_y - clip_height >= clip_y - 1) &&
2496                         (view_width - clip_x - clip_width >= clip_x - 1)) {
2497
2498                 /* when OS scales up/down to letter box, it may end up
2499                  * with few blank pixels on the border due to truncating.
2500                  * Add offset margin to account for this
2501                  */
2502                 if (clip_x <= 4 || clip_y <= 4)
2503                         return true;
2504         }
2505
2506         return false;
2507 }
2508
2509 static enum surface_update_type check_boundary_crossing_for_windowed_mpo_with_odm(struct dc *dc,
2510                 struct dc_surface_update *srf_updates, int surface_count,
2511                 enum surface_update_type update_type)
2512 {
2513         enum surface_update_type new_update_type = update_type;
2514         int i, j;
2515         struct pipe_ctx *pipe = NULL;
2516         struct dc_stream_state *stream;
2517
2518         /* Check that we are in windowed MPO with ODM
2519          * - look for MPO pipe by scanning pipes for first pipe matching
2520          *   surface that has moved ( position change )
2521          * - MPO pipe will have top pipe
2522          * - check that top pipe has ODM pointer
2523          */
2524         if ((surface_count > 1) && dc->config.enable_windowed_mpo_odm) {
2525                 for (i = 0; i < surface_count; i++) {
2526                         if (srf_updates[i].surface && srf_updates[i].scaling_info
2527                                         && srf_updates[i].surface->update_flags.bits.position_change) {
2528
2529                                 for (j = 0; j < dc->res_pool->pipe_count; j++) {
2530                                         if (srf_updates[i].surface == dc->current_state->res_ctx.pipe_ctx[j].plane_state) {
2531                                                 pipe = &dc->current_state->res_ctx.pipe_ctx[j];
2532                                                 stream = pipe->stream;
2533                                                 break;
2534                                         }
2535                                 }
2536
2537                                 if (pipe && pipe->top_pipe && (get_num_odm_splits(pipe->top_pipe) > 0) && stream
2538                                                 && !dc_check_is_fullscreen_video(stream->src, srf_updates[i].scaling_info->clip_rect)) {
2539                                         struct rect old_clip_rect, new_clip_rect;
2540                                         bool old_clip_rect_left, old_clip_rect_right, old_clip_rect_middle;
2541                                         bool new_clip_rect_left, new_clip_rect_right, new_clip_rect_middle;
2542
2543                                         old_clip_rect = srf_updates[i].surface->clip_rect;
2544                                         new_clip_rect = srf_updates[i].scaling_info->clip_rect;
2545
2546                                         old_clip_rect_left = ((old_clip_rect.x + old_clip_rect.width) <= (stream->src.x + (stream->src.width/2)));
2547                                         old_clip_rect_right = (old_clip_rect.x >= (stream->src.x + (stream->src.width/2)));
2548                                         old_clip_rect_middle = !old_clip_rect_left && !old_clip_rect_right;
2549
2550                                         new_clip_rect_left = ((new_clip_rect.x + new_clip_rect.width) <= (stream->src.x + (stream->src.width/2)));
2551                                         new_clip_rect_right = (new_clip_rect.x >= (stream->src.x + (stream->src.width/2)));
2552                                         new_clip_rect_middle = !new_clip_rect_left && !new_clip_rect_right;
2553
2554                                         if (old_clip_rect_left && new_clip_rect_middle)
2555                                                 new_update_type = UPDATE_TYPE_FULL;
2556                                         else if (old_clip_rect_middle && new_clip_rect_right)
2557                                                 new_update_type = UPDATE_TYPE_FULL;
2558                                         else if (old_clip_rect_right && new_clip_rect_middle)
2559                                                 new_update_type = UPDATE_TYPE_FULL;
2560                                         else if (old_clip_rect_middle && new_clip_rect_left)
2561                                                 new_update_type = UPDATE_TYPE_FULL;
2562                                 }
2563                         }
2564                 }
2565         }
2566         return new_update_type;
2567 }
2568
2569 /*
2570  * dc_check_update_surfaces_for_stream() - Determine update type (fast, med, or full)
2571  *
2572  * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types
2573  */
2574 enum surface_update_type dc_check_update_surfaces_for_stream(
2575                 struct dc *dc,
2576                 struct dc_surface_update *updates,
2577                 int surface_count,
2578                 struct dc_stream_update *stream_update,
2579                 const struct dc_stream_status *stream_status)
2580 {
2581         int i;
2582         enum surface_update_type type;
2583
2584         if (stream_update)
2585                 stream_update->stream->update_flags.raw = 0;
2586         for (i = 0; i < surface_count; i++)
2587                 updates[i].surface->update_flags.raw = 0;
2588
2589         type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
2590         if (type == UPDATE_TYPE_FULL) {
2591                 if (stream_update) {
2592                         uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed;
2593                         stream_update->stream->update_flags.raw = 0xFFFFFFFF;
2594                         stream_update->stream->update_flags.bits.dsc_changed = dsc_changed;
2595                 }
2596                 for (i = 0; i < surface_count; i++)
2597                         updates[i].surface->update_flags.raw = 0xFFFFFFFF;
2598         }
2599
2600         if (type == UPDATE_TYPE_MED)
2601                 type = check_boundary_crossing_for_windowed_mpo_with_odm(dc,
2602                                 updates, surface_count, type);
2603
2604         if (type == UPDATE_TYPE_FAST) {
2605                 // If there's an available clock comparator, we use that.
2606                 if (dc->clk_mgr->funcs->are_clock_states_equal) {
2607                         if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk))
2608                                 dc->optimized_required = true;
2609                 // Else we fallback to mem compare.
2610                 } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
2611                         dc->optimized_required = true;
2612                 }
2613
2614                 dc->optimized_required |= dc->wm_optimized_required;
2615         }
2616
2617         return type;
2618 }
2619
2620 static struct dc_stream_status *stream_get_status(
2621         struct dc_state *ctx,
2622         struct dc_stream_state *stream)
2623 {
2624         uint8_t i;
2625
2626         for (i = 0; i < ctx->stream_count; i++) {
2627                 if (stream == ctx->streams[i]) {
2628                         return &ctx->stream_status[i];
2629                 }
2630         }
2631
2632         return NULL;
2633 }
2634
2635 static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
2636
2637 static void copy_surface_update_to_plane(
2638                 struct dc_plane_state *surface,
2639                 struct dc_surface_update *srf_update)
2640 {
2641         if (srf_update->flip_addr) {
2642                 surface->address = srf_update->flip_addr->address;
2643                 surface->flip_immediate =
2644                         srf_update->flip_addr->flip_immediate;
2645                 surface->time.time_elapsed_in_us[surface->time.index] =
2646                         srf_update->flip_addr->flip_timestamp_in_us -
2647                                 surface->time.prev_update_time_in_us;
2648                 surface->time.prev_update_time_in_us =
2649                         srf_update->flip_addr->flip_timestamp_in_us;
2650                 surface->time.index++;
2651                 if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
2652                         surface->time.index = 0;
2653
2654                 surface->triplebuffer_flips = srf_update->flip_addr->triplebuffer_flips;
2655         }
2656
2657         if (srf_update->scaling_info) {
2658                 surface->scaling_quality =
2659                                 srf_update->scaling_info->scaling_quality;
2660                 surface->dst_rect =
2661                                 srf_update->scaling_info->dst_rect;
2662                 surface->src_rect =
2663                                 srf_update->scaling_info->src_rect;
2664                 surface->clip_rect =
2665                                 srf_update->scaling_info->clip_rect;
2666         }
2667
2668         if (srf_update->plane_info) {
2669                 surface->color_space =
2670                                 srf_update->plane_info->color_space;
2671                 surface->format =
2672                                 srf_update->plane_info->format;
2673                 surface->plane_size =
2674                                 srf_update->plane_info->plane_size;
2675                 surface->rotation =
2676                                 srf_update->plane_info->rotation;
2677                 surface->horizontal_mirror =
2678                                 srf_update->plane_info->horizontal_mirror;
2679                 surface->stereo_format =
2680                                 srf_update->plane_info->stereo_format;
2681                 surface->tiling_info =
2682                                 srf_update->plane_info->tiling_info;
2683                 surface->visible =
2684                                 srf_update->plane_info->visible;
2685                 surface->per_pixel_alpha =
2686                                 srf_update->plane_info->per_pixel_alpha;
2687                 surface->global_alpha =
2688                                 srf_update->plane_info->global_alpha;
2689                 surface->global_alpha_value =
2690                                 srf_update->plane_info->global_alpha_value;
2691                 surface->dcc =
2692                                 srf_update->plane_info->dcc;
2693                 surface->layer_index =
2694                                 srf_update->plane_info->layer_index;
2695         }
2696
2697         if (srf_update->gamma &&
2698                         (surface->gamma_correction !=
2699                                         srf_update->gamma)) {
2700                 memcpy(&surface->gamma_correction->entries,
2701                         &srf_update->gamma->entries,
2702                         sizeof(struct dc_gamma_entries));
2703                 surface->gamma_correction->is_identity =
2704                         srf_update->gamma->is_identity;
2705                 surface->gamma_correction->num_entries =
2706                         srf_update->gamma->num_entries;
2707                 surface->gamma_correction->type =
2708                         srf_update->gamma->type;
2709         }
2710
2711         if (srf_update->in_transfer_func &&
2712                         (surface->in_transfer_func !=
2713                                 srf_update->in_transfer_func)) {
2714                 surface->in_transfer_func->sdr_ref_white_level =
2715                         srf_update->in_transfer_func->sdr_ref_white_level;
2716                 surface->in_transfer_func->tf =
2717                         srf_update->in_transfer_func->tf;
2718                 surface->in_transfer_func->type =
2719                         srf_update->in_transfer_func->type;
2720                 memcpy(&surface->in_transfer_func->tf_pts,
2721                         &srf_update->in_transfer_func->tf_pts,
2722                         sizeof(struct dc_transfer_func_distributed_points));
2723         }
2724
2725         if (srf_update->func_shaper &&
2726                         (surface->in_shaper_func !=
2727                         srf_update->func_shaper))
2728                 memcpy(surface->in_shaper_func, srf_update->func_shaper,
2729                 sizeof(*surface->in_shaper_func));
2730
2731         if (srf_update->lut3d_func &&
2732                         (surface->lut3d_func !=
2733                         srf_update->lut3d_func))
2734                 memcpy(surface->lut3d_func, srf_update->lut3d_func,
2735                 sizeof(*surface->lut3d_func));
2736
2737         if (srf_update->hdr_mult.value)
2738                 surface->hdr_mult =
2739                                 srf_update->hdr_mult;
2740
2741         if (srf_update->blend_tf &&
2742                         (surface->blend_tf !=
2743                         srf_update->blend_tf))
2744                 memcpy(surface->blend_tf, srf_update->blend_tf,
2745                 sizeof(*surface->blend_tf));
2746
2747         if (srf_update->input_csc_color_matrix)
2748                 surface->input_csc_color_matrix =
2749                         *srf_update->input_csc_color_matrix;
2750
2751         if (srf_update->coeff_reduction_factor)
2752                 surface->coeff_reduction_factor =
2753                         *srf_update->coeff_reduction_factor;
2754
2755         if (srf_update->gamut_remap_matrix)
2756                 surface->gamut_remap_matrix =
2757                         *srf_update->gamut_remap_matrix;
2758 }
2759
2760 static void copy_stream_update_to_stream(struct dc *dc,
2761                                          struct dc_state *context,
2762                                          struct dc_stream_state *stream,
2763                                          struct dc_stream_update *update)
2764 {
2765         struct dc_context *dc_ctx = dc->ctx;
2766
2767         if (update == NULL || stream == NULL)
2768                 return;
2769
2770         if (update->src.height && update->src.width)
2771                 stream->src = update->src;
2772
2773         if (update->dst.height && update->dst.width)
2774                 stream->dst = update->dst;
2775
2776         if (update->out_transfer_func &&
2777             stream->out_transfer_func != update->out_transfer_func) {
2778                 stream->out_transfer_func->sdr_ref_white_level =
2779                         update->out_transfer_func->sdr_ref_white_level;
2780                 stream->out_transfer_func->tf = update->out_transfer_func->tf;
2781                 stream->out_transfer_func->type =
2782                         update->out_transfer_func->type;
2783                 memcpy(&stream->out_transfer_func->tf_pts,
2784                        &update->out_transfer_func->tf_pts,
2785                        sizeof(struct dc_transfer_func_distributed_points));
2786         }
2787
2788         if (update->hdr_static_metadata)
2789                 stream->hdr_static_metadata = *update->hdr_static_metadata;
2790
2791         if (update->abm_level)
2792                 stream->abm_level = *update->abm_level;
2793
2794         if (update->periodic_interrupt)
2795                 stream->periodic_interrupt = *update->periodic_interrupt;
2796
2797         if (update->gamut_remap)
2798                 stream->gamut_remap_matrix = *update->gamut_remap;
2799
2800         /* Note: this being updated after mode set is currently not a use case
2801          * however if it arises OCSC would need to be reprogrammed at the
2802          * minimum
2803          */
2804         if (update->output_color_space)
2805                 stream->output_color_space = *update->output_color_space;
2806
2807         if (update->output_csc_transform)
2808                 stream->csc_color_matrix = *update->output_csc_transform;
2809
2810         if (update->vrr_infopacket)
2811                 stream->vrr_infopacket = *update->vrr_infopacket;
2812
2813         if (update->allow_freesync)
2814                 stream->allow_freesync = *update->allow_freesync;
2815
2816         if (update->vrr_active_variable)
2817                 stream->vrr_active_variable = *update->vrr_active_variable;
2818
2819         if (update->crtc_timing_adjust)
2820                 stream->adjust = *update->crtc_timing_adjust;
2821
2822         if (update->dpms_off)
2823                 stream->dpms_off = *update->dpms_off;
2824
2825         if (update->hfvsif_infopacket)
2826                 stream->hfvsif_infopacket = *update->hfvsif_infopacket;
2827
2828         if (update->vtem_infopacket)
2829                 stream->vtem_infopacket = *update->vtem_infopacket;
2830
2831         if (update->vsc_infopacket)
2832                 stream->vsc_infopacket = *update->vsc_infopacket;
2833
2834         if (update->vsp_infopacket)
2835                 stream->vsp_infopacket = *update->vsp_infopacket;
2836
2837         if (update->dither_option)
2838                 stream->dither_option = *update->dither_option;
2839
2840         if (update->pending_test_pattern)
2841                 stream->test_pattern = *update->pending_test_pattern;
2842         /* update current stream with writeback info */
2843         if (update->wb_update) {
2844                 int i;
2845
2846                 stream->num_wb_info = update->wb_update->num_wb_info;
2847                 ASSERT(stream->num_wb_info <= MAX_DWB_PIPES);
2848                 for (i = 0; i < stream->num_wb_info; i++)
2849                         stream->writeback_info[i] =
2850                                 update->wb_update->writeback_info[i];
2851         }
2852         if (update->dsc_config) {
2853                 struct dc_dsc_config old_dsc_cfg = stream->timing.dsc_cfg;
2854                 uint32_t old_dsc_enabled = stream->timing.flags.DSC;
2855                 uint32_t enable_dsc = (update->dsc_config->num_slices_h != 0 &&
2856                                        update->dsc_config->num_slices_v != 0);
2857
2858                 /* Use temporarry context for validating new DSC config */
2859                 struct dc_state *dsc_validate_context = dc_create_state(dc);
2860
2861                 if (dsc_validate_context) {
2862                         dc_resource_state_copy_construct(dc->current_state, dsc_validate_context);
2863
2864                         stream->timing.dsc_cfg = *update->dsc_config;
2865                         stream->timing.flags.DSC = enable_dsc;
2866                         if (!dc->res_pool->funcs->validate_bandwidth(dc, dsc_validate_context, true)) {
2867                                 stream->timing.dsc_cfg = old_dsc_cfg;
2868                                 stream->timing.flags.DSC = old_dsc_enabled;
2869                                 update->dsc_config = NULL;
2870                         }
2871
2872                         dc_release_state(dsc_validate_context);
2873                 } else {
2874                         DC_ERROR("Failed to allocate new validate context for DSC change\n");
2875                         update->dsc_config = NULL;
2876                 }
2877         }
2878 }
2879
2880 static bool update_planes_and_stream_state(struct dc *dc,
2881                 struct dc_surface_update *srf_updates, int surface_count,
2882                 struct dc_stream_state *stream,
2883                 struct dc_stream_update *stream_update,
2884                 enum surface_update_type *new_update_type,
2885                 struct dc_state **new_context)
2886 {
2887         struct dc_state *context;
2888         int i, j;
2889         enum surface_update_type update_type;
2890         const struct dc_stream_status *stream_status;
2891         struct dc_context *dc_ctx = dc->ctx;
2892
2893         stream_status = dc_stream_get_status(stream);
2894
2895         if (!stream_status) {
2896                 if (surface_count) /* Only an error condition if surf_count non-zero*/
2897                         ASSERT(false);
2898
2899                 return false; /* Cannot commit surface to stream that is not committed */
2900         }
2901
2902         context = dc->current_state;
2903
2904         update_type = dc_check_update_surfaces_for_stream(
2905                         dc, srf_updates, surface_count, stream_update, stream_status);
2906
2907         /* update current stream with the new updates */
2908         copy_stream_update_to_stream(dc, context, stream, stream_update);
2909
2910         /* do not perform surface update if surface has invalid dimensions
2911          * (all zero) and no scaling_info is provided
2912          */
2913         if (surface_count > 0) {
2914                 for (i = 0; i < surface_count; i++) {
2915                         if ((srf_updates[i].surface->src_rect.width == 0 ||
2916                                  srf_updates[i].surface->src_rect.height == 0 ||
2917                                  srf_updates[i].surface->dst_rect.width == 0 ||
2918                                  srf_updates[i].surface->dst_rect.height == 0) &&
2919                                 (!srf_updates[i].scaling_info ||
2920                                   srf_updates[i].scaling_info->src_rect.width == 0 ||
2921                                   srf_updates[i].scaling_info->src_rect.height == 0 ||
2922                                   srf_updates[i].scaling_info->dst_rect.width == 0 ||
2923                                   srf_updates[i].scaling_info->dst_rect.height == 0)) {
2924                                 DC_ERROR("Invalid src/dst rects in surface update!\n");
2925                                 return false;
2926                         }
2927                 }
2928         }
2929
2930         if (update_type >= update_surface_trace_level)
2931                 update_surface_trace(dc, srf_updates, surface_count);
2932
2933         if (update_type >= UPDATE_TYPE_FULL) {
2934                 struct dc_plane_state *new_planes[MAX_SURFACES] = {0};
2935
2936                 for (i = 0; i < surface_count; i++)
2937                         new_planes[i] = srf_updates[i].surface;
2938
2939                 /* initialize scratch memory for building context */
2940                 context = dc_create_state(dc);
2941                 if (context == NULL) {
2942                         DC_ERROR("Failed to allocate new validate context!\n");
2943                         return false;
2944                 }
2945
2946                 dc_resource_state_copy_construct(
2947                                 dc->current_state, context);
2948
2949                 /* For each full update, remove all existing phantom pipes first.
2950                  * Ensures that we have enough pipes for newly added MPO planes
2951                  */
2952                 if (dc->res_pool->funcs->remove_phantom_pipes)
2953                         dc->res_pool->funcs->remove_phantom_pipes(dc, context);
2954
2955                 /*remove old surfaces from context */
2956                 if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
2957
2958                         BREAK_TO_DEBUGGER();
2959                         goto fail;
2960                 }
2961
2962                 /* add surface to context */
2963                 if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
2964
2965                         BREAK_TO_DEBUGGER();
2966                         goto fail;
2967                 }
2968         }
2969
2970         /* save update parameters into surface */
2971         for (i = 0; i < surface_count; i++) {
2972                 struct dc_plane_state *surface = srf_updates[i].surface;
2973
2974                 copy_surface_update_to_plane(surface, &srf_updates[i]);
2975
2976                 if (update_type >= UPDATE_TYPE_MED) {
2977                         for (j = 0; j < dc->res_pool->pipe_count; j++) {
2978                                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2979
2980                                 if (pipe_ctx->plane_state != surface)
2981                                         continue;
2982
2983                                 resource_build_scaling_params(pipe_ctx);
2984                         }
2985                 }
2986         }
2987
2988         if (update_type == UPDATE_TYPE_FULL) {
2989                 if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
2990                         BREAK_TO_DEBUGGER();
2991                         goto fail;
2992                 }
2993         }
2994
2995         *new_context = context;
2996         *new_update_type = update_type;
2997
2998         return true;
2999
3000 fail:
3001         dc_release_state(context);
3002
3003         return false;
3004
3005 }
3006
3007 static void commit_planes_do_stream_update(struct dc *dc,
3008                 struct dc_stream_state *stream,
3009                 struct dc_stream_update *stream_update,
3010                 enum surface_update_type update_type,
3011                 struct dc_state *context)
3012 {
3013         int j;
3014
3015         // Stream updates
3016         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3017                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3018
3019                 if (!pipe_ctx->top_pipe &&  !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) {
3020
3021                         if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt)
3022                                 dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
3023
3024                         if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
3025                                         stream_update->vrr_infopacket ||
3026                                         stream_update->vsc_infopacket ||
3027                                         stream_update->vsp_infopacket ||
3028                                         stream_update->hfvsif_infopacket ||
3029                                         stream_update->vtem_infopacket) {
3030                                 resource_build_info_frame(pipe_ctx);
3031                                 dc->hwss.update_info_frame(pipe_ctx);
3032
3033                                 if (dc_is_dp_signal(pipe_ctx->stream->signal))
3034                                         dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
3035                         }
3036
3037                         if (stream_update->hdr_static_metadata &&
3038                                         stream->use_dynamic_meta &&
3039                                         dc->hwss.set_dmdata_attributes &&
3040                                         pipe_ctx->stream->dmdata_address.quad_part != 0)
3041                                 dc->hwss.set_dmdata_attributes(pipe_ctx);
3042
3043                         if (stream_update->gamut_remap)
3044                                 dc_stream_set_gamut_remap(dc, stream);
3045
3046                         if (stream_update->output_csc_transform)
3047                                 dc_stream_program_csc_matrix(dc, stream);
3048
3049                         if (stream_update->dither_option) {
3050                                 struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
3051                                 resource_build_bit_depth_reduction_params(pipe_ctx->stream,
3052                                                                         &pipe_ctx->stream->bit_depth_params);
3053                                 pipe_ctx->stream_res.opp->funcs->opp_program_fmt(pipe_ctx->stream_res.opp,
3054                                                 &stream->bit_depth_params,
3055                                                 &stream->clamping);
3056                                 while (odm_pipe) {
3057                                         odm_pipe->stream_res.opp->funcs->opp_program_fmt(odm_pipe->stream_res.opp,
3058                                                         &stream->bit_depth_params,
3059                                                         &stream->clamping);
3060                                         odm_pipe = odm_pipe->next_odm_pipe;
3061                                 }
3062                         }
3063
3064
3065                         /* Full fe update*/
3066                         if (update_type == UPDATE_TYPE_FAST)
3067                                 continue;
3068
3069                         if (stream_update->dsc_config)
3070                                 dp_update_dsc_config(pipe_ctx);
3071
3072                         if (stream_update->mst_bw_update) {
3073                                 if (stream_update->mst_bw_update->is_increase)
3074                                         dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
3075                                 else
3076                                         dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
3077                         }
3078
3079                         if (stream_update->pending_test_pattern) {
3080                                 dc_link_dp_set_test_pattern(stream->link,
3081                                         stream->test_pattern.type,
3082                                         stream->test_pattern.color_space,
3083                                         stream->test_pattern.p_link_settings,
3084                                         stream->test_pattern.p_custom_pattern,
3085                                         stream->test_pattern.cust_pattern_size);
3086                         }
3087
3088                         if (stream_update->dpms_off) {
3089                                 if (*stream_update->dpms_off) {
3090                                         core_link_disable_stream(pipe_ctx);
3091                                         /* for dpms, keep acquired resources*/
3092                                         if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
3093                                                 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
3094
3095                                         dc->optimized_required = true;
3096
3097                                 } else {
3098                                         if (get_seamless_boot_stream_count(context) == 0)
3099                                                 dc->hwss.prepare_bandwidth(dc, dc->current_state);
3100                                         core_link_enable_stream(dc->current_state, pipe_ctx);
3101                                 }
3102                         }
3103
3104                         if (stream_update->abm_level && pipe_ctx->stream_res.abm) {
3105                                 bool should_program_abm = true;
3106
3107                                 // if otg funcs defined check if blanked before programming
3108                                 if (pipe_ctx->stream_res.tg->funcs->is_blanked)
3109                                         if (pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg))
3110                                                 should_program_abm = false;
3111
3112                                 if (should_program_abm) {
3113                                         if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
3114                                                 dc->hwss.set_abm_immediate_disable(pipe_ctx);
3115                                         } else {
3116                                                 pipe_ctx->stream_res.abm->funcs->set_abm_level(
3117                                                         pipe_ctx->stream_res.abm, stream->abm_level);
3118                                         }
3119                                 }
3120                         }
3121                 }
3122         }
3123 }
3124
3125 static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream)
3126 {
3127         if ((stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1
3128                         || stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
3129                         && stream->ctx->dce_version >= DCN_VERSION_3_1)
3130                 return true;
3131
3132         return false;
3133 }
3134
3135 void dc_dmub_update_dirty_rect(struct dc *dc,
3136                                int surface_count,
3137                                struct dc_stream_state *stream,
3138                                struct dc_surface_update *srf_updates,
3139                                struct dc_state *context)
3140 {
3141         union dmub_rb_cmd cmd;
3142         struct dc_context *dc_ctx = dc->ctx;
3143         struct dmub_cmd_update_dirty_rect_data *update_dirty_rect;
3144         unsigned int i, j;
3145         unsigned int panel_inst = 0;
3146
3147         if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream))
3148                 return;
3149
3150         if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst))
3151                 return;
3152
3153         memset(&cmd, 0x0, sizeof(cmd));
3154         cmd.update_dirty_rect.header.type = DMUB_CMD__UPDATE_DIRTY_RECT;
3155         cmd.update_dirty_rect.header.sub_type = 0;
3156         cmd.update_dirty_rect.header.payload_bytes =
3157                 sizeof(cmd.update_dirty_rect) -
3158                 sizeof(cmd.update_dirty_rect.header);
3159         update_dirty_rect = &cmd.update_dirty_rect.update_dirty_rect_data;
3160         for (i = 0; i < surface_count; i++) {
3161                 struct dc_plane_state *plane_state = srf_updates[i].surface;
3162                 const struct dc_flip_addrs *flip_addr = srf_updates[i].flip_addr;
3163
3164                 if (!srf_updates[i].surface || !flip_addr)
3165                         continue;
3166                 /* Do not send in immediate flip mode */
3167                 if (srf_updates[i].surface->flip_immediate)
3168                         continue;
3169
3170                 update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count;
3171                 memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects,
3172                                 sizeof(flip_addr->dirty_rects));
3173                 for (j = 0; j < dc->res_pool->pipe_count; j++) {
3174                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3175
3176                         if (pipe_ctx->stream != stream)
3177                                 continue;
3178                         if (pipe_ctx->plane_state != plane_state)
3179                                 continue;
3180
3181                         update_dirty_rect->panel_inst = panel_inst;
3182                         update_dirty_rect->pipe_idx = j;
3183                         dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd);
3184                         dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv);
3185                 }
3186         }
3187 }
3188
3189 static void commit_planes_for_stream(struct dc *dc,
3190                 struct dc_surface_update *srf_updates,
3191                 int surface_count,
3192                 struct dc_stream_state *stream,
3193                 struct dc_stream_update *stream_update,
3194                 enum surface_update_type update_type,
3195                 struct dc_state *context)
3196 {
3197         int i, j;
3198         struct pipe_ctx *top_pipe_to_program = NULL;
3199         bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST);
3200         bool subvp_prev_use = false;
3201
3202         // Once we apply the new subvp context to hardware it won't be in the
3203         // dc->current_state anymore, so we have to cache it before we apply
3204         // the new SubVP context
3205         subvp_prev_use = false;
3206
3207
3208         dc_z10_restore(dc);
3209
3210         if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) {
3211                 /* Optimize seamless boot flag keeps clocks and watermarks high until
3212                  * first flip. After first flip, optimization is required to lower
3213                  * bandwidth. Important to note that it is expected UEFI will
3214                  * only light up a single display on POST, therefore we only expect
3215                  * one stream with seamless boot flag set.
3216                  */
3217                 if (stream->apply_seamless_boot_optimization) {
3218                         stream->apply_seamless_boot_optimization = false;
3219
3220                         if (get_seamless_boot_stream_count(context) == 0)
3221                                 dc->optimized_required = true;
3222                 }
3223         }
3224
3225         if (update_type == UPDATE_TYPE_FULL) {
3226                 dc_allow_idle_optimizations(dc, false);
3227
3228                 if (get_seamless_boot_stream_count(context) == 0)
3229                         dc->hwss.prepare_bandwidth(dc, context);
3230
3231                 if (dc->debug.enable_double_buffered_dsc_pg_support)
3232                         dc->hwss.update_dsc_pg(dc, context, false);
3233
3234                 context_clock_trace(dc, context);
3235         }
3236
3237         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3238                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3239
3240                 if (!pipe_ctx->top_pipe &&
3241                         !pipe_ctx->prev_odm_pipe &&
3242                         pipe_ctx->stream &&
3243                         pipe_ctx->stream == stream) {
3244                         top_pipe_to_program = pipe_ctx;
3245                 }
3246         }
3247
3248         for (i = 0; i < dc->res_pool->pipe_count; i++) {
3249                 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
3250
3251                 // Check old context for SubVP
3252                 subvp_prev_use |= (old_pipe->stream && old_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM);
3253                 if (subvp_prev_use)
3254                         break;
3255         }
3256
3257         if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) {
3258                 struct pipe_ctx *mpcc_pipe;
3259                 struct pipe_ctx *odm_pipe;
3260
3261                 for (mpcc_pipe = top_pipe_to_program; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe)
3262                         for (odm_pipe = mpcc_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3263                                 odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU;
3264         }
3265
3266         if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
3267                 if (top_pipe_to_program &&
3268                         top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
3269                         if (should_use_dmub_lock(stream->link)) {
3270                                 union dmub_hw_lock_flags hw_locks = { 0 };
3271                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
3272
3273                                 hw_locks.bits.lock_dig = 1;
3274                                 inst_flags.dig_inst = top_pipe_to_program->stream_res.tg->inst;
3275
3276                                 dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
3277                                                         true,
3278                                                         &hw_locks,
3279                                                         &inst_flags);
3280                         } else
3281                                 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable(
3282                                                 top_pipe_to_program->stream_res.tg);
3283                 }
3284
3285         if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
3286                 if (dc->hwss.subvp_pipe_control_lock)
3287                                 dc->hwss.subvp_pipe_control_lock(dc, context, true, should_lock_all_pipes, NULL, subvp_prev_use);
3288                 dc->hwss.interdependent_update_lock(dc, context, true);
3289
3290         } else {
3291                 if (dc->hwss.subvp_pipe_control_lock)
3292                         dc->hwss.subvp_pipe_control_lock(dc, context, true, should_lock_all_pipes, top_pipe_to_program, subvp_prev_use);
3293                 /* Lock the top pipe while updating plane addrs, since freesync requires
3294                  *  plane addr update event triggers to be synchronized.
3295                  *  top_pipe_to_program is expected to never be NULL
3296                  */
3297                 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
3298         }
3299
3300         if (update_type != UPDATE_TYPE_FAST) {
3301                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3302                         struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
3303
3304                         if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) ||
3305                                         subvp_prev_use) {
3306                                 // If old context or new context has phantom pipes, apply
3307                                 // the phantom timings now. We can't change the phantom
3308                                 // pipe configuration safely without driver acquiring
3309                                 // the DMCUB lock first.
3310                                 dc->hwss.apply_ctx_to_hw(dc, context);
3311                                 break;
3312                         }
3313                 }
3314         }
3315
3316         dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context);
3317
3318         if (update_type != UPDATE_TYPE_FAST) {
3319                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3320                         struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
3321
3322                         if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) ||
3323                                         subvp_prev_use) {
3324                                 // If old context or new context has phantom pipes, apply
3325                                 // the phantom timings now. We can't change the phantom
3326                                 // pipe configuration safely without driver acquiring
3327                                 // the DMCUB lock first.
3328                                 dc->hwss.apply_ctx_to_hw(dc, context);
3329                                 break;
3330                         }
3331                 }
3332         }
3333
3334         // Stream updates
3335         if (stream_update)
3336                 commit_planes_do_stream_update(dc, stream, stream_update, update_type, context);
3337
3338         if (surface_count == 0) {
3339                 /*
3340                  * In case of turning off screen, no need to program front end a second time.
3341                  * just return after program blank.
3342                  */
3343                 if (dc->hwss.apply_ctx_for_surface)
3344                         dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
3345                 if (dc->hwss.program_front_end_for_ctx)
3346                         dc->hwss.program_front_end_for_ctx(dc, context);
3347
3348                 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
3349                         dc->hwss.interdependent_update_lock(dc, context, false);
3350                 } else {
3351                         dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
3352                 }
3353                 dc->hwss.post_unlock_program_front_end(dc, context);
3354
3355                 if (update_type != UPDATE_TYPE_FAST)
3356                         if (dc->hwss.commit_subvp_config)
3357                                 dc->hwss.commit_subvp_config(dc, context);
3358
3359                 /* Since phantom pipe programming is moved to post_unlock_program_front_end,
3360                  * move the SubVP lock to after the phantom pipes have been setup
3361                  */
3362                 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
3363                         if (dc->hwss.subvp_pipe_control_lock)
3364                                 dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
3365                 } else {
3366                         if (dc->hwss.subvp_pipe_control_lock)
3367                                 dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
3368                 }
3369
3370                 return;
3371         }
3372
3373         if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
3374                 for (i = 0; i < surface_count; i++) {
3375                         struct dc_plane_state *plane_state = srf_updates[i].surface;
3376                         /*set logical flag for lock/unlock use*/
3377                         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3378                                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3379                                 if (!pipe_ctx->plane_state)
3380                                         continue;
3381                                 if (should_update_pipe_for_plane(context, pipe_ctx, plane_state))
3382                                         continue;
3383                                 pipe_ctx->plane_state->triplebuffer_flips = false;
3384                                 if (update_type == UPDATE_TYPE_FAST &&
3385                                         dc->hwss.program_triplebuffer != NULL &&
3386                                         !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) {
3387                                                 /*triple buffer for VUpdate  only*/
3388                                                 pipe_ctx->plane_state->triplebuffer_flips = true;
3389                                 }
3390                         }
3391                         if (update_type == UPDATE_TYPE_FULL) {
3392                                 /* force vsync flip when reconfiguring pipes to prevent underflow */
3393                                 plane_state->flip_immediate = false;
3394                         }
3395                 }
3396         }
3397
3398         // Update Type FULL, Surface updates
3399         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3400                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3401
3402                 if (!pipe_ctx->top_pipe &&
3403                         !pipe_ctx->prev_odm_pipe &&
3404                         should_update_pipe_for_stream(context, pipe_ctx, stream)) {
3405                         struct dc_stream_status *stream_status = NULL;
3406
3407                         if (!pipe_ctx->plane_state)
3408                                 continue;
3409
3410                         /* Full fe update*/
3411                         if (update_type == UPDATE_TYPE_FAST)
3412                                 continue;
3413
3414                         ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
3415
3416                         if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
3417                                 /*turn off triple buffer for full update*/
3418                                 dc->hwss.program_triplebuffer(
3419                                         dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
3420                         }
3421                         stream_status =
3422                                 stream_get_status(context, pipe_ctx->stream);
3423
3424                         if (dc->hwss.apply_ctx_for_surface)
3425                                 dc->hwss.apply_ctx_for_surface(
3426                                         dc, pipe_ctx->stream, stream_status->plane_count, context);
3427                 }
3428         }
3429         if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) {
3430                 dc->hwss.program_front_end_for_ctx(dc, context);
3431                 if (dc->debug.validate_dml_output) {
3432                         for (i = 0; i < dc->res_pool->pipe_count; i++) {
3433                                 struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i];
3434                                 if (cur_pipe->stream == NULL)
3435                                         continue;
3436
3437                                 cur_pipe->plane_res.hubp->funcs->validate_dml_output(
3438                                                 cur_pipe->plane_res.hubp, dc->ctx,
3439                                                 &context->res_ctx.pipe_ctx[i].rq_regs,
3440                                                 &context->res_ctx.pipe_ctx[i].dlg_regs,
3441                                                 &context->res_ctx.pipe_ctx[i].ttu_regs);
3442                         }
3443                 }
3444         }
3445
3446         // Update Type FAST, Surface updates
3447         if (update_type == UPDATE_TYPE_FAST) {
3448                 if (dc->hwss.set_flip_control_gsl)
3449                         for (i = 0; i < surface_count; i++) {
3450                                 struct dc_plane_state *plane_state = srf_updates[i].surface;
3451
3452                                 for (j = 0; j < dc->res_pool->pipe_count; j++) {
3453                                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3454
3455                                         if (!should_update_pipe_for_stream(context, pipe_ctx, stream))
3456                                                 continue;
3457
3458                                         if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
3459                                                 continue;
3460
3461                                         // GSL has to be used for flip immediate
3462                                         dc->hwss.set_flip_control_gsl(pipe_ctx,
3463                                                         pipe_ctx->plane_state->flip_immediate);
3464                                 }
3465                         }
3466
3467                 /* Perform requested Updates */
3468                 for (i = 0; i < surface_count; i++) {
3469                         struct dc_plane_state *plane_state = srf_updates[i].surface;
3470
3471                         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3472                                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3473
3474                                 if (!should_update_pipe_for_stream(context, pipe_ctx, stream))
3475                                         continue;
3476
3477                                 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
3478                                         continue;
3479
3480                                 /*program triple buffer after lock based on flip type*/
3481                                 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
3482                                         /*only enable triplebuffer for  fast_update*/
3483                                         dc->hwss.program_triplebuffer(
3484                                                 dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
3485                                 }
3486                                 if (pipe_ctx->plane_state->update_flags.bits.addr_update)
3487                                         dc->hwss.update_plane_addr(dc, pipe_ctx);
3488                         }
3489                 }
3490
3491         }
3492
3493         if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
3494                 dc->hwss.interdependent_update_lock(dc, context, false);
3495         } else {
3496                 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
3497         }
3498
3499         if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
3500                 if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
3501                         top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
3502                                 top_pipe_to_program->stream_res.tg,
3503                                 CRTC_STATE_VACTIVE);
3504                         top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
3505                                 top_pipe_to_program->stream_res.tg,
3506                                 CRTC_STATE_VBLANK);
3507                         top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
3508                                 top_pipe_to_program->stream_res.tg,
3509                                 CRTC_STATE_VACTIVE);
3510
3511                         if (should_use_dmub_lock(stream->link)) {
3512                                 union dmub_hw_lock_flags hw_locks = { 0 };
3513                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
3514
3515                                 hw_locks.bits.lock_dig = 1;
3516                                 inst_flags.dig_inst = top_pipe_to_program->stream_res.tg->inst;
3517
3518                                 dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
3519                                                         false,
3520                                                         &hw_locks,
3521                                                         &inst_flags);
3522                         } else
3523                                 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_disable(
3524                                         top_pipe_to_program->stream_res.tg);
3525                 }
3526
3527         if (update_type != UPDATE_TYPE_FAST)
3528                 dc->hwss.post_unlock_program_front_end(dc, context);
3529         if (update_type != UPDATE_TYPE_FAST)
3530                 if (dc->hwss.commit_subvp_config)
3531                         dc->hwss.commit_subvp_config(dc, context);
3532
3533         if (update_type != UPDATE_TYPE_FAST)
3534                 if (dc->hwss.commit_subvp_config)
3535                         dc->hwss.commit_subvp_config(dc, context);
3536
3537         /* Since phantom pipe programming is moved to post_unlock_program_front_end,
3538          * move the SubVP lock to after the phantom pipes have been setup
3539          */
3540         if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
3541                 if (dc->hwss.subvp_pipe_control_lock)
3542                         dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
3543         } else {
3544                 if (dc->hwss.subvp_pipe_control_lock)
3545                         dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, top_pipe_to_program, subvp_prev_use);
3546         }
3547
3548         // Fire manual trigger only when bottom plane is flipped
3549         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3550                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
3551
3552                 if (!pipe_ctx->plane_state)
3553                         continue;
3554
3555                 if (pipe_ctx->bottom_pipe || pipe_ctx->next_odm_pipe ||
3556                                 !pipe_ctx->stream || !should_update_pipe_for_stream(context, pipe_ctx, stream) ||
3557                                 !pipe_ctx->plane_state->update_flags.bits.addr_update ||
3558                                 pipe_ctx->plane_state->skip_manual_trigger)
3559                         continue;
3560
3561                 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger)
3562                         pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
3563         }
3564 }
3565
3566 /* Determines if the incoming context requires a applying transition state with unnecessary
3567  * pipe splitting and ODM disabled, due to hardware limitations. In a case where
3568  * the OPP associated with an MPCC might change due to plane additions, this function
3569  * returns true.
3570  */
3571 static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
3572                 struct dc_stream_state *stream,
3573                 int surface_count,
3574                 bool *is_plane_addition)
3575 {
3576
3577         struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream);
3578         bool force_minimal_pipe_splitting = false;
3579         uint32_t i;
3580
3581         *is_plane_addition = false;
3582
3583         if (cur_stream_status &&
3584                         dc->current_state->stream_count > 0 &&
3585                         dc->debug.pipe_split_policy != MPC_SPLIT_AVOID) {
3586                 /* determine if minimal transition is required due to MPC*/
3587                 if (surface_count > 0) {
3588                         if (cur_stream_status->plane_count > surface_count) {
3589                                 force_minimal_pipe_splitting = true;
3590                         } else if (cur_stream_status->plane_count < surface_count) {
3591                                 force_minimal_pipe_splitting = true;
3592                                 *is_plane_addition = true;
3593                         }
3594                 }
3595         }
3596
3597         if (cur_stream_status &&
3598                         dc->current_state->stream_count == 1 &&
3599                         dc->debug.enable_single_display_2to1_odm_policy) {
3600                 /* determine if minimal transition is required due to dynamic ODM*/
3601                 if (surface_count > 0) {
3602                         if (cur_stream_status->plane_count > 2 && cur_stream_status->plane_count > surface_count) {
3603                                 force_minimal_pipe_splitting = true;
3604                         } else if (surface_count > 2 && cur_stream_status->plane_count < surface_count) {
3605                                 force_minimal_pipe_splitting = true;
3606                                 *is_plane_addition = true;
3607                         }
3608                 }
3609         }
3610
3611         /* For SubVP pipe split case when adding MPO video
3612          * we need to add a minimal transition. In this case
3613          * there will be 2 streams (1 main stream, 1 phantom
3614          * stream).
3615          */
3616         if (cur_stream_status &&
3617                         dc->current_state->stream_count == 2 &&
3618                         stream->mall_stream_config.type == SUBVP_MAIN) {
3619                 bool is_pipe_split = false;
3620
3621                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3622                         if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream &&
3623                                         (dc->current_state->res_ctx.pipe_ctx[i].bottom_pipe ||
3624                                         dc->current_state->res_ctx.pipe_ctx[i].next_odm_pipe)) {
3625                                 is_pipe_split = true;
3626                                 break;
3627                         }
3628                 }
3629
3630                 /* determine if minimal transition is required due to SubVP*/
3631                 if (surface_count > 0 && is_pipe_split) {
3632                         if (cur_stream_status->plane_count > surface_count) {
3633                                 force_minimal_pipe_splitting = true;
3634                         } else if (cur_stream_status->plane_count < surface_count) {
3635                                 force_minimal_pipe_splitting = true;
3636                                 *is_plane_addition = true;
3637                         }
3638                 }
3639         }
3640
3641         return force_minimal_pipe_splitting;
3642 }
3643
3644 static bool commit_minimal_transition_state(struct dc *dc,
3645                 struct dc_state *transition_base_context)
3646 {
3647         struct dc_state *transition_context = dc_create_state(dc);
3648         enum pipe_split_policy tmp_mpc_policy;
3649         bool temp_dynamic_odm_policy;
3650         bool temp_subvp_policy;
3651         enum dc_status ret = DC_ERROR_UNEXPECTED;
3652         unsigned int i, j;
3653
3654         if (!transition_context)
3655                 return false;
3656
3657         if (!dc->config.is_vmin_only_asic) {
3658                 tmp_mpc_policy = dc->debug.pipe_split_policy;
3659                 dc->debug.pipe_split_policy = MPC_SPLIT_AVOID;
3660         }
3661
3662         temp_dynamic_odm_policy = dc->debug.enable_single_display_2to1_odm_policy;
3663         dc->debug.enable_single_display_2to1_odm_policy = false;
3664
3665         temp_subvp_policy = dc->debug.force_disable_subvp;
3666         dc->debug.force_disable_subvp = true;
3667
3668         dc_resource_state_copy_construct(transition_base_context, transition_context);
3669
3670         //commit minimal state
3671         if (dc->res_pool->funcs->validate_bandwidth(dc, transition_context, false)) {
3672                 for (i = 0; i < transition_context->stream_count; i++) {
3673                         struct dc_stream_status *stream_status = &transition_context->stream_status[i];
3674
3675                         for (j = 0; j < stream_status->plane_count; j++) {
3676                                 struct dc_plane_state *plane_state = stream_status->plane_states[j];
3677
3678                                 /* force vsync flip when reconfiguring pipes to prevent underflow
3679                                  * and corruption
3680                                  */
3681                                 plane_state->flip_immediate = false;
3682                         }
3683                 }
3684
3685                 ret = dc_commit_state_no_check(dc, transition_context);
3686         }
3687
3688         /*always release as dc_commit_state_no_check retains in good case*/
3689         dc_release_state(transition_context);
3690
3691         /*restore previous pipe split and odm policy*/
3692         if (!dc->config.is_vmin_only_asic)
3693                 dc->debug.pipe_split_policy = tmp_mpc_policy;
3694
3695         dc->debug.enable_single_display_2to1_odm_policy = temp_dynamic_odm_policy;
3696         dc->debug.force_disable_subvp = temp_subvp_policy;
3697
3698         if (ret != DC_OK) {
3699                 /*this should never happen*/
3700                 BREAK_TO_DEBUGGER();
3701                 return false;
3702         }
3703
3704         /*force full surface update*/
3705         for (i = 0; i < dc->current_state->stream_count; i++) {
3706                 for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) {
3707                         dc->current_state->stream_status[i].plane_states[j]->update_flags.raw = 0xFFFFFFFF;
3708                 }
3709         }
3710
3711         return true;
3712 }
3713
3714 bool dc_update_planes_and_stream(struct dc *dc,
3715                 struct dc_surface_update *srf_updates, int surface_count,
3716                 struct dc_stream_state *stream,
3717                 struct dc_stream_update *stream_update)
3718 {
3719         struct dc_state *context;
3720         enum surface_update_type update_type;
3721         int i;
3722
3723         /* In cases where MPO and split or ODM are used transitions can
3724          * cause underflow. Apply stream configuration with minimal pipe
3725          * split first to avoid unsupported transitions for active pipes.
3726          */
3727         bool force_minimal_pipe_splitting;
3728         bool is_plane_addition;
3729
3730         force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes(
3731                         dc,
3732                         stream,
3733                         surface_count,
3734                         &is_plane_addition);
3735
3736         /* on plane addition, minimal state is the current one */
3737         if (force_minimal_pipe_splitting && is_plane_addition &&
3738                 !commit_minimal_transition_state(dc, dc->current_state))
3739                                 return false;
3740
3741         if (!update_planes_and_stream_state(
3742                         dc,
3743                         srf_updates,
3744                         surface_count,
3745                         stream,
3746                         stream_update,
3747                         &update_type,
3748                         &context))
3749                 return false;
3750
3751         /* on plane removal, minimal state is the new one */
3752         if (force_minimal_pipe_splitting && !is_plane_addition) {
3753                 if (!commit_minimal_transition_state(dc, context)) {
3754                         dc_release_state(context);
3755                         return false;
3756                 }
3757
3758                 update_type = UPDATE_TYPE_FULL;
3759         }
3760
3761         commit_planes_for_stream(
3762                         dc,
3763                         srf_updates,
3764                         surface_count,
3765                         stream,
3766                         stream_update,
3767                         update_type,
3768                         context);
3769
3770         if (dc->current_state != context) {
3771
3772                 /* Since memory free requires elevated IRQL, an interrupt
3773                  * request is generated by mem free. If this happens
3774                  * between freeing and reassigning the context, our vsync
3775                  * interrupt will call into dc and cause a memory
3776                  * corruption BSOD. Hence, we first reassign the context,
3777                  * then free the old context.
3778                  */
3779
3780                 struct dc_state *old = dc->current_state;
3781
3782                 dc->current_state = context;
3783                 dc_release_state(old);
3784
3785                 // clear any forced full updates
3786                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3787                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
3788
3789                         if (pipe_ctx->plane_state && pipe_ctx->stream == stream)
3790                                 pipe_ctx->plane_state->force_full_update = false;
3791                 }
3792         }
3793         return true;
3794 }
3795
3796 void dc_commit_updates_for_stream(struct dc *dc,
3797                 struct dc_surface_update *srf_updates,
3798                 int surface_count,
3799                 struct dc_stream_state *stream,
3800                 struct dc_stream_update *stream_update,
3801                 struct dc_state *state)
3802 {
3803         const struct dc_stream_status *stream_status;
3804         enum surface_update_type update_type;
3805         struct dc_state *context;
3806         struct dc_context *dc_ctx = dc->ctx;
3807         int i, j;
3808
3809         stream_status = dc_stream_get_status(stream);
3810         context = dc->current_state;
3811
3812         update_type = dc_check_update_surfaces_for_stream(
3813                                 dc, srf_updates, surface_count, stream_update, stream_status);
3814
3815         if (update_type >= update_surface_trace_level)
3816                 update_surface_trace(dc, srf_updates, surface_count);
3817
3818
3819         if (update_type >= UPDATE_TYPE_FULL) {
3820
3821                 /* initialize scratch memory for building context */
3822                 context = dc_create_state(dc);
3823                 if (context == NULL) {
3824                         DC_ERROR("Failed to allocate new validate context!\n");
3825                         return;
3826                 }
3827
3828                 dc_resource_state_copy_construct(state, context);
3829
3830                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3831                         struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
3832                         struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
3833
3834                         if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
3835                                 new_pipe->plane_state->force_full_update = true;
3836                 }
3837         } else if (update_type == UPDATE_TYPE_FAST && dc_ctx->dce_version >= DCE_VERSION_MAX) {
3838                 /*
3839                  * Previous frame finished and HW is ready for optimization.
3840                  *
3841                  * Only relevant for DCN behavior where we can guarantee the optimization
3842                  * is safe to apply - retain the legacy behavior for DCE.
3843                  */
3844                 dc_post_update_surfaces_to_stream(dc);
3845         }
3846
3847
3848         for (i = 0; i < surface_count; i++) {
3849                 struct dc_plane_state *surface = srf_updates[i].surface;
3850
3851                 copy_surface_update_to_plane(surface, &srf_updates[i]);
3852
3853                 if (update_type >= UPDATE_TYPE_MED) {
3854                         for (j = 0; j < dc->res_pool->pipe_count; j++) {
3855                                 struct pipe_ctx *pipe_ctx =
3856                                         &context->res_ctx.pipe_ctx[j];
3857
3858                                 if (pipe_ctx->plane_state != surface)
3859                                         continue;
3860
3861                                 resource_build_scaling_params(pipe_ctx);
3862                         }
3863                 }
3864         }
3865
3866         copy_stream_update_to_stream(dc, context, stream, stream_update);
3867
3868         if (update_type >= UPDATE_TYPE_FULL) {
3869                 if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
3870                         DC_ERROR("Mode validation failed for stream update!\n");
3871                         dc_release_state(context);
3872                         return;
3873                 }
3874         }
3875
3876         TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
3877
3878         commit_planes_for_stream(
3879                                 dc,
3880                                 srf_updates,
3881                                 surface_count,
3882                                 stream,
3883                                 stream_update,
3884                                 update_type,
3885                                 context);
3886         /*update current_State*/
3887         if (dc->current_state != context) {
3888
3889                 struct dc_state *old = dc->current_state;
3890
3891                 dc->current_state = context;
3892                 dc_release_state(old);
3893
3894                 for (i = 0; i < dc->res_pool->pipe_count; i++) {
3895                         struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
3896
3897                         if (pipe_ctx->plane_state && pipe_ctx->stream == stream)
3898                                 pipe_ctx->plane_state->force_full_update = false;
3899                 }
3900         }
3901
3902         /* Legacy optimization path for DCE. */
3903         if (update_type >= UPDATE_TYPE_FULL && dc_ctx->dce_version < DCE_VERSION_MAX) {
3904                 dc_post_update_surfaces_to_stream(dc);
3905                 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
3906         }
3907
3908         return;
3909
3910 }
3911
3912 uint8_t dc_get_current_stream_count(struct dc *dc)
3913 {
3914         return dc->current_state->stream_count;
3915 }
3916
3917 struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
3918 {
3919         if (i < dc->current_state->stream_count)
3920                 return dc->current_state->streams[i];
3921         return NULL;
3922 }
3923
3924 enum dc_irq_source dc_interrupt_to_irq_source(
3925                 struct dc *dc,
3926                 uint32_t src_id,
3927                 uint32_t ext_id)
3928 {
3929         return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
3930 }
3931
3932 /*
3933  * dc_interrupt_set() - Enable/disable an AMD hw interrupt source
3934  */
3935 bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
3936 {
3937
3938         if (dc == NULL)
3939                 return false;
3940
3941         return dal_irq_service_set(dc->res_pool->irqs, src, enable);
3942 }
3943
3944 void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
3945 {
3946         dal_irq_service_ack(dc->res_pool->irqs, src);
3947 }
3948
3949 void dc_power_down_on_boot(struct dc *dc)
3950 {
3951         if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW &&
3952                         dc->hwss.power_down_on_boot)
3953                 dc->hwss.power_down_on_boot(dc);
3954 }
3955
3956 void dc_set_power_state(
3957         struct dc *dc,
3958         enum dc_acpi_cm_power_state power_state)
3959 {
3960         struct kref refcount;
3961         struct display_mode_lib *dml;
3962
3963         if (!dc->current_state)
3964                 return;
3965
3966         switch (power_state) {
3967         case DC_ACPI_CM_POWER_STATE_D0:
3968                 dc_resource_state_construct(dc, dc->current_state);
3969
3970                 dc_z10_restore(dc);
3971
3972                 if (dc->ctx->dmub_srv)
3973                         dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv);
3974
3975                 dc->hwss.init_hw(dc);
3976
3977                 if (dc->hwss.init_sys_ctx != NULL &&
3978                         dc->vm_pa_config.valid) {
3979                         dc->hwss.init_sys_ctx(dc->hwseq, dc, &dc->vm_pa_config);
3980                 }
3981
3982                 break;
3983         default:
3984                 ASSERT(dc->current_state->stream_count == 0);
3985                 /* Zero out the current context so that on resume we start with
3986                  * clean state, and dc hw programming optimizations will not
3987                  * cause any trouble.
3988                  */
3989                 dml = kzalloc(sizeof(struct display_mode_lib),
3990                                 GFP_KERNEL);
3991
3992                 ASSERT(dml);
3993                 if (!dml)
3994                         return;
3995
3996                 /* Preserve refcount */
3997                 refcount = dc->current_state->refcount;
3998                 /* Preserve display mode lib */
3999                 memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib));
4000
4001                 dc_resource_state_destruct(dc->current_state);
4002                 memset(dc->current_state, 0,
4003                                 sizeof(*dc->current_state));
4004
4005                 dc->current_state->refcount = refcount;
4006                 dc->current_state->bw_ctx.dml = *dml;
4007
4008                 kfree(dml);
4009
4010                 break;
4011         }
4012 }
4013
4014 void dc_resume(struct dc *dc)
4015 {
4016         uint32_t i;
4017
4018         for (i = 0; i < dc->link_count; i++)
4019                 core_link_resume(dc->links[i]);
4020 }
4021
4022 bool dc_is_dmcu_initialized(struct dc *dc)
4023 {
4024         struct dmcu *dmcu = dc->res_pool->dmcu;
4025
4026         if (dmcu)
4027                 return dmcu->funcs->is_dmcu_initialized(dmcu);
4028         return false;
4029 }
4030
4031 bool dc_is_oem_i2c_device_present(
4032         struct dc *dc,
4033         size_t slave_address)
4034 {
4035         if (dc->res_pool->oem_device)
4036                 return dce_i2c_oem_device_present(
4037                         dc->res_pool,
4038                         dc->res_pool->oem_device,
4039                         slave_address);
4040
4041         return false;
4042 }
4043
4044 bool dc_submit_i2c(
4045                 struct dc *dc,
4046                 uint32_t link_index,
4047                 struct i2c_command *cmd)
4048 {
4049
4050         struct dc_link *link = dc->links[link_index];
4051         struct ddc_service *ddc = link->ddc;
4052         return dce_i2c_submit_command(
4053                 dc->res_pool,
4054                 ddc->ddc_pin,
4055                 cmd);
4056 }
4057
4058 bool dc_submit_i2c_oem(
4059                 struct dc *dc,
4060                 struct i2c_command *cmd)
4061 {
4062         struct ddc_service *ddc = dc->res_pool->oem_device;
4063         if (ddc)
4064                 return dce_i2c_submit_command(
4065                         dc->res_pool,
4066                         ddc->ddc_pin,
4067                         cmd);
4068
4069         return false;
4070 }
4071
4072 static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
4073 {
4074         if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
4075                 BREAK_TO_DEBUGGER();
4076                 return false;
4077         }
4078
4079         dc_sink_retain(sink);
4080
4081         dc_link->remote_sinks[dc_link->sink_count] = sink;
4082         dc_link->sink_count++;
4083
4084         return true;
4085 }
4086
4087 /*
4088  * dc_link_add_remote_sink() - Create a sink and attach it to an existing link
4089  *
4090  * EDID length is in bytes
4091  */
4092 struct dc_sink *dc_link_add_remote_sink(
4093                 struct dc_link *link,
4094                 const uint8_t *edid,
4095                 int len,
4096                 struct dc_sink_init_data *init_data)
4097 {
4098         struct dc_sink *dc_sink;
4099         enum dc_edid_status edid_status;
4100
4101         if (len > DC_MAX_EDID_BUFFER_SIZE) {
4102                 dm_error("Max EDID buffer size breached!\n");
4103                 return NULL;
4104         }
4105
4106         if (!init_data) {
4107                 BREAK_TO_DEBUGGER();
4108                 return NULL;
4109         }
4110
4111         if (!init_data->link) {
4112                 BREAK_TO_DEBUGGER();
4113                 return NULL;
4114         }
4115
4116         dc_sink = dc_sink_create(init_data);
4117
4118         if (!dc_sink)
4119                 return NULL;
4120
4121         memmove(dc_sink->dc_edid.raw_edid, edid, len);
4122         dc_sink->dc_edid.length = len;
4123
4124         if (!link_add_remote_sink_helper(
4125                         link,
4126                         dc_sink))
4127                 goto fail_add_sink;
4128
4129         edid_status = dm_helpers_parse_edid_caps(
4130                         link,
4131                         &dc_sink->dc_edid,
4132                         &dc_sink->edid_caps);
4133
4134         /*
4135          * Treat device as no EDID device if EDID
4136          * parsing fails
4137          */
4138         if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
4139                 dc_sink->dc_edid.length = 0;
4140                 dm_error("Bad EDID, status%d!\n", edid_status);
4141         }
4142
4143         return dc_sink;
4144
4145 fail_add_sink:
4146         dc_sink_release(dc_sink);
4147         return NULL;
4148 }
4149
4150 /*
4151  * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link
4152  *
4153  * Note that this just removes the struct dc_sink - it doesn't
4154  * program hardware or alter other members of dc_link
4155  */
4156 void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
4157 {
4158         int i;
4159
4160         if (!link->sink_count) {
4161                 BREAK_TO_DEBUGGER();
4162                 return;
4163         }
4164
4165         for (i = 0; i < link->sink_count; i++) {
4166                 if (link->remote_sinks[i] == sink) {
4167                         dc_sink_release(sink);
4168                         link->remote_sinks[i] = NULL;
4169
4170                         /* shrink array to remove empty place */
4171                         while (i < link->sink_count - 1) {
4172                                 link->remote_sinks[i] = link->remote_sinks[i+1];
4173                                 i++;
4174                         }
4175                         link->remote_sinks[i] = NULL;
4176                         link->sink_count--;
4177                         return;
4178                 }
4179         }
4180 }
4181
4182 void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
4183 {
4184         info->displayClock                              = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
4185         info->engineClock                               = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz;
4186         info->memoryClock                               = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz;
4187         info->maxSupportedDppClock              = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz;
4188         info->dppClock                                  = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz;
4189         info->socClock                                  = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz;
4190         info->dcfClockDeepSleep                 = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz;
4191         info->fClock                                    = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz;
4192         info->phyClock                                  = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz;
4193 }
4194 enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping)
4195 {
4196         if (dc->hwss.set_clock)
4197                 return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping);
4198         return DC_ERROR_UNEXPECTED;
4199 }
4200 void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg)
4201 {
4202         if (dc->hwss.get_clock)
4203                 dc->hwss.get_clock(dc, clock_type, clock_cfg);
4204 }
4205
4206 /* enable/disable eDP PSR without specify stream for eDP */
4207 bool dc_set_psr_allow_active(struct dc *dc, bool enable)
4208 {
4209         int i;
4210         bool allow_active;
4211
4212         for (i = 0; i < dc->current_state->stream_count ; i++) {
4213                 struct dc_link *link;
4214                 struct dc_stream_state *stream = dc->current_state->streams[i];
4215
4216                 link = stream->link;
4217                 if (!link)
4218                         continue;
4219
4220                 if (link->psr_settings.psr_feature_enabled) {
4221                         if (enable && !link->psr_settings.psr_allow_active) {
4222                                 allow_active = true;
4223                                 if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL))
4224                                         return false;
4225                         } else if (!enable && link->psr_settings.psr_allow_active) {
4226                                 allow_active = false;
4227                                 if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL))
4228                                         return false;
4229                         }
4230                 }
4231         }
4232
4233         return true;
4234 }
4235
4236 void dc_allow_idle_optimizations(struct dc *dc, bool allow)
4237 {
4238         if (dc->debug.disable_idle_power_optimizations)
4239                 return;
4240
4241         if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
4242                 if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr))
4243                         return;
4244
4245         if (allow == dc->idle_optimizations_allowed)
4246                 return;
4247
4248         if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations(dc, allow))
4249                 dc->idle_optimizations_allowed = allow;
4250 }
4251
4252 /* set min and max memory clock to lowest and highest DPM level, respectively */
4253 void dc_unlock_memory_clock_frequency(struct dc *dc)
4254 {
4255         if (dc->clk_mgr->funcs->set_hard_min_memclk)
4256                 dc->clk_mgr->funcs->set_hard_min_memclk(dc->clk_mgr, false);
4257
4258         if (dc->clk_mgr->funcs->set_hard_max_memclk)
4259                 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
4260 }
4261
4262 /* set min memory clock to the min required for current mode, max to maxDPM */
4263 void dc_lock_memory_clock_frequency(struct dc *dc)
4264 {
4265         if (dc->clk_mgr->funcs->get_memclk_states_from_smu)
4266                 dc->clk_mgr->funcs->get_memclk_states_from_smu(dc->clk_mgr);
4267
4268         if (dc->clk_mgr->funcs->set_hard_min_memclk)
4269                 dc->clk_mgr->funcs->set_hard_min_memclk(dc->clk_mgr, true);
4270
4271         if (dc->clk_mgr->funcs->set_hard_max_memclk)
4272                 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
4273 }
4274
4275 static void blank_and_force_memclk(struct dc *dc, bool apply, unsigned int memclk_mhz)
4276 {
4277         struct dc_state *context = dc->current_state;
4278         struct hubp *hubp;
4279         struct pipe_ctx *pipe;
4280         int i;
4281
4282         for (i = 0; i < dc->res_pool->pipe_count; i++) {
4283                 pipe = &context->res_ctx.pipe_ctx[i];
4284
4285                 if (pipe->stream != NULL) {
4286                         dc->hwss.disable_pixel_data(dc, pipe, true);
4287
4288                         // wait for double buffer
4289                         pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VACTIVE);
4290                         pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VBLANK);
4291                         pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VACTIVE);
4292
4293                         hubp = pipe->plane_res.hubp;
4294                         hubp->funcs->set_blank_regs(hubp, true);
4295                 }
4296         }
4297
4298         dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, memclk_mhz);
4299         dc->clk_mgr->funcs->set_min_memclk(dc->clk_mgr, memclk_mhz);
4300
4301         for (i = 0; i < dc->res_pool->pipe_count; i++) {
4302                 pipe = &context->res_ctx.pipe_ctx[i];
4303
4304                 if (pipe->stream != NULL) {
4305                         dc->hwss.disable_pixel_data(dc, pipe, false);
4306
4307                         hubp = pipe->plane_res.hubp;
4308                         hubp->funcs->set_blank_regs(hubp, false);
4309                 }
4310         }
4311 }
4312
4313
4314 /**
4315  * dc_enable_dcmode_clk_limit() - lower clocks in dc (battery) mode
4316  * @dc: pointer to dc of the dm calling this
4317  * @enable: True = transition to DC mode, false = transition back to AC mode
4318  *
4319  * Some SoCs define additional clock limits when in DC mode, DM should
4320  * invoke this function when the platform undergoes a power source transition
4321  * so DC can apply/unapply the limit. This interface may be disruptive to
4322  * the onscreen content.
4323  *
4324  * Context: Triggered by OS through DM interface, or manually by escape calls.
4325  * Need to hold a dclock when doing so.
4326  *
4327  * Return: none (void function)
4328  *
4329  */
4330 void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable)
4331 {
4332         uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev;
4333         unsigned int softMax, maxDPM, funcMin;
4334         bool p_state_change_support;
4335
4336         if (!ASICREV_IS_BEIGE_GOBY_P(hw_internal_rev))
4337                 return;
4338
4339         softMax = dc->clk_mgr->bw_params->dc_mode_softmax_memclk;
4340         maxDPM = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz;
4341         funcMin = (dc->clk_mgr->clks.dramclk_khz + 999) / 1000;
4342         p_state_change_support = dc->clk_mgr->clks.p_state_change_support;
4343
4344         if (enable && !dc->clk_mgr->dc_mode_softmax_enabled) {
4345                 if (p_state_change_support) {
4346                         if (funcMin <= softMax)
4347                                 dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, softMax);
4348                         // else: No-Op
4349                 } else {
4350                         if (funcMin <= softMax)
4351                                 blank_and_force_memclk(dc, true, softMax);
4352                         // else: No-Op
4353                 }
4354         } else if (!enable && dc->clk_mgr->dc_mode_softmax_enabled) {
4355                 if (p_state_change_support) {
4356                         if (funcMin <= softMax)
4357                                 dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, maxDPM);
4358                         // else: No-Op
4359                 } else {
4360                         if (funcMin <= softMax)
4361                                 blank_and_force_memclk(dc, true, maxDPM);
4362                         // else: No-Op
4363                 }
4364         }
4365         dc->clk_mgr->dc_mode_softmax_enabled = enable;
4366 }
4367 bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane,
4368                 struct dc_cursor_attributes *cursor_attr)
4369 {
4370         if (dc->hwss.does_plane_fit_in_mall && dc->hwss.does_plane_fit_in_mall(dc, plane, cursor_attr))
4371                 return true;
4372         return false;
4373 }
4374
4375 /* cleanup on driver unload */
4376 void dc_hardware_release(struct dc *dc)
4377 {
4378         dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(dc);
4379
4380         if (dc->hwss.hardware_release)
4381                 dc->hwss.hardware_release(dc);
4382 }
4383
4384 void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
4385 {
4386         if (dc->current_state)
4387                 dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching_shut_down = true;
4388 }
4389
4390 /*
4391  *****************************************************************************
4392  * Function: dc_is_dmub_outbox_supported -
4393  *
4394  * @brief
4395  *      Checks whether DMUB FW supports outbox notifications, if supported
4396  *              DM should register outbox interrupt prior to actually enabling interrupts
4397  *              via dc_enable_dmub_outbox
4398  *
4399  *  @param
4400  *              [in] dc: dc structure
4401  *
4402  *  @return
4403  *              True if DMUB FW supports outbox notifications, False otherwise
4404  *****************************************************************************
4405  */
4406 bool dc_is_dmub_outbox_supported(struct dc *dc)
4407 {
4408         /* DCN31 B0 USB4 DPIA needs dmub notifications for interrupts */
4409         if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
4410             dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 &&
4411             !dc->debug.dpia_debug.bits.disable_dpia)
4412                 return true;
4413
4414         if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_1 &&
4415             !dc->debug.dpia_debug.bits.disable_dpia)
4416                 return true;
4417
4418         /* dmub aux needs dmub notifications to be enabled */
4419         return dc->debug.enable_dmub_aux_for_legacy_ddc;
4420 }
4421
4422 /*
4423  *****************************************************************************
4424  *  Function: dc_enable_dmub_notifications
4425  *
4426  *  @brief
4427  *              Calls dc_is_dmub_outbox_supported to check if dmub fw supports outbox
4428  *              notifications. All DMs shall switch to dc_is_dmub_outbox_supported.
4429  *              This API shall be removed after switching.
4430  *
4431  *  @param
4432  *              [in] dc: dc structure
4433  *
4434  *  @return
4435  *              True if DMUB FW supports outbox notifications, False otherwise
4436  *****************************************************************************
4437  */
4438 bool dc_enable_dmub_notifications(struct dc *dc)
4439 {
4440         return dc_is_dmub_outbox_supported(dc);
4441 }
4442
4443 /**
4444  *****************************************************************************
4445  *  Function: dc_enable_dmub_outbox
4446  *
4447  *  @brief
4448  *              Enables DMUB unsolicited notifications to x86 via outbox
4449  *
4450  *  @param
4451  *              [in] dc: dc structure
4452  *
4453  *  @return
4454  *              None
4455  *****************************************************************************
4456  */
4457 void dc_enable_dmub_outbox(struct dc *dc)
4458 {
4459         struct dc_context *dc_ctx = dc->ctx;
4460
4461         dmub_enable_outbox_notification(dc_ctx->dmub_srv);
4462         DC_LOG_DC("%s: dmub outbox notifications enabled\n", __func__);
4463 }
4464
4465 /**
4466  * dc_process_dmub_aux_transfer_async - Submits aux command to dmub via inbox message
4467  *                                      Sets port index appropriately for legacy DDC
4468  * @dc: dc structure
4469  * @link_index: link index
4470  * @payload: aux payload
4471  *
4472  * Returns: True if successful, False if failure
4473  */
4474 bool dc_process_dmub_aux_transfer_async(struct dc *dc,
4475                                 uint32_t link_index,
4476                                 struct aux_payload *payload)
4477 {
4478         uint8_t action;
4479         union dmub_rb_cmd cmd = {0};
4480         struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
4481
4482         ASSERT(payload->length <= 16);
4483
4484         cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
4485         cmd.dp_aux_access.header.payload_bytes = 0;
4486         /* For dpia, ddc_pin is set to NULL */
4487         if (!dc->links[link_index]->ddc->ddc_pin)
4488                 cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_DPIA;
4489         else
4490                 cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
4491
4492         cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst;
4493         cmd.dp_aux_access.aux_control.sw_crc_enabled = 0;
4494         cmd.dp_aux_access.aux_control.timeout = 0;
4495         cmd.dp_aux_access.aux_control.dpaux.address = payload->address;
4496         cmd.dp_aux_access.aux_control.dpaux.is_i2c_over_aux = payload->i2c_over_aux;
4497         cmd.dp_aux_access.aux_control.dpaux.length = payload->length;
4498
4499         /* set aux action */
4500         if (payload->i2c_over_aux) {
4501                 if (payload->write) {
4502                         if (payload->mot)
4503                                 action = DP_AUX_REQ_ACTION_I2C_WRITE_MOT;
4504                         else
4505                                 action = DP_AUX_REQ_ACTION_I2C_WRITE;
4506                 } else {
4507                         if (payload->mot)
4508                                 action = DP_AUX_REQ_ACTION_I2C_READ_MOT;
4509                         else
4510                                 action = DP_AUX_REQ_ACTION_I2C_READ;
4511                         }
4512         } else {
4513                 if (payload->write)
4514                         action = DP_AUX_REQ_ACTION_DPCD_WRITE;
4515                 else
4516                         action = DP_AUX_REQ_ACTION_DPCD_READ;
4517         }
4518
4519         cmd.dp_aux_access.aux_control.dpaux.action = action;
4520
4521         if (payload->length && payload->write) {
4522                 memcpy(cmd.dp_aux_access.aux_control.dpaux.data,
4523                         payload->data,
4524                         payload->length
4525                         );
4526         }
4527
4528         dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
4529         dc_dmub_srv_cmd_execute(dmub_srv);
4530         dc_dmub_srv_wait_idle(dmub_srv);
4531
4532         return true;
4533 }
4534
4535 uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
4536                                             uint8_t dpia_port_index)
4537 {
4538         uint8_t index, link_index = 0xFF;
4539
4540         for (index = 0; index < dc->link_count; index++) {
4541                 /* ddc_hw_inst has dpia port index for dpia links
4542                  * and ddc instance for legacy links
4543                  */
4544                 if (!dc->links[index]->ddc->ddc_pin) {
4545                         if (dc->links[index]->ddc_hw_inst == dpia_port_index) {
4546                                 link_index = index;
4547                                 break;
4548                         }
4549                 }
4550         }
4551         ASSERT(link_index != 0xFF);
4552         return link_index;
4553 }
4554
4555 /**
4556  *****************************************************************************
4557  *  Function: dc_process_dmub_set_config_async
4558  *
4559  *  @brief
4560  *              Submits set_config command to dmub via inbox message
4561  *
4562  *  @param
4563  *              [in] dc: dc structure
4564  *              [in] link_index: link index
4565  *              [in] payload: aux payload
4566  *              [out] notify: set_config immediate reply
4567  *
4568  *  @return
4569  *              True if successful, False if failure
4570  *****************************************************************************
4571  */
4572 bool dc_process_dmub_set_config_async(struct dc *dc,
4573                                 uint32_t link_index,
4574                                 struct set_config_cmd_payload *payload,
4575                                 struct dmub_notification *notify)
4576 {
4577         union dmub_rb_cmd cmd = {0};
4578         struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
4579         bool is_cmd_complete = true;
4580
4581         /* prepare SET_CONFIG command */
4582         cmd.set_config_access.header.type = DMUB_CMD__DPIA;
4583         cmd.set_config_access.header.sub_type = DMUB_CMD__DPIA_SET_CONFIG_ACCESS;
4584
4585         cmd.set_config_access.set_config_control.instance = dc->links[link_index]->ddc_hw_inst;
4586         cmd.set_config_access.set_config_control.cmd_pkt.msg_type = payload->msg_type;
4587         cmd.set_config_access.set_config_control.cmd_pkt.msg_data = payload->msg_data;
4588
4589         if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) {
4590                 /* command is not processed by dmub */
4591                 notify->sc_status = SET_CONFIG_UNKNOWN_ERROR;
4592                 return is_cmd_complete;
4593         }
4594
4595         /* command processed by dmub, if ret_status is 1, it is completed instantly */
4596         if (cmd.set_config_access.header.ret_status == 1)
4597                 notify->sc_status = cmd.set_config_access.set_config_control.immed_status;
4598         else
4599                 /* cmd pending, will receive notification via outbox */
4600                 is_cmd_complete = false;
4601
4602         return is_cmd_complete;
4603 }
4604
4605 /**
4606  *****************************************************************************
4607  *  Function: dc_process_dmub_set_mst_slots
4608  *
4609  *  @brief
4610  *              Submits mst slot allocation command to dmub via inbox message
4611  *
4612  *  @param
4613  *              [in] dc: dc structure
4614  *              [in] link_index: link index
4615  *              [in] mst_alloc_slots: mst slots to be allotted
4616  *              [out] mst_slots_in_use: mst slots in use returned in failure case
4617  *
4618  *      @return
4619  *              DC_OK if successful, DC_ERROR if failure
4620  *****************************************************************************
4621  */
4622 enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
4623                                 uint32_t link_index,
4624                                 uint8_t mst_alloc_slots,
4625                                 uint8_t *mst_slots_in_use)
4626 {
4627         union dmub_rb_cmd cmd = {0};
4628         struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
4629
4630         /* prepare MST_ALLOC_SLOTS command */
4631         cmd.set_mst_alloc_slots.header.type = DMUB_CMD__DPIA;
4632         cmd.set_mst_alloc_slots.header.sub_type = DMUB_CMD__DPIA_MST_ALLOC_SLOTS;
4633
4634         cmd.set_mst_alloc_slots.mst_slots_control.instance = dc->links[link_index]->ddc_hw_inst;
4635         cmd.set_mst_alloc_slots.mst_slots_control.mst_alloc_slots = mst_alloc_slots;
4636
4637         if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd))
4638                 /* command is not processed by dmub */
4639                 return DC_ERROR_UNEXPECTED;
4640
4641         /* command processed by dmub, if ret_status is 1 */
4642         if (cmd.set_config_access.header.ret_status != 1)
4643                 /* command processing error */
4644                 return DC_ERROR_UNEXPECTED;
4645
4646         /* command processed and we have a status of 2, mst not enabled in dpia */
4647         if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 2)
4648                 return DC_FAIL_UNSUPPORTED_1;
4649
4650         /* previously configured mst alloc and used slots did not match */
4651         if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 3) {
4652                 *mst_slots_in_use = cmd.set_mst_alloc_slots.mst_slots_control.mst_slots_in_use;
4653                 return DC_NOT_SUPPORTED;
4654         }
4655
4656         return DC_OK;
4657 }
4658
4659 /**
4660  *****************************************************************************
4661  *  Function: dc_process_dmub_dpia_hpd_int_enable
4662  *
4663  *  @brief
4664  *              Submits dpia hpd int enable command to dmub via inbox message
4665  *
4666  *  @param
4667  *              [in] dc: dc structure
4668  *              [in] hpd_int_enable: 1 for hpd int enable, 0 to disable
4669  *
4670  *      @return
4671  *              None
4672  *****************************************************************************
4673  */
4674 void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
4675                                 uint32_t hpd_int_enable)
4676 {
4677         union dmub_rb_cmd cmd = {0};
4678         struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
4679
4680         cmd.dpia_hpd_int_enable.header.type = DMUB_CMD__DPIA_HPD_INT_ENABLE;
4681         cmd.dpia_hpd_int_enable.enable = hpd_int_enable;
4682
4683         dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
4684         dc_dmub_srv_cmd_execute(dmub_srv);
4685         dc_dmub_srv_wait_idle(dmub_srv);
4686
4687         DC_LOG_DEBUG("%s: hpd_int_enable(%d)\n", __func__, hpd_int_enable);
4688 }
4689
4690 /**
4691  * dc_disable_accelerated_mode - disable accelerated mode
4692  * @dc: dc structure
4693  */
4694 void dc_disable_accelerated_mode(struct dc *dc)
4695 {
4696         bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 0);
4697 }
4698
4699
4700 /**
4701  *****************************************************************************
4702  *  dc_notify_vsync_int_state() - notifies vsync enable/disable state
4703  *  @dc: dc structure
4704  *      @stream: stream where vsync int state changed
4705  *      @enable: whether vsync is enabled or disabled
4706  *
4707  *  Called when vsync is enabled/disabled
4708  *      Will notify DMUB to start/stop ABM interrupts after steady state is reached
4709  *
4710  *****************************************************************************
4711  */
4712 void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable)
4713 {
4714         int i;
4715         int edp_num;
4716         struct pipe_ctx *pipe = NULL;
4717         struct dc_link *link = stream->sink->link;
4718         struct dc_link *edp_links[MAX_NUM_EDP];
4719
4720
4721         if (link->psr_settings.psr_feature_enabled)
4722                 return;
4723
4724         /*find primary pipe associated with stream*/
4725         for (i = 0; i < MAX_PIPES; i++) {
4726                 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
4727
4728                 if (pipe->stream == stream && pipe->stream_res.tg)
4729                         break;
4730         }
4731
4732         if (i == MAX_PIPES) {
4733                 ASSERT(0);
4734                 return;
4735         }
4736
4737         get_edp_links(dc, edp_links, &edp_num);
4738
4739         /* Determine panel inst */
4740         for (i = 0; i < edp_num; i++) {
4741                 if (edp_links[i] == link)
4742                         break;
4743         }
4744
4745         if (i == edp_num) {
4746                 return;
4747         }
4748
4749         if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause)
4750                 pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst);
4751 }
4752 /*
4753  * dc_extended_blank_supported: Decide whether extended blank is supported
4754  *
4755  * Extended blank is a freesync optimization feature to be enabled in the future.
4756  * During the extra vblank period gained from freesync, we have the ability to enter z9/z10.
4757  *
4758  * @param [in] dc: Current DC state
4759  * @return: Indicate whether extended blank is supported (true or false)
4760  */
4761 bool dc_extended_blank_supported(struct dc *dc)
4762 {
4763         return dc->debug.extended_blank_optimization && !dc->debug.disable_z10
4764                 && dc->caps.zstate_support && dc->caps.is_apu;
4765 }
This page took 0.328673 seconds and 4 git commands to generate.