Merge branch 'for-upstream/mali-dp' of git://linux-arm.org/linux-ld into drm-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / display / dc / core / dc_resource.c
1 /*
2  * Copyright 2012-15 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 "resource.h"
28 #include "include/irq_service_interface.h"
29 #include "link_encoder.h"
30 #include "stream_encoder.h"
31 #include "opp.h"
32 #include "timing_generator.h"
33 #include "transform.h"
34 #include "dpp.h"
35 #include "core_types.h"
36 #include "set_mode_types.h"
37 #include "virtual/virtual_stream_encoder.h"
38 #include "dpcd_defs.h"
39
40 #include "dce80/dce80_resource.h"
41 #include "dce100/dce100_resource.h"
42 #include "dce110/dce110_resource.h"
43 #include "dce112/dce112_resource.h"
44 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
45 #include "dcn10/dcn10_resource.h"
46 #endif
47 #include "dce120/dce120_resource.h"
48
49 #define DC_LOGGER_INIT(logger)
50
51 enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
52 {
53         enum dce_version dc_version = DCE_VERSION_UNKNOWN;
54         switch (asic_id.chip_family) {
55
56         case FAMILY_CI:
57                 dc_version = DCE_VERSION_8_0;
58                 break;
59         case FAMILY_KV:
60                 if (ASIC_REV_IS_KALINDI(asic_id.hw_internal_rev) ||
61                     ASIC_REV_IS_BHAVANI(asic_id.hw_internal_rev) ||
62                     ASIC_REV_IS_GODAVARI(asic_id.hw_internal_rev))
63                         dc_version = DCE_VERSION_8_3;
64                 else
65                         dc_version = DCE_VERSION_8_1;
66                 break;
67         case FAMILY_CZ:
68                 dc_version = DCE_VERSION_11_0;
69                 break;
70
71         case FAMILY_VI:
72                 if (ASIC_REV_IS_TONGA_P(asic_id.hw_internal_rev) ||
73                                 ASIC_REV_IS_FIJI_P(asic_id.hw_internal_rev)) {
74                         dc_version = DCE_VERSION_10_0;
75                         break;
76                 }
77                 if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev) ||
78                                 ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) ||
79                                 ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) {
80                         dc_version = DCE_VERSION_11_2;
81                 }
82                 if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev))
83                         dc_version = DCE_VERSION_11_22;
84                 break;
85         case FAMILY_AI:
86                 if (ASICREV_IS_VEGA20_P(asic_id.hw_internal_rev))
87                         dc_version = DCE_VERSION_12_1;
88                 else
89                         dc_version = DCE_VERSION_12_0;
90                 break;
91 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
92         case FAMILY_RV:
93                 dc_version = DCN_VERSION_1_0;
94 #if defined(CONFIG_DRM_AMD_DC_DCN1_01)
95                 if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev))
96                         dc_version = DCN_VERSION_1_01;
97 #endif
98                 break;
99 #endif
100         default:
101                 dc_version = DCE_VERSION_UNKNOWN;
102                 break;
103         }
104         return dc_version;
105 }
106
107 struct resource_pool *dc_create_resource_pool(
108                                 struct dc  *dc,
109                                 int num_virtual_links,
110                                 enum dce_version dc_version,
111                                 struct hw_asic_id asic_id)
112 {
113         struct resource_pool *res_pool = NULL;
114
115         switch (dc_version) {
116         case DCE_VERSION_8_0:
117                 res_pool = dce80_create_resource_pool(
118                         num_virtual_links, dc);
119                 break;
120         case DCE_VERSION_8_1:
121                 res_pool = dce81_create_resource_pool(
122                         num_virtual_links, dc);
123                 break;
124         case DCE_VERSION_8_3:
125                 res_pool = dce83_create_resource_pool(
126                         num_virtual_links, dc);
127                 break;
128         case DCE_VERSION_10_0:
129                 res_pool = dce100_create_resource_pool(
130                                 num_virtual_links, dc);
131                 break;
132         case DCE_VERSION_11_0:
133                 res_pool = dce110_create_resource_pool(
134                         num_virtual_links, dc, asic_id);
135                 break;
136         case DCE_VERSION_11_2:
137         case DCE_VERSION_11_22:
138                 res_pool = dce112_create_resource_pool(
139                         num_virtual_links, dc);
140                 break;
141         case DCE_VERSION_12_0:
142         case DCE_VERSION_12_1:
143                 res_pool = dce120_create_resource_pool(
144                         num_virtual_links, dc);
145                 break;
146
147 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
148         case DCN_VERSION_1_0:
149 #if defined(CONFIG_DRM_AMD_DC_DCN1_01)
150         case DCN_VERSION_1_01:
151 #endif
152                 res_pool = dcn10_create_resource_pool(
153                                 num_virtual_links, dc);
154                 break;
155 #endif
156
157
158         default:
159                 break;
160         }
161         if (res_pool != NULL) {
162                 struct dc_firmware_info fw_info = { { 0 } };
163
164                 if (dc->ctx->dc_bios->funcs->get_firmware_info(
165                                 dc->ctx->dc_bios, &fw_info) == BP_RESULT_OK) {
166                                 res_pool->ref_clock_inKhz = fw_info.pll_info.crystal_frequency;
167                         } else
168                                 ASSERT_CRITICAL(false);
169         }
170
171         return res_pool;
172 }
173
174 void dc_destroy_resource_pool(struct dc  *dc)
175 {
176         if (dc) {
177                 if (dc->res_pool)
178                         dc->res_pool->funcs->destroy(&dc->res_pool);
179
180                 kfree(dc->hwseq);
181         }
182 }
183
184 static void update_num_audio(
185         const struct resource_straps *straps,
186         unsigned int *num_audio,
187         struct audio_support *aud_support)
188 {
189         aud_support->dp_audio = true;
190         aud_support->hdmi_audio_native = false;
191         aud_support->hdmi_audio_on_dongle = false;
192
193         if (straps->hdmi_disable == 0) {
194                 if (straps->dc_pinstraps_audio & 0x2) {
195                         aud_support->hdmi_audio_on_dongle = true;
196                         aud_support->hdmi_audio_native = true;
197                 }
198         }
199
200         switch (straps->audio_stream_number) {
201         case 0: /* multi streams supported */
202                 break;
203         case 1: /* multi streams not supported */
204                 *num_audio = 1;
205                 break;
206         default:
207                 DC_ERR("DC: unexpected audio fuse!\n");
208         }
209 }
210
211 bool resource_construct(
212         unsigned int num_virtual_links,
213         struct dc  *dc,
214         struct resource_pool *pool,
215         const struct resource_create_funcs *create_funcs)
216 {
217         struct dc_context *ctx = dc->ctx;
218         const struct resource_caps *caps = pool->res_cap;
219         int i;
220         unsigned int num_audio = caps->num_audio;
221         struct resource_straps straps = {0};
222
223         if (create_funcs->read_dce_straps)
224                 create_funcs->read_dce_straps(dc->ctx, &straps);
225
226         pool->audio_count = 0;
227         if (create_funcs->create_audio) {
228                 /* find the total number of streams available via the
229                  * AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT
230                  * registers (one for each pin) starting from pin 1
231                  * up to the max number of audio pins.
232                  * We stop on the first pin where
233                  * PORT_CONNECTIVITY == 1 (as instructed by HW team).
234                  */
235                 update_num_audio(&straps, &num_audio, &pool->audio_support);
236                 for (i = 0; i < pool->pipe_count && i < num_audio; i++) {
237                         struct audio *aud = create_funcs->create_audio(ctx, i);
238
239                         if (aud == NULL) {
240                                 DC_ERR("DC: failed to create audio!\n");
241                                 return false;
242                         }
243
244                         if (!aud->funcs->endpoint_valid(aud)) {
245                                 aud->funcs->destroy(&aud);
246                                 break;
247                         }
248
249                         pool->audios[i] = aud;
250                         pool->audio_count++;
251                 }
252         }
253
254         pool->stream_enc_count = 0;
255         if (create_funcs->create_stream_encoder) {
256                 for (i = 0; i < caps->num_stream_encoder; i++) {
257                         pool->stream_enc[i] = create_funcs->create_stream_encoder(i, ctx);
258                         if (pool->stream_enc[i] == NULL)
259                                 DC_ERR("DC: failed to create stream_encoder!\n");
260                         pool->stream_enc_count++;
261                 }
262         }
263         dc->caps.dynamic_audio = false;
264         if (pool->audio_count < pool->stream_enc_count) {
265                 dc->caps.dynamic_audio = true;
266         }
267         for (i = 0; i < num_virtual_links; i++) {
268                 pool->stream_enc[pool->stream_enc_count] =
269                         virtual_stream_encoder_create(
270                                         ctx, ctx->dc_bios);
271                 if (pool->stream_enc[pool->stream_enc_count] == NULL) {
272                         DC_ERR("DC: failed to create stream_encoder!\n");
273                         return false;
274                 }
275                 pool->stream_enc_count++;
276         }
277
278         dc->hwseq = create_funcs->create_hwseq(ctx);
279
280         return true;
281 }
282 static int find_matching_clock_source(
283                 const struct resource_pool *pool,
284                 struct clock_source *clock_source)
285 {
286
287         int i;
288
289         for (i = 0; i < pool->clk_src_count; i++) {
290                 if (pool->clock_sources[i] == clock_source)
291                         return i;
292         }
293         return -1;
294 }
295
296 void resource_unreference_clock_source(
297                 struct resource_context *res_ctx,
298                 const struct resource_pool *pool,
299                 struct clock_source *clock_source)
300 {
301         int i = find_matching_clock_source(pool, clock_source);
302
303         if (i > -1)
304                 res_ctx->clock_source_ref_count[i]--;
305
306         if (pool->dp_clock_source == clock_source)
307                 res_ctx->dp_clock_source_ref_count--;
308 }
309
310 void resource_reference_clock_source(
311                 struct resource_context *res_ctx,
312                 const struct resource_pool *pool,
313                 struct clock_source *clock_source)
314 {
315         int i = find_matching_clock_source(pool, clock_source);
316
317         if (i > -1)
318                 res_ctx->clock_source_ref_count[i]++;
319
320         if (pool->dp_clock_source == clock_source)
321                 res_ctx->dp_clock_source_ref_count++;
322 }
323
324 int resource_get_clock_source_reference(
325                 struct resource_context *res_ctx,
326                 const struct resource_pool *pool,
327                 struct clock_source *clock_source)
328 {
329         int i = find_matching_clock_source(pool, clock_source);
330
331         if (i > -1)
332                 return res_ctx->clock_source_ref_count[i];
333
334         if (pool->dp_clock_source == clock_source)
335                 return res_ctx->dp_clock_source_ref_count;
336
337         return -1;
338 }
339
340 bool resource_are_streams_timing_synchronizable(
341         struct dc_stream_state *stream1,
342         struct dc_stream_state *stream2)
343 {
344         if (stream1->timing.h_total != stream2->timing.h_total)
345                 return false;
346
347         if (stream1->timing.v_total != stream2->timing.v_total)
348                 return false;
349
350         if (stream1->timing.h_addressable
351                                 != stream2->timing.h_addressable)
352                 return false;
353
354         if (stream1->timing.v_addressable
355                                 != stream2->timing.v_addressable)
356                 return false;
357
358         if (stream1->timing.pix_clk_100hz
359                                 != stream2->timing.pix_clk_100hz)
360                 return false;
361
362         if (stream1->clamping.c_depth != stream2->clamping.c_depth)
363                 return false;
364
365         if (stream1->phy_pix_clk != stream2->phy_pix_clk
366                         && (!dc_is_dp_signal(stream1->signal)
367                         || !dc_is_dp_signal(stream2->signal)))
368                 return false;
369
370         if (stream1->view_format != stream2->view_format)
371                 return false;
372
373         return true;
374 }
375 static bool is_dp_and_hdmi_sharable(
376                 struct dc_stream_state *stream1,
377                 struct dc_stream_state *stream2)
378 {
379         if (stream1->ctx->dc->caps.disable_dp_clk_share)
380                 return false;
381
382         if (stream1->clamping.c_depth != COLOR_DEPTH_888 ||
383                 stream2->clamping.c_depth != COLOR_DEPTH_888)
384                 return false;
385
386         return true;
387
388 }
389
390 static bool is_sharable_clk_src(
391         const struct pipe_ctx *pipe_with_clk_src,
392         const struct pipe_ctx *pipe)
393 {
394         if (pipe_with_clk_src->clock_source == NULL)
395                 return false;
396
397         if (pipe_with_clk_src->stream->signal == SIGNAL_TYPE_VIRTUAL)
398                 return false;
399
400         if (dc_is_dp_signal(pipe_with_clk_src->stream->signal) ||
401                 (dc_is_dp_signal(pipe->stream->signal) &&
402                 !is_dp_and_hdmi_sharable(pipe_with_clk_src->stream,
403                                      pipe->stream)))
404                 return false;
405
406         if (dc_is_hdmi_signal(pipe_with_clk_src->stream->signal)
407                         && dc_is_dual_link_signal(pipe->stream->signal))
408                 return false;
409
410         if (dc_is_hdmi_signal(pipe->stream->signal)
411                         && dc_is_dual_link_signal(pipe_with_clk_src->stream->signal))
412                 return false;
413
414         if (!resource_are_streams_timing_synchronizable(
415                         pipe_with_clk_src->stream, pipe->stream))
416                 return false;
417
418         return true;
419 }
420
421 struct clock_source *resource_find_used_clk_src_for_sharing(
422                                         struct resource_context *res_ctx,
423                                         struct pipe_ctx *pipe_ctx)
424 {
425         int i;
426
427         for (i = 0; i < MAX_PIPES; i++) {
428                 if (is_sharable_clk_src(&res_ctx->pipe_ctx[i], pipe_ctx))
429                         return res_ctx->pipe_ctx[i].clock_source;
430         }
431
432         return NULL;
433 }
434
435 static enum pixel_format convert_pixel_format_to_dalsurface(
436                 enum surface_pixel_format surface_pixel_format)
437 {
438         enum pixel_format dal_pixel_format = PIXEL_FORMAT_UNKNOWN;
439
440         switch (surface_pixel_format) {
441         case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
442                 dal_pixel_format = PIXEL_FORMAT_INDEX8;
443                 break;
444         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
445                 dal_pixel_format = PIXEL_FORMAT_RGB565;
446                 break;
447         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
448                 dal_pixel_format = PIXEL_FORMAT_RGB565;
449                 break;
450         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
451                 dal_pixel_format = PIXEL_FORMAT_ARGB8888;
452                 break;
453         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
454                 dal_pixel_format = PIXEL_FORMAT_ARGB8888;
455                 break;
456         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
457                 dal_pixel_format = PIXEL_FORMAT_ARGB2101010;
458                 break;
459         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
460                 dal_pixel_format = PIXEL_FORMAT_ARGB2101010;
461                 break;
462         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
463                 dal_pixel_format = PIXEL_FORMAT_ARGB2101010_XRBIAS;
464                 break;
465         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
466         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
467                 dal_pixel_format = PIXEL_FORMAT_FP16;
468                 break;
469         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
470         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
471                 dal_pixel_format = PIXEL_FORMAT_420BPP8;
472                 break;
473         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
474         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
475                 dal_pixel_format = PIXEL_FORMAT_420BPP10;
476                 break;
477         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
478         default:
479                 dal_pixel_format = PIXEL_FORMAT_UNKNOWN;
480                 break;
481         }
482         return dal_pixel_format;
483 }
484
485 static inline void get_vp_scan_direction(
486         enum dc_rotation_angle rotation,
487         bool horizontal_mirror,
488         bool *orthogonal_rotation,
489         bool *flip_vert_scan_dir,
490         bool *flip_horz_scan_dir)
491 {
492         *orthogonal_rotation = false;
493         *flip_vert_scan_dir = false;
494         *flip_horz_scan_dir = false;
495         if (rotation == ROTATION_ANGLE_180) {
496                 *flip_vert_scan_dir = true;
497                 *flip_horz_scan_dir = true;
498         } else if (rotation == ROTATION_ANGLE_90) {
499                 *orthogonal_rotation = true;
500                 *flip_horz_scan_dir = true;
501         } else if (rotation == ROTATION_ANGLE_270) {
502                 *orthogonal_rotation = true;
503                 *flip_vert_scan_dir = true;
504         }
505
506         if (horizontal_mirror)
507                 *flip_horz_scan_dir = !*flip_horz_scan_dir;
508 }
509
510 static void calculate_viewport(struct pipe_ctx *pipe_ctx)
511 {
512         const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
513         const struct dc_stream_state *stream = pipe_ctx->stream;
514         struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
515         struct rect surf_src = plane_state->src_rect;
516         struct rect clip, dest;
517         int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
518                         || data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
519         bool pri_split = pipe_ctx->bottom_pipe &&
520                         pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state;
521         bool sec_split = pipe_ctx->top_pipe &&
522                         pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
523         bool orthogonal_rotation, flip_y_start, flip_x_start;
524
525         if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
526                 stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
527                 pri_split = false;
528                 sec_split = false;
529         }
530
531         /* The actual clip is an intersection between stream
532          * source and surface clip
533          */
534         dest = plane_state->dst_rect;
535         clip.x = stream->src.x > plane_state->clip_rect.x ?
536                         stream->src.x : plane_state->clip_rect.x;
537
538         clip.width = stream->src.x + stream->src.width <
539                         plane_state->clip_rect.x + plane_state->clip_rect.width ?
540                         stream->src.x + stream->src.width - clip.x :
541                         plane_state->clip_rect.x + plane_state->clip_rect.width - clip.x ;
542
543         clip.y = stream->src.y > plane_state->clip_rect.y ?
544                         stream->src.y : plane_state->clip_rect.y;
545
546         clip.height = stream->src.y + stream->src.height <
547                         plane_state->clip_rect.y + plane_state->clip_rect.height ?
548                         stream->src.y + stream->src.height - clip.y :
549                         plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ;
550
551         /*
552          * Need to calculate how scan origin is shifted in vp space
553          * to correctly rotate clip and dst
554          */
555         get_vp_scan_direction(
556                         plane_state->rotation,
557                         plane_state->horizontal_mirror,
558                         &orthogonal_rotation,
559                         &flip_y_start,
560                         &flip_x_start);
561
562         if (orthogonal_rotation) {
563                 swap(clip.x, clip.y);
564                 swap(clip.width, clip.height);
565                 swap(dest.x, dest.y);
566                 swap(dest.width, dest.height);
567         }
568         if (flip_x_start) {
569                 clip.x = dest.x + dest.width - clip.x - clip.width;
570                 dest.x = 0;
571         }
572         if (flip_y_start) {
573                 clip.y = dest.y + dest.height - clip.y - clip.height;
574                 dest.y = 0;
575         }
576
577         /* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio
578          * num_pixels = clip.num_pix * scl_ratio
579          */
580         data->viewport.x = surf_src.x + (clip.x - dest.x) * surf_src.width / dest.width;
581         data->viewport.width = clip.width * surf_src.width / dest.width;
582
583         data->viewport.y = surf_src.y + (clip.y - dest.y) * surf_src.height / dest.height;
584         data->viewport.height = clip.height * surf_src.height / dest.height;
585
586         /* Handle split */
587         if (pri_split || sec_split) {
588                 if (orthogonal_rotation) {
589                         if (flip_y_start != pri_split)
590                                 data->viewport.height /= 2;
591                         else {
592                                 data->viewport.y +=  data->viewport.height / 2;
593                                 /* Ceil offset pipe */
594                                 data->viewport.height = (data->viewport.height + 1) / 2;
595                         }
596                 } else {
597                         if (flip_x_start != pri_split)
598                                 data->viewport.width /= 2;
599                         else {
600                                 data->viewport.x +=  data->viewport.width / 2;
601                                 /* Ceil offset pipe */
602                                 data->viewport.width = (data->viewport.width + 1) / 2;
603                         }
604                 }
605         }
606
607         /* Round down, compensate in init */
608         data->viewport_c.x = data->viewport.x / vpc_div;
609         data->viewport_c.y = data->viewport.y / vpc_div;
610         data->inits.h_c = (data->viewport.x % vpc_div) != 0 ? dc_fixpt_half : dc_fixpt_zero;
611         data->inits.v_c = (data->viewport.y % vpc_div) != 0 ? dc_fixpt_half : dc_fixpt_zero;
612
613         /* Round up, assume original video size always even dimensions */
614         data->viewport_c.width = (data->viewport.width + vpc_div - 1) / vpc_div;
615         data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
616 }
617
618 static void calculate_recout(struct pipe_ctx *pipe_ctx)
619 {
620         const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
621         const struct dc_stream_state *stream = pipe_ctx->stream;
622         struct rect surf_clip = plane_state->clip_rect;
623         bool pri_split = pipe_ctx->bottom_pipe &&
624                         pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state;
625         bool sec_split = pipe_ctx->top_pipe &&
626                         pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
627         bool top_bottom_split = stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
628
629         pipe_ctx->plane_res.scl_data.recout.x = stream->dst.x;
630         if (stream->src.x < surf_clip.x)
631                 pipe_ctx->plane_res.scl_data.recout.x += (surf_clip.x
632                         - stream->src.x) * stream->dst.width
633                                                 / stream->src.width;
634
635         pipe_ctx->plane_res.scl_data.recout.width = surf_clip.width *
636                         stream->dst.width / stream->src.width;
637         if (pipe_ctx->plane_res.scl_data.recout.width + pipe_ctx->plane_res.scl_data.recout.x >
638                         stream->dst.x + stream->dst.width)
639                 pipe_ctx->plane_res.scl_data.recout.width =
640                         stream->dst.x + stream->dst.width
641                                                 - pipe_ctx->plane_res.scl_data.recout.x;
642
643         pipe_ctx->plane_res.scl_data.recout.y = stream->dst.y;
644         if (stream->src.y < surf_clip.y)
645                 pipe_ctx->plane_res.scl_data.recout.y += (surf_clip.y
646                         - stream->src.y) * stream->dst.height
647                                                 / stream->src.height;
648
649         pipe_ctx->plane_res.scl_data.recout.height = surf_clip.height *
650                         stream->dst.height / stream->src.height;
651         if (pipe_ctx->plane_res.scl_data.recout.height + pipe_ctx->plane_res.scl_data.recout.y >
652                         stream->dst.y + stream->dst.height)
653                 pipe_ctx->plane_res.scl_data.recout.height =
654                         stream->dst.y + stream->dst.height
655                                                 - pipe_ctx->plane_res.scl_data.recout.y;
656
657         /* Handle h & v split, handle rotation using viewport */
658         if (sec_split && top_bottom_split) {
659                 pipe_ctx->plane_res.scl_data.recout.y +=
660                                 pipe_ctx->plane_res.scl_data.recout.height / 2;
661                 /* Floor primary pipe, ceil 2ndary pipe */
662                 pipe_ctx->plane_res.scl_data.recout.height =
663                                 (pipe_ctx->plane_res.scl_data.recout.height + 1) / 2;
664         } else if (pri_split && top_bottom_split)
665                 pipe_ctx->plane_res.scl_data.recout.height /= 2;
666         else if (sec_split) {
667                 pipe_ctx->plane_res.scl_data.recout.x +=
668                                 pipe_ctx->plane_res.scl_data.recout.width / 2;
669                 /* Ceil offset pipe */
670                 pipe_ctx->plane_res.scl_data.recout.width =
671                                 (pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
672         } else if (pri_split)
673                 pipe_ctx->plane_res.scl_data.recout.width /= 2;
674 }
675
676 static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
677 {
678         const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
679         const struct dc_stream_state *stream = pipe_ctx->stream;
680         struct rect surf_src = plane_state->src_rect;
681         const int in_w = stream->src.width;
682         const int in_h = stream->src.height;
683         const int out_w = stream->dst.width;
684         const int out_h = stream->dst.height;
685
686         /*Swap surf_src height and width since scaling ratios are in recout rotation*/
687         if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
688                         pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
689                 swap(surf_src.height, surf_src.width);
690
691         pipe_ctx->plane_res.scl_data.ratios.horz = dc_fixpt_from_fraction(
692                                         surf_src.width,
693                                         plane_state->dst_rect.width);
694         pipe_ctx->plane_res.scl_data.ratios.vert = dc_fixpt_from_fraction(
695                                         surf_src.height,
696                                         plane_state->dst_rect.height);
697
698         if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
699                 pipe_ctx->plane_res.scl_data.ratios.horz.value *= 2;
700         else if (stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
701                 pipe_ctx->plane_res.scl_data.ratios.vert.value *= 2;
702
703         pipe_ctx->plane_res.scl_data.ratios.vert.value = div64_s64(
704                 pipe_ctx->plane_res.scl_data.ratios.vert.value * in_h, out_h);
705         pipe_ctx->plane_res.scl_data.ratios.horz.value = div64_s64(
706                 pipe_ctx->plane_res.scl_data.ratios.horz.value * in_w, out_w);
707
708         pipe_ctx->plane_res.scl_data.ratios.horz_c = pipe_ctx->plane_res.scl_data.ratios.horz;
709         pipe_ctx->plane_res.scl_data.ratios.vert_c = pipe_ctx->plane_res.scl_data.ratios.vert;
710
711         if (pipe_ctx->plane_res.scl_data.format == PIXEL_FORMAT_420BPP8
712                         || pipe_ctx->plane_res.scl_data.format == PIXEL_FORMAT_420BPP10) {
713                 pipe_ctx->plane_res.scl_data.ratios.horz_c.value /= 2;
714                 pipe_ctx->plane_res.scl_data.ratios.vert_c.value /= 2;
715         }
716         pipe_ctx->plane_res.scl_data.ratios.horz = dc_fixpt_truncate(
717                         pipe_ctx->plane_res.scl_data.ratios.horz, 19);
718         pipe_ctx->plane_res.scl_data.ratios.vert = dc_fixpt_truncate(
719                         pipe_ctx->plane_res.scl_data.ratios.vert, 19);
720         pipe_ctx->plane_res.scl_data.ratios.horz_c = dc_fixpt_truncate(
721                         pipe_ctx->plane_res.scl_data.ratios.horz_c, 19);
722         pipe_ctx->plane_res.scl_data.ratios.vert_c = dc_fixpt_truncate(
723                         pipe_ctx->plane_res.scl_data.ratios.vert_c, 19);
724 }
725
726 static inline void adjust_vp_and_init_for_seamless_clip(
727                 bool flip_scan_dir,
728                 int recout_skip,
729                 int src_size,
730                 int taps,
731                 struct fixed31_32 ratio,
732                 struct fixed31_32 *init,
733                 int *vp_offset,
734                 int *vp_size)
735 {
736         if (!flip_scan_dir) {
737                 /* Adjust for viewport end clip-off */
738                 if ((*vp_offset + *vp_size) < src_size) {
739                         int vp_clip = src_size - *vp_size - *vp_offset;
740                         int int_part = dc_fixpt_floor(dc_fixpt_sub(*init, ratio));
741
742                         int_part = int_part > 0 ? int_part : 0;
743                         *vp_size += int_part < vp_clip ? int_part : vp_clip;
744                 }
745
746                 /* Adjust for non-0 viewport offset */
747                 if (*vp_offset) {
748                         int int_part;
749
750                         *init = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_skip));
751                         int_part = dc_fixpt_floor(*init) - *vp_offset;
752                         if (int_part < taps) {
753                                 int int_adj = *vp_offset >= (taps - int_part) ?
754                                                         (taps - int_part) : *vp_offset;
755                                 *vp_offset -= int_adj;
756                                 *vp_size += int_adj;
757                                 int_part += int_adj;
758                         } else if (int_part > taps) {
759                                 *vp_offset += int_part - taps;
760                                 *vp_size -= int_part - taps;
761                                 int_part = taps;
762                         }
763                         init->value &= 0xffffffff;
764                         *init = dc_fixpt_add_int(*init, int_part);
765                 }
766         } else {
767                 /* Adjust for non-0 viewport offset */
768                 if (*vp_offset) {
769                         int int_part = dc_fixpt_floor(dc_fixpt_sub(*init, ratio));
770
771                         int_part = int_part > 0 ? int_part : 0;
772                         *vp_size += int_part < *vp_offset ? int_part : *vp_offset;
773                         *vp_offset -= int_part < *vp_offset ? int_part : *vp_offset;
774                 }
775
776                 /* Adjust for viewport end clip-off */
777                 if ((*vp_offset + *vp_size) < src_size) {
778                         int int_part;
779                         int end_offset = src_size - *vp_offset - *vp_size;
780
781                         /*
782                          * this is init if vp had no offset, keep in mind this is from the
783                          * right side of vp due to scan direction
784                          */
785                         *init = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_skip));
786                         /*
787                          * this is the difference between first pixel of viewport available to read
788                          * and init position, takning into account scan direction
789                          */
790                         int_part = dc_fixpt_floor(*init) - end_offset;
791                         if (int_part < taps) {
792                                 int int_adj = end_offset >= (taps - int_part) ?
793                                                         (taps - int_part) : end_offset;
794                                 *vp_size += int_adj;
795                                 int_part += int_adj;
796                         } else if (int_part > taps) {
797                                 *vp_size += int_part - taps;
798                                 int_part = taps;
799                         }
800                         init->value &= 0xffffffff;
801                         *init = dc_fixpt_add_int(*init, int_part);
802                 }
803         }
804 }
805
806 static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
807 {
808         const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
809         const struct dc_stream_state *stream = pipe_ctx->stream;
810         struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
811         struct rect src = pipe_ctx->plane_state->src_rect;
812         int recout_skip_h, recout_skip_v, surf_size_h, surf_size_v;
813         int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
814                         || data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
815         bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
816
817         /*
818          * Need to calculate the scan direction for viewport to make adjustments
819          */
820         get_vp_scan_direction(
821                         plane_state->rotation,
822                         plane_state->horizontal_mirror,
823                         &orthogonal_rotation,
824                         &flip_vert_scan_dir,
825                         &flip_horz_scan_dir);
826
827         /* Calculate src rect rotation adjusted to recout space */
828         surf_size_h = src.x + src.width;
829         surf_size_v = src.y + src.height;
830         if (flip_horz_scan_dir)
831                 src.x = 0;
832         if (flip_vert_scan_dir)
833                 src.y = 0;
834         if (orthogonal_rotation) {
835                 swap(src.x, src.y);
836                 swap(src.width, src.height);
837         }
838
839         /* Recout matching initial vp offset = recout_offset - (stream dst offset +
840          *                      ((surf dst offset - stream src offset) * 1/ stream scaling ratio)
841          *                      - (surf surf_src offset * 1/ full scl ratio))
842          */
843         recout_skip_h = data->recout.x - (stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
844                                         * stream->dst.width / stream->src.width -
845                                         src.x * plane_state->dst_rect.width / src.width
846                                         * stream->dst.width / stream->src.width);
847         recout_skip_v = data->recout.y - (stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
848                                         * stream->dst.height / stream->src.height -
849                                         src.y * plane_state->dst_rect.height / src.height
850                                         * stream->dst.height / stream->src.height);
851         if (orthogonal_rotation)
852                 swap(recout_skip_h, recout_skip_v);
853         /*
854          * Init calculated according to formula:
855          *      init = (scaling_ratio + number_of_taps + 1) / 2
856          *      init_bot = init + scaling_ratio
857          *      init_c = init + truncated_vp_c_offset(from calculate viewport)
858          */
859         data->inits.h = dc_fixpt_truncate(dc_fixpt_div_int(
860                         dc_fixpt_add_int(data->ratios.horz, data->taps.h_taps + 1), 2), 19);
861
862         data->inits.h_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.h_c, dc_fixpt_div_int(
863                         dc_fixpt_add_int(data->ratios.horz_c, data->taps.h_taps_c + 1), 2)), 19);
864
865         data->inits.v = dc_fixpt_truncate(dc_fixpt_div_int(
866                         dc_fixpt_add_int(data->ratios.vert, data->taps.v_taps + 1), 2), 19);
867
868         data->inits.v_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.v_c, dc_fixpt_div_int(
869                         dc_fixpt_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2)), 19);
870
871         /*
872          * Taps, inits and scaling ratios are in recout space need to rotate
873          * to viewport rotation before adjustment
874          */
875         adjust_vp_and_init_for_seamless_clip(
876                         flip_horz_scan_dir,
877                         recout_skip_h,
878                         surf_size_h,
879                         orthogonal_rotation ? data->taps.v_taps : data->taps.h_taps,
880                         orthogonal_rotation ? data->ratios.vert : data->ratios.horz,
881                         orthogonal_rotation ? &data->inits.v : &data->inits.h,
882                         &data->viewport.x,
883                         &data->viewport.width);
884         adjust_vp_and_init_for_seamless_clip(
885                         flip_horz_scan_dir,
886                         recout_skip_h,
887                         surf_size_h / vpc_div,
888                         orthogonal_rotation ? data->taps.v_taps_c : data->taps.h_taps_c,
889                         orthogonal_rotation ? data->ratios.vert_c : data->ratios.horz_c,
890                         orthogonal_rotation ? &data->inits.v_c : &data->inits.h_c,
891                         &data->viewport_c.x,
892                         &data->viewport_c.width);
893         adjust_vp_and_init_for_seamless_clip(
894                         flip_vert_scan_dir,
895                         recout_skip_v,
896                         surf_size_v,
897                         orthogonal_rotation ? data->taps.h_taps : data->taps.v_taps,
898                         orthogonal_rotation ? data->ratios.horz : data->ratios.vert,
899                         orthogonal_rotation ? &data->inits.h : &data->inits.v,
900                         &data->viewport.y,
901                         &data->viewport.height);
902         adjust_vp_and_init_for_seamless_clip(
903                         flip_vert_scan_dir,
904                         recout_skip_v,
905                         surf_size_v / vpc_div,
906                         orthogonal_rotation ? data->taps.h_taps_c : data->taps.v_taps_c,
907                         orthogonal_rotation ? data->ratios.horz_c : data->ratios.vert_c,
908                         orthogonal_rotation ? &data->inits.h_c : &data->inits.v_c,
909                         &data->viewport_c.y,
910                         &data->viewport_c.height);
911
912         /* Interlaced inits based on final vert inits */
913         data->inits.v_bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
914         data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
915
916 }
917
918 bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
919 {
920         const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
921         struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
922         bool res = false;
923         DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
924         /* Important: scaling ratio calculation requires pixel format,
925          * lb depth calculation requires recout and taps require scaling ratios.
926          * Inits require viewport, taps, ratios and recout of split pipe
927          */
928         pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
929                         pipe_ctx->plane_state->format);
930
931         calculate_scaling_ratios(pipe_ctx);
932
933         calculate_viewport(pipe_ctx);
934
935         if (pipe_ctx->plane_res.scl_data.viewport.height < 16 || pipe_ctx->plane_res.scl_data.viewport.width < 16)
936                 return false;
937
938         calculate_recout(pipe_ctx);
939
940         /**
941          * Setting line buffer pixel depth to 24bpp yields banding
942          * on certain displays, such as the Sharp 4k
943          */
944         pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
945
946         pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
947         pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
948
949         pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
950         pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
951
952         /* Taps calculations */
953         if (pipe_ctx->plane_res.xfm != NULL)
954                 res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
955                                 pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
956
957         if (pipe_ctx->plane_res.dpp != NULL)
958                 res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
959                                 pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
960         if (!res) {
961                 /* Try 24 bpp linebuffer */
962                 pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_24BPP;
963
964                 if (pipe_ctx->plane_res.xfm != NULL)
965                         res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
966                                         pipe_ctx->plane_res.xfm,
967                                         &pipe_ctx->plane_res.scl_data,
968                                         &plane_state->scaling_quality);
969
970                 if (pipe_ctx->plane_res.dpp != NULL)
971                         res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
972                                         pipe_ctx->plane_res.dpp,
973                                         &pipe_ctx->plane_res.scl_data,
974                                         &plane_state->scaling_quality);
975         }
976
977         if (res)
978                 /* May need to re-check lb size after this in some obscure scenario */
979                 calculate_inits_and_adj_vp(pipe_ctx);
980
981         DC_LOG_SCALER(
982                                 "%s: Viewport:\nheight:%d width:%d x:%d "
983                                 "y:%d\n dst_rect:\nheight:%d width:%d x:%d "
984                                 "y:%d\n",
985                                 __func__,
986                                 pipe_ctx->plane_res.scl_data.viewport.height,
987                                 pipe_ctx->plane_res.scl_data.viewport.width,
988                                 pipe_ctx->plane_res.scl_data.viewport.x,
989                                 pipe_ctx->plane_res.scl_data.viewport.y,
990                                 plane_state->dst_rect.height,
991                                 plane_state->dst_rect.width,
992                                 plane_state->dst_rect.x,
993                                 plane_state->dst_rect.y);
994
995         return res;
996 }
997
998
999 enum dc_status resource_build_scaling_params_for_context(
1000         const struct dc  *dc,
1001         struct dc_state *context)
1002 {
1003         int i;
1004
1005         for (i = 0; i < MAX_PIPES; i++) {
1006                 if (context->res_ctx.pipe_ctx[i].plane_state != NULL &&
1007                                 context->res_ctx.pipe_ctx[i].stream != NULL)
1008                         if (!resource_build_scaling_params(&context->res_ctx.pipe_ctx[i]))
1009                                 return DC_FAIL_SCALING;
1010         }
1011
1012         return DC_OK;
1013 }
1014
1015 struct pipe_ctx *find_idle_secondary_pipe(
1016                 struct resource_context *res_ctx,
1017                 const struct resource_pool *pool)
1018 {
1019         int i;
1020         struct pipe_ctx *secondary_pipe = NULL;
1021
1022         /*
1023          * search backwards for the second pipe to keep pipe
1024          * assignment more consistent
1025          */
1026
1027         for (i = pool->pipe_count - 1; i >= 0; i--) {
1028                 if (res_ctx->pipe_ctx[i].stream == NULL) {
1029                         secondary_pipe = &res_ctx->pipe_ctx[i];
1030                         secondary_pipe->pipe_idx = i;
1031                         break;
1032                 }
1033         }
1034
1035
1036         return secondary_pipe;
1037 }
1038
1039 struct pipe_ctx *resource_get_head_pipe_for_stream(
1040                 struct resource_context *res_ctx,
1041                 struct dc_stream_state *stream)
1042 {
1043         int i;
1044         for (i = 0; i < MAX_PIPES; i++) {
1045                 if (res_ctx->pipe_ctx[i].stream == stream &&
1046                                 !res_ctx->pipe_ctx[i].top_pipe) {
1047                         return &res_ctx->pipe_ctx[i];
1048                         break;
1049                 }
1050         }
1051         return NULL;
1052 }
1053
1054 static struct pipe_ctx *resource_get_tail_pipe_for_stream(
1055                 struct resource_context *res_ctx,
1056                 struct dc_stream_state *stream)
1057 {
1058         struct pipe_ctx *head_pipe, *tail_pipe;
1059         head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
1060
1061         if (!head_pipe)
1062                 return NULL;
1063
1064         tail_pipe = head_pipe->bottom_pipe;
1065
1066         while (tail_pipe) {
1067                 head_pipe = tail_pipe;
1068                 tail_pipe = tail_pipe->bottom_pipe;
1069         }
1070
1071         return head_pipe;
1072 }
1073
1074 /*
1075  * A free_pipe for a stream is defined here as a pipe
1076  * that has no surface attached yet
1077  */
1078 static struct pipe_ctx *acquire_free_pipe_for_stream(
1079                 struct dc_state *context,
1080                 const struct resource_pool *pool,
1081                 struct dc_stream_state *stream)
1082 {
1083         int i;
1084         struct resource_context *res_ctx = &context->res_ctx;
1085
1086         struct pipe_ctx *head_pipe = NULL;
1087
1088         /* Find head pipe, which has the back end set up*/
1089
1090         head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
1091
1092         if (!head_pipe) {
1093                 ASSERT(0);
1094                 return NULL;
1095         }
1096
1097         if (!head_pipe->plane_state)
1098                 return head_pipe;
1099
1100         /* Re-use pipe already acquired for this stream if available*/
1101         for (i = pool->pipe_count - 1; i >= 0; i--) {
1102                 if (res_ctx->pipe_ctx[i].stream == stream &&
1103                                 !res_ctx->pipe_ctx[i].plane_state) {
1104                         return &res_ctx->pipe_ctx[i];
1105                 }
1106         }
1107
1108         /*
1109          * At this point we have no re-useable pipe for this stream and we need
1110          * to acquire an idle one to satisfy the request
1111          */
1112
1113         if (!pool->funcs->acquire_idle_pipe_for_layer)
1114                 return NULL;
1115
1116         return pool->funcs->acquire_idle_pipe_for_layer(context, pool, stream);
1117
1118 }
1119
1120 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1121 static int acquire_first_split_pipe(
1122                 struct resource_context *res_ctx,
1123                 const struct resource_pool *pool,
1124                 struct dc_stream_state *stream)
1125 {
1126         int i;
1127
1128         for (i = 0; i < pool->pipe_count; i++) {
1129                 struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
1130
1131                 if (pipe_ctx->top_pipe &&
1132                                 pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state) {
1133                         pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe;
1134                         if (pipe_ctx->bottom_pipe)
1135                                 pipe_ctx->bottom_pipe->top_pipe = pipe_ctx->top_pipe;
1136
1137                         memset(pipe_ctx, 0, sizeof(*pipe_ctx));
1138                         pipe_ctx->stream_res.tg = pool->timing_generators[i];
1139                         pipe_ctx->plane_res.hubp = pool->hubps[i];
1140                         pipe_ctx->plane_res.ipp = pool->ipps[i];
1141                         pipe_ctx->plane_res.dpp = pool->dpps[i];
1142                         pipe_ctx->stream_res.opp = pool->opps[i];
1143                         pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
1144                         pipe_ctx->pipe_idx = i;
1145
1146                         pipe_ctx->stream = stream;
1147                         return i;
1148                 }
1149         }
1150         return -1;
1151 }
1152 #endif
1153
1154 bool dc_add_plane_to_context(
1155                 const struct dc *dc,
1156                 struct dc_stream_state *stream,
1157                 struct dc_plane_state *plane_state,
1158                 struct dc_state *context)
1159 {
1160         int i;
1161         struct resource_pool *pool = dc->res_pool;
1162         struct pipe_ctx *head_pipe, *tail_pipe, *free_pipe;
1163         struct dc_stream_status *stream_status = NULL;
1164
1165         for (i = 0; i < context->stream_count; i++)
1166                 if (context->streams[i] == stream) {
1167                         stream_status = &context->stream_status[i];
1168                         break;
1169                 }
1170         if (stream_status == NULL) {
1171                 dm_error("Existing stream not found; failed to attach surface!\n");
1172                 return false;
1173         }
1174
1175
1176         if (stream_status->plane_count == MAX_SURFACE_NUM) {
1177                 dm_error("Surface: can not attach plane_state %p! Maximum is: %d\n",
1178                                 plane_state, MAX_SURFACE_NUM);
1179                 return false;
1180         }
1181
1182         head_pipe = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
1183
1184         if (!head_pipe) {
1185                 dm_error("Head pipe not found for stream_state %p !\n", stream);
1186                 return false;
1187         }
1188
1189         tail_pipe = resource_get_tail_pipe_for_stream(&context->res_ctx, stream);
1190         ASSERT(tail_pipe);
1191
1192         free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
1193
1194 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1195         if (!free_pipe) {
1196                 int pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
1197                 if (pipe_idx >= 0)
1198                         free_pipe = &context->res_ctx.pipe_ctx[pipe_idx];
1199         }
1200 #endif
1201         if (!free_pipe)
1202                 return false;
1203
1204         /* retain new surfaces */
1205         dc_plane_state_retain(plane_state);
1206         free_pipe->plane_state = plane_state;
1207
1208         if (head_pipe != free_pipe) {
1209                 free_pipe->stream_res.tg = tail_pipe->stream_res.tg;
1210                 free_pipe->stream_res.abm = tail_pipe->stream_res.abm;
1211                 free_pipe->stream_res.opp = tail_pipe->stream_res.opp;
1212                 free_pipe->stream_res.stream_enc = tail_pipe->stream_res.stream_enc;
1213                 free_pipe->stream_res.audio = tail_pipe->stream_res.audio;
1214                 free_pipe->clock_source = tail_pipe->clock_source;
1215                 free_pipe->top_pipe = tail_pipe;
1216                 tail_pipe->bottom_pipe = free_pipe;
1217         }
1218
1219         /* assign new surfaces*/
1220         stream_status->plane_states[stream_status->plane_count] = plane_state;
1221
1222         stream_status->plane_count++;
1223
1224         return true;
1225 }
1226
1227 bool dc_remove_plane_from_context(
1228                 const struct dc *dc,
1229                 struct dc_stream_state *stream,
1230                 struct dc_plane_state *plane_state,
1231                 struct dc_state *context)
1232 {
1233         int i;
1234         struct dc_stream_status *stream_status = NULL;
1235         struct resource_pool *pool = dc->res_pool;
1236
1237         for (i = 0; i < context->stream_count; i++)
1238                 if (context->streams[i] == stream) {
1239                         stream_status = &context->stream_status[i];
1240                         break;
1241                 }
1242
1243         if (stream_status == NULL) {
1244                 dm_error("Existing stream not found; failed to remove plane.\n");
1245                 return false;
1246         }
1247
1248         /* release pipe for plane*/
1249         for (i = pool->pipe_count - 1; i >= 0; i--) {
1250                 struct pipe_ctx *pipe_ctx;
1251
1252                 if (context->res_ctx.pipe_ctx[i].plane_state == plane_state) {
1253                         pipe_ctx = &context->res_ctx.pipe_ctx[i];
1254
1255                         if (pipe_ctx->top_pipe)
1256                                 pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe;
1257
1258                         /* Second condition is to avoid setting NULL to top pipe
1259                          * of tail pipe making it look like head pipe in subsequent
1260                          * deletes
1261                          */
1262                         if (pipe_ctx->bottom_pipe && pipe_ctx->top_pipe)
1263                                 pipe_ctx->bottom_pipe->top_pipe = pipe_ctx->top_pipe;
1264
1265                         /*
1266                          * For head pipe detach surfaces from pipe for tail
1267                          * pipe just zero it out
1268                          */
1269                         if (!pipe_ctx->top_pipe) {
1270                                 pipe_ctx->plane_state = NULL;
1271                                 pipe_ctx->bottom_pipe = NULL;
1272                         } else  {
1273                                 memset(pipe_ctx, 0, sizeof(*pipe_ctx));
1274                         }
1275                 }
1276         }
1277
1278
1279         for (i = 0; i < stream_status->plane_count; i++) {
1280                 if (stream_status->plane_states[i] == plane_state) {
1281
1282                         dc_plane_state_release(stream_status->plane_states[i]);
1283                         break;
1284                 }
1285         }
1286
1287         if (i == stream_status->plane_count) {
1288                 dm_error("Existing plane_state not found; failed to detach it!\n");
1289                 return false;
1290         }
1291
1292         stream_status->plane_count--;
1293
1294         /* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */
1295         for (; i < stream_status->plane_count; i++)
1296                 stream_status->plane_states[i] = stream_status->plane_states[i + 1];
1297
1298         stream_status->plane_states[stream_status->plane_count] = NULL;
1299
1300         return true;
1301 }
1302
1303 bool dc_rem_all_planes_for_stream(
1304                 const struct dc *dc,
1305                 struct dc_stream_state *stream,
1306                 struct dc_state *context)
1307 {
1308         int i, old_plane_count;
1309         struct dc_stream_status *stream_status = NULL;
1310         struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
1311
1312         for (i = 0; i < context->stream_count; i++)
1313                         if (context->streams[i] == stream) {
1314                                 stream_status = &context->stream_status[i];
1315                                 break;
1316                         }
1317
1318         if (stream_status == NULL) {
1319                 dm_error("Existing stream %p not found!\n", stream);
1320                 return false;
1321         }
1322
1323         old_plane_count = stream_status->plane_count;
1324
1325         for (i = 0; i < old_plane_count; i++)
1326                 del_planes[i] = stream_status->plane_states[i];
1327
1328         for (i = 0; i < old_plane_count; i++)
1329                 if (!dc_remove_plane_from_context(dc, stream, del_planes[i], context))
1330                         return false;
1331
1332         return true;
1333 }
1334
1335 static bool add_all_planes_for_stream(
1336                 const struct dc *dc,
1337                 struct dc_stream_state *stream,
1338                 const struct dc_validation_set set[],
1339                 int set_count,
1340                 struct dc_state *context)
1341 {
1342         int i, j;
1343
1344         for (i = 0; i < set_count; i++)
1345                 if (set[i].stream == stream)
1346                         break;
1347
1348         if (i == set_count) {
1349                 dm_error("Stream %p not found in set!\n", stream);
1350                 return false;
1351         }
1352
1353         for (j = 0; j < set[i].plane_count; j++)
1354                 if (!dc_add_plane_to_context(dc, stream, set[i].plane_states[j], context))
1355                         return false;
1356
1357         return true;
1358 }
1359
1360 bool dc_add_all_planes_for_stream(
1361                 const struct dc *dc,
1362                 struct dc_stream_state *stream,
1363                 struct dc_plane_state * const *plane_states,
1364                 int plane_count,
1365                 struct dc_state *context)
1366 {
1367         struct dc_validation_set set;
1368         int i;
1369
1370         set.stream = stream;
1371         set.plane_count = plane_count;
1372
1373         for (i = 0; i < plane_count; i++)
1374                 set.plane_states[i] = plane_states[i];
1375
1376         return add_all_planes_for_stream(dc, stream, &set, 1, context);
1377 }
1378
1379
1380 static bool is_hdr_static_meta_changed(struct dc_stream_state *cur_stream,
1381         struct dc_stream_state *new_stream)
1382 {
1383         if (cur_stream == NULL)
1384                 return true;
1385
1386         if (memcmp(&cur_stream->hdr_static_metadata,
1387                         &new_stream->hdr_static_metadata,
1388                         sizeof(struct dc_info_packet)) != 0)
1389                 return true;
1390
1391         return false;
1392 }
1393
1394 static bool is_vsc_info_packet_changed(struct dc_stream_state *cur_stream,
1395                 struct dc_stream_state *new_stream)
1396 {
1397         if (cur_stream == NULL)
1398                 return true;
1399
1400         if (memcmp(&cur_stream->vsc_infopacket,
1401                         &new_stream->vsc_infopacket,
1402                         sizeof(struct dc_info_packet)) != 0)
1403                 return true;
1404
1405         return false;
1406 }
1407
1408 static bool is_timing_changed(struct dc_stream_state *cur_stream,
1409                 struct dc_stream_state *new_stream)
1410 {
1411         if (cur_stream == NULL)
1412                 return true;
1413
1414         /* If sink pointer changed, it means this is a hotplug, we should do
1415          * full hw setting.
1416          */
1417         if (cur_stream->sink != new_stream->sink)
1418                 return true;
1419
1420         /* If output color space is changed, need to reprogram info frames */
1421         if (cur_stream->output_color_space != new_stream->output_color_space)
1422                 return true;
1423
1424         return memcmp(
1425                 &cur_stream->timing,
1426                 &new_stream->timing,
1427                 sizeof(struct dc_crtc_timing)) != 0;
1428 }
1429
1430 static bool are_stream_backends_same(
1431         struct dc_stream_state *stream_a, struct dc_stream_state *stream_b)
1432 {
1433         if (stream_a == stream_b)
1434                 return true;
1435
1436         if (stream_a == NULL || stream_b == NULL)
1437                 return false;
1438
1439         if (is_timing_changed(stream_a, stream_b))
1440                 return false;
1441
1442         if (is_hdr_static_meta_changed(stream_a, stream_b))
1443                 return false;
1444
1445         if (stream_a->dpms_off != stream_b->dpms_off)
1446                 return false;
1447
1448         if (is_vsc_info_packet_changed(stream_a, stream_b))
1449                 return false;
1450
1451         return true;
1452 }
1453
1454 /**
1455  * dc_is_stream_unchanged() - Compare two stream states for equivalence.
1456  *
1457  * Checks if there a difference between the two states
1458  * that would require a mode change.
1459  *
1460  * Does not compare cursor position or attributes.
1461  */
1462 bool dc_is_stream_unchanged(
1463         struct dc_stream_state *old_stream, struct dc_stream_state *stream)
1464 {
1465
1466         if (!are_stream_backends_same(old_stream, stream))
1467                 return false;
1468
1469         return true;
1470 }
1471
1472 /**
1473  * dc_is_stream_scaling_unchanged() - Compare scaling rectangles of two streams.
1474  */
1475 bool dc_is_stream_scaling_unchanged(
1476         struct dc_stream_state *old_stream, struct dc_stream_state *stream)
1477 {
1478         if (old_stream == stream)
1479                 return true;
1480
1481         if (old_stream == NULL || stream == NULL)
1482                 return false;
1483
1484         if (memcmp(&old_stream->src,
1485                         &stream->src,
1486                         sizeof(struct rect)) != 0)
1487                 return false;
1488
1489         if (memcmp(&old_stream->dst,
1490                         &stream->dst,
1491                         sizeof(struct rect)) != 0)
1492                 return false;
1493
1494         return true;
1495 }
1496
1497 static void update_stream_engine_usage(
1498                 struct resource_context *res_ctx,
1499                 const struct resource_pool *pool,
1500                 struct stream_encoder *stream_enc,
1501                 bool acquired)
1502 {
1503         int i;
1504
1505         for (i = 0; i < pool->stream_enc_count; i++) {
1506                 if (pool->stream_enc[i] == stream_enc)
1507                         res_ctx->is_stream_enc_acquired[i] = acquired;
1508         }
1509 }
1510
1511 /* TODO: release audio object */
1512 void update_audio_usage(
1513                 struct resource_context *res_ctx,
1514                 const struct resource_pool *pool,
1515                 struct audio *audio,
1516                 bool acquired)
1517 {
1518         int i;
1519         for (i = 0; i < pool->audio_count; i++) {
1520                 if (pool->audios[i] == audio)
1521                         res_ctx->is_audio_acquired[i] = acquired;
1522         }
1523 }
1524
1525 static int acquire_first_free_pipe(
1526                 struct resource_context *res_ctx,
1527                 const struct resource_pool *pool,
1528                 struct dc_stream_state *stream)
1529 {
1530         int i;
1531
1532         for (i = 0; i < pool->pipe_count; i++) {
1533                 if (!res_ctx->pipe_ctx[i].stream) {
1534                         struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
1535
1536                         pipe_ctx->stream_res.tg = pool->timing_generators[i];
1537                         pipe_ctx->plane_res.mi = pool->mis[i];
1538                         pipe_ctx->plane_res.hubp = pool->hubps[i];
1539                         pipe_ctx->plane_res.ipp = pool->ipps[i];
1540                         pipe_ctx->plane_res.xfm = pool->transforms[i];
1541                         pipe_ctx->plane_res.dpp = pool->dpps[i];
1542                         pipe_ctx->stream_res.opp = pool->opps[i];
1543                         if (pool->dpps[i])
1544                                 pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
1545                         pipe_ctx->pipe_idx = i;
1546
1547
1548                         pipe_ctx->stream = stream;
1549                         return i;
1550                 }
1551         }
1552         return -1;
1553 }
1554
1555 static struct stream_encoder *find_first_free_match_stream_enc_for_link(
1556                 struct resource_context *res_ctx,
1557                 const struct resource_pool *pool,
1558                 struct dc_stream_state *stream)
1559 {
1560         int i;
1561         int j = -1;
1562         struct dc_link *link = stream->link;
1563
1564         for (i = 0; i < pool->stream_enc_count; i++) {
1565                 if (!res_ctx->is_stream_enc_acquired[i] &&
1566                                 pool->stream_enc[i]) {
1567                         /* Store first available for MST second display
1568                          * in daisy chain use case */
1569                         j = i;
1570                         if (pool->stream_enc[i]->id ==
1571                                         link->link_enc->preferred_engine)
1572                                 return pool->stream_enc[i];
1573                 }
1574         }
1575
1576         /*
1577          * below can happen in cases when stream encoder is acquired:
1578          * 1) for second MST display in chain, so preferred engine already
1579          * acquired;
1580          * 2) for another link, which preferred engine already acquired by any
1581          * MST configuration.
1582          *
1583          * If signal is of DP type and preferred engine not found, return last available
1584          *
1585          * TODO - This is just a patch up and a generic solution is
1586          * required for non DP connectors.
1587          */
1588
1589         if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT)
1590                 return pool->stream_enc[j];
1591
1592         return NULL;
1593 }
1594
1595 static struct audio *find_first_free_audio(
1596                 struct resource_context *res_ctx,
1597                 const struct resource_pool *pool,
1598                 enum engine_id id)
1599 {
1600         int i;
1601         for (i = 0; i < pool->audio_count; i++) {
1602                 if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {
1603                         /*we have enough audio endpoint, find the matching inst*/
1604                         if (id != i)
1605                                 continue;
1606
1607                         return pool->audios[i];
1608                 }
1609         }
1610         /*not found the matching one, first come first serve*/
1611         for (i = 0; i < pool->audio_count; i++) {
1612                 if (res_ctx->is_audio_acquired[i] == false) {
1613                         return pool->audios[i];
1614                 }
1615         }
1616         return 0;
1617 }
1618
1619 bool resource_is_stream_unchanged(
1620         struct dc_state *old_context, struct dc_stream_state *stream)
1621 {
1622         int i;
1623
1624         for (i = 0; i < old_context->stream_count; i++) {
1625                 struct dc_stream_state *old_stream = old_context->streams[i];
1626
1627                 if (are_stream_backends_same(old_stream, stream))
1628                                 return true;
1629         }
1630
1631         return false;
1632 }
1633
1634 /**
1635  * dc_add_stream_to_ctx() - Add a new dc_stream_state to a dc_state.
1636  */
1637 enum dc_status dc_add_stream_to_ctx(
1638                 struct dc *dc,
1639                 struct dc_state *new_ctx,
1640                 struct dc_stream_state *stream)
1641 {
1642         enum dc_status res;
1643         DC_LOGGER_INIT(dc->ctx->logger);
1644
1645         if (new_ctx->stream_count >= dc->res_pool->timing_generator_count) {
1646                 DC_LOG_WARNING("Max streams reached, can't add stream %p !\n", stream);
1647                 return DC_ERROR_UNEXPECTED;
1648         }
1649
1650         new_ctx->streams[new_ctx->stream_count] = stream;
1651         dc_stream_retain(stream);
1652         new_ctx->stream_count++;
1653
1654         res = dc->res_pool->funcs->add_stream_to_ctx(dc, new_ctx, stream);
1655         if (res != DC_OK)
1656                 DC_LOG_WARNING("Adding stream %p to context failed with err %d!\n", stream, res);
1657
1658         return res;
1659 }
1660
1661 /**
1662  * dc_remove_stream_from_ctx() - Remove a stream from a dc_state.
1663  */
1664 enum dc_status dc_remove_stream_from_ctx(
1665                         struct dc *dc,
1666                         struct dc_state *new_ctx,
1667                         struct dc_stream_state *stream)
1668 {
1669         int i;
1670         struct dc_context *dc_ctx = dc->ctx;
1671         struct pipe_ctx *del_pipe = NULL;
1672
1673         /* Release primary pipe */
1674         for (i = 0; i < MAX_PIPES; i++) {
1675                 if (new_ctx->res_ctx.pipe_ctx[i].stream == stream &&
1676                                 !new_ctx->res_ctx.pipe_ctx[i].top_pipe) {
1677                         del_pipe = &new_ctx->res_ctx.pipe_ctx[i];
1678
1679                         ASSERT(del_pipe->stream_res.stream_enc);
1680                         update_stream_engine_usage(
1681                                         &new_ctx->res_ctx,
1682                                                 dc->res_pool,
1683                                         del_pipe->stream_res.stream_enc,
1684                                         false);
1685
1686                         if (del_pipe->stream_res.audio)
1687                                 update_audio_usage(
1688                                         &new_ctx->res_ctx,
1689                                         dc->res_pool,
1690                                         del_pipe->stream_res.audio,
1691                                         false);
1692
1693                         resource_unreference_clock_source(&new_ctx->res_ctx,
1694                                                           dc->res_pool,
1695                                                           del_pipe->clock_source);
1696
1697                         if (dc->res_pool->funcs->remove_stream_from_ctx)
1698                                 dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream);
1699
1700                         memset(del_pipe, 0, sizeof(*del_pipe));
1701
1702                         break;
1703                 }
1704         }
1705
1706         if (!del_pipe) {
1707                 DC_ERROR("Pipe not found for stream %p !\n", stream);
1708                 return DC_ERROR_UNEXPECTED;
1709         }
1710
1711         for (i = 0; i < new_ctx->stream_count; i++)
1712                 if (new_ctx->streams[i] == stream)
1713                         break;
1714
1715         if (new_ctx->streams[i] != stream) {
1716                 DC_ERROR("Context doesn't have stream %p !\n", stream);
1717                 return DC_ERROR_UNEXPECTED;
1718         }
1719
1720         dc_stream_release(new_ctx->streams[i]);
1721         new_ctx->stream_count--;
1722
1723         /* Trim back arrays */
1724         for (; i < new_ctx->stream_count; i++) {
1725                 new_ctx->streams[i] = new_ctx->streams[i + 1];
1726                 new_ctx->stream_status[i] = new_ctx->stream_status[i + 1];
1727         }
1728
1729         new_ctx->streams[new_ctx->stream_count] = NULL;
1730         memset(
1731                         &new_ctx->stream_status[new_ctx->stream_count],
1732                         0,
1733                         sizeof(new_ctx->stream_status[0]));
1734
1735         return DC_OK;
1736 }
1737
1738 static struct dc_stream_state *find_pll_sharable_stream(
1739                 struct dc_stream_state *stream_needs_pll,
1740                 struct dc_state *context)
1741 {
1742         int i;
1743
1744         for (i = 0; i < context->stream_count; i++) {
1745                 struct dc_stream_state *stream_has_pll = context->streams[i];
1746
1747                 /* We are looking for non dp, non virtual stream */
1748                 if (resource_are_streams_timing_synchronizable(
1749                         stream_needs_pll, stream_has_pll)
1750                         && !dc_is_dp_signal(stream_has_pll->signal)
1751                         && stream_has_pll->link->connector_signal
1752                         != SIGNAL_TYPE_VIRTUAL)
1753                         return stream_has_pll;
1754
1755         }
1756
1757         return NULL;
1758 }
1759
1760 static int get_norm_pix_clk(const struct dc_crtc_timing *timing)
1761 {
1762         uint32_t pix_clk = timing->pix_clk_100hz;
1763         uint32_t normalized_pix_clk = pix_clk;
1764
1765         if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
1766                 pix_clk /= 2;
1767         if (timing->pixel_encoding != PIXEL_ENCODING_YCBCR422) {
1768                 switch (timing->display_color_depth) {
1769                 case COLOR_DEPTH_888:
1770                         normalized_pix_clk = pix_clk;
1771                         break;
1772                 case COLOR_DEPTH_101010:
1773                         normalized_pix_clk = (pix_clk * 30) / 24;
1774                         break;
1775                 case COLOR_DEPTH_121212:
1776                         normalized_pix_clk = (pix_clk * 36) / 24;
1777                 break;
1778                 case COLOR_DEPTH_161616:
1779                         normalized_pix_clk = (pix_clk * 48) / 24;
1780                 break;
1781                 default:
1782                         ASSERT(0);
1783                 break;
1784                 }
1785         }
1786         return normalized_pix_clk;
1787 }
1788
1789 static void calculate_phy_pix_clks(struct dc_stream_state *stream)
1790 {
1791         /* update actual pixel clock on all streams */
1792         if (dc_is_hdmi_signal(stream->signal))
1793                 stream->phy_pix_clk = get_norm_pix_clk(
1794                         &stream->timing) / 10;
1795         else
1796                 stream->phy_pix_clk =
1797                         stream->timing.pix_clk_100hz / 10;
1798
1799         if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
1800                 stream->phy_pix_clk *= 2;
1801 }
1802
1803 enum dc_status resource_map_pool_resources(
1804                 const struct dc  *dc,
1805                 struct dc_state *context,
1806                 struct dc_stream_state *stream)
1807 {
1808         const struct resource_pool *pool = dc->res_pool;
1809         int i;
1810         struct dc_context *dc_ctx = dc->ctx;
1811         struct pipe_ctx *pipe_ctx = NULL;
1812         int pipe_idx = -1;
1813
1814         /* TODO Check if this is needed */
1815         /*if (!resource_is_stream_unchanged(old_context, stream)) {
1816                         if (stream != NULL && old_context->streams[i] != NULL) {
1817                                 stream->bit_depth_params =
1818                                                 old_context->streams[i]->bit_depth_params;
1819                                 stream->clamping = old_context->streams[i]->clamping;
1820                                 continue;
1821                         }
1822                 }
1823         */
1824
1825         calculate_phy_pix_clks(stream);
1826
1827         /* acquire new resources */
1828         pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
1829
1830 #ifdef CONFIG_DRM_AMD_DC_DCN1_0
1831         if (pipe_idx < 0)
1832                 pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
1833 #endif
1834
1835         if (pipe_idx < 0 || context->res_ctx.pipe_ctx[pipe_idx].stream_res.tg == NULL)
1836                 return DC_NO_CONTROLLER_RESOURCE;
1837
1838         pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
1839
1840         pipe_ctx->stream_res.stream_enc =
1841                 find_first_free_match_stream_enc_for_link(
1842                         &context->res_ctx, pool, stream);
1843
1844         if (!pipe_ctx->stream_res.stream_enc)
1845                 return DC_NO_STREAM_ENC_RESOURCE;
1846
1847         update_stream_engine_usage(
1848                 &context->res_ctx, pool,
1849                 pipe_ctx->stream_res.stream_enc,
1850                 true);
1851
1852         /* TODO: Add check if ASIC support and EDID audio */
1853         if (!stream->converter_disable_audio &&
1854             dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
1855             stream->audio_info.mode_count) {
1856                 pipe_ctx->stream_res.audio = find_first_free_audio(
1857                 &context->res_ctx, pool, pipe_ctx->stream_res.stream_enc->id);
1858
1859                 /*
1860                  * Audio assigned in order first come first get.
1861                  * There are asics which has number of audio
1862                  * resources less then number of pipes
1863                  */
1864                 if (pipe_ctx->stream_res.audio)
1865                         update_audio_usage(&context->res_ctx, pool,
1866                                            pipe_ctx->stream_res.audio, true);
1867         }
1868
1869         /* Add ABM to the resource if on EDP */
1870         if (pipe_ctx->stream && dc_is_embedded_signal(pipe_ctx->stream->signal))
1871                 pipe_ctx->stream_res.abm = pool->abm;
1872
1873         for (i = 0; i < context->stream_count; i++)
1874                 if (context->streams[i] == stream) {
1875                         context->stream_status[i].primary_otg_inst = pipe_ctx->stream_res.tg->inst;
1876                         context->stream_status[i].stream_enc_inst = pipe_ctx->stream_res.stream_enc->id;
1877                         return DC_OK;
1878                 }
1879
1880         DC_ERROR("Stream %p not found in new ctx!\n", stream);
1881         return DC_ERROR_UNEXPECTED;
1882 }
1883
1884 /**
1885  * dc_resource_state_copy_construct_current() - Creates a new dc_state from existing state
1886  * Is a shallow copy.  Increments refcounts on existing streams and planes.
1887  * @dc: copy out of dc->current_state
1888  * @dst_ctx: copy into this
1889  */
1890 void dc_resource_state_copy_construct_current(
1891                 const struct dc *dc,
1892                 struct dc_state *dst_ctx)
1893 {
1894         dc_resource_state_copy_construct(dc->current_state, dst_ctx);
1895 }
1896
1897
1898 void dc_resource_state_construct(
1899                 const struct dc *dc,
1900                 struct dc_state *dst_ctx)
1901 {
1902         dst_ctx->dccg = dc->res_pool->clk_mgr;
1903 }
1904
1905 /**
1906  * dc_validate_global_state() - Determine if HW can support a given state
1907  * Checks HW resource availability and bandwidth requirement.
1908  * @dc: dc struct for this driver
1909  * @new_ctx: state to be validated
1910  *
1911  * Return: DC_OK if the result can be programmed.  Otherwise, an error code.
1912  */
1913 enum dc_status dc_validate_global_state(
1914                 struct dc *dc,
1915                 struct dc_state *new_ctx)
1916 {
1917         enum dc_status result = DC_ERROR_UNEXPECTED;
1918         int i, j;
1919
1920         if (!new_ctx)
1921                 return DC_ERROR_UNEXPECTED;
1922
1923         if (dc->res_pool->funcs->validate_global) {
1924                 result = dc->res_pool->funcs->validate_global(dc, new_ctx);
1925                 if (result != DC_OK)
1926                         return result;
1927         }
1928
1929         for (i = 0; i < new_ctx->stream_count; i++) {
1930                 struct dc_stream_state *stream = new_ctx->streams[i];
1931
1932                 for (j = 0; j < dc->res_pool->pipe_count; j++) {
1933                         struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[j];
1934
1935                         if (pipe_ctx->stream != stream)
1936                                 continue;
1937
1938                         if (dc->res_pool->funcs->get_default_swizzle_mode &&
1939                                         pipe_ctx->plane_state &&
1940                                         pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) {
1941                                 result = dc->res_pool->funcs->get_default_swizzle_mode(pipe_ctx->plane_state);
1942                                 if (result != DC_OK)
1943                                         return result;
1944                         }
1945
1946                         /* Switch to dp clock source only if there is
1947                          * no non dp stream that shares the same timing
1948                          * with the dp stream.
1949                          */
1950                         if (dc_is_dp_signal(pipe_ctx->stream->signal) &&
1951                                 !find_pll_sharable_stream(stream, new_ctx)) {
1952
1953                                 resource_unreference_clock_source(
1954                                                 &new_ctx->res_ctx,
1955                                                 dc->res_pool,
1956                                                 pipe_ctx->clock_source);
1957
1958                                 pipe_ctx->clock_source = dc->res_pool->dp_clock_source;
1959                                 resource_reference_clock_source(
1960                                                 &new_ctx->res_ctx,
1961                                                 dc->res_pool,
1962                                                  pipe_ctx->clock_source);
1963                         }
1964                 }
1965         }
1966
1967         result = resource_build_scaling_params_for_context(dc, new_ctx);
1968
1969         if (result == DC_OK)
1970                 if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx))
1971                         result = DC_FAIL_BANDWIDTH_VALIDATE;
1972
1973         return result;
1974 }
1975
1976 static void patch_gamut_packet_checksum(
1977                 struct dc_info_packet *gamut_packet)
1978 {
1979         /* For gamut we recalc checksum */
1980         if (gamut_packet->valid) {
1981                 uint8_t chk_sum = 0;
1982                 uint8_t *ptr;
1983                 uint8_t i;
1984
1985                 /*start of the Gamut data. */
1986                 ptr = &gamut_packet->sb[3];
1987
1988                 for (i = 0; i <= gamut_packet->sb[1]; i++)
1989                         chk_sum += ptr[i];
1990
1991                 gamut_packet->sb[2] = (uint8_t) (0x100 - chk_sum);
1992         }
1993 }
1994
1995 static void set_avi_info_frame(
1996                 struct dc_info_packet *info_packet,
1997                 struct pipe_ctx *pipe_ctx)
1998 {
1999         struct dc_stream_state *stream = pipe_ctx->stream;
2000         enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
2001         uint32_t pixel_encoding = 0;
2002         enum scanning_type scan_type = SCANNING_TYPE_NODATA;
2003         enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA;
2004         bool itc = false;
2005         uint8_t itc_value = 0;
2006         uint8_t cn0_cn1 = 0;
2007         unsigned int cn0_cn1_value = 0;
2008         uint8_t *check_sum = NULL;
2009         uint8_t byte_index = 0;
2010         union hdmi_info_packet hdmi_info;
2011         union display_content_support support = {0};
2012         unsigned int vic = pipe_ctx->stream->timing.vic;
2013         enum dc_timing_3d_format format;
2014
2015         memset(&hdmi_info, 0, sizeof(union hdmi_info_packet));
2016
2017         color_space = pipe_ctx->stream->output_color_space;
2018         if (color_space == COLOR_SPACE_UNKNOWN)
2019                 color_space = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ?
2020                         COLOR_SPACE_SRGB:COLOR_SPACE_YCBCR709;
2021
2022         /* Initialize header */
2023         hdmi_info.bits.header.info_frame_type = HDMI_INFOFRAME_TYPE_AVI;
2024         /* InfoFrameVersion_3 is defined by CEA861F (Section 6.4), but shall
2025         * not be used in HDMI 2.0 (Section 10.1) */
2026         hdmi_info.bits.header.version = 2;
2027         hdmi_info.bits.header.length = HDMI_AVI_INFOFRAME_SIZE;
2028
2029         /*
2030          * IDO-defined (Y2,Y1,Y0 = 1,1,1) shall not be used by devices built
2031          * according to HDMI 2.0 spec (Section 10.1)
2032          */
2033
2034         switch (stream->timing.pixel_encoding) {
2035         case PIXEL_ENCODING_YCBCR422:
2036                 pixel_encoding = 1;
2037                 break;
2038
2039         case PIXEL_ENCODING_YCBCR444:
2040                 pixel_encoding = 2;
2041                 break;
2042         case PIXEL_ENCODING_YCBCR420:
2043                 pixel_encoding = 3;
2044                 break;
2045
2046         case PIXEL_ENCODING_RGB:
2047         default:
2048                 pixel_encoding = 0;
2049         }
2050
2051         /* Y0_Y1_Y2 : The pixel encoding */
2052         /* H14b AVI InfoFrame has extension on Y-field from 2 bits to 3 bits */
2053         hdmi_info.bits.Y0_Y1_Y2 = pixel_encoding;
2054
2055         /* A0 = 1 Active Format Information valid */
2056         hdmi_info.bits.A0 = ACTIVE_FORMAT_VALID;
2057
2058         /* B0, B1 = 3; Bar info data is valid */
2059         hdmi_info.bits.B0_B1 = BAR_INFO_BOTH_VALID;
2060
2061         hdmi_info.bits.SC0_SC1 = PICTURE_SCALING_UNIFORM;
2062
2063         /* S0, S1 : Underscan / Overscan */
2064         /* TODO: un-hardcode scan type */
2065         scan_type = SCANNING_TYPE_UNDERSCAN;
2066         hdmi_info.bits.S0_S1 = scan_type;
2067
2068         /* C0, C1 : Colorimetry */
2069         if (color_space == COLOR_SPACE_YCBCR709 ||
2070                         color_space == COLOR_SPACE_YCBCR709_LIMITED)
2071                 hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709;
2072         else if (color_space == COLOR_SPACE_YCBCR601 ||
2073                         color_space == COLOR_SPACE_YCBCR601_LIMITED)
2074                 hdmi_info.bits.C0_C1 = COLORIMETRY_ITU601;
2075         else {
2076                 hdmi_info.bits.C0_C1 = COLORIMETRY_NO_DATA;
2077         }
2078         if (color_space == COLOR_SPACE_2020_RGB_FULLRANGE ||
2079                         color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE ||
2080                         color_space == COLOR_SPACE_2020_YCBCR) {
2081                 hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR;
2082                 hdmi_info.bits.C0_C1   = COLORIMETRY_EXTENDED;
2083         } else if (color_space == COLOR_SPACE_ADOBERGB) {
2084                 hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_ADOBERGB;
2085                 hdmi_info.bits.C0_C1   = COLORIMETRY_EXTENDED;
2086         }
2087
2088         /* TODO: un-hardcode aspect ratio */
2089         aspect = stream->timing.aspect_ratio;
2090
2091         switch (aspect) {
2092         case ASPECT_RATIO_4_3:
2093         case ASPECT_RATIO_16_9:
2094                 hdmi_info.bits.M0_M1 = aspect;
2095                 break;
2096
2097         case ASPECT_RATIO_NO_DATA:
2098         case ASPECT_RATIO_64_27:
2099         case ASPECT_RATIO_256_135:
2100         default:
2101                 hdmi_info.bits.M0_M1 = 0;
2102         }
2103
2104         /* Active Format Aspect ratio - same as Picture Aspect Ratio. */
2105         hdmi_info.bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE;
2106
2107         /* TODO: un-hardcode cn0_cn1 and itc */
2108
2109         cn0_cn1 = 0;
2110         cn0_cn1_value = 0;
2111
2112         itc = true;
2113         itc_value = 1;
2114
2115         support = stream->content_support;
2116
2117         if (itc) {
2118                 if (!support.bits.valid_content_type) {
2119                         cn0_cn1_value = 0;
2120                 } else {
2121                         if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GRAPHICS) {
2122                                 if (support.bits.graphics_content == 1) {
2123                                         cn0_cn1_value = 0;
2124                                 }
2125                         } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_PHOTO) {
2126                                 if (support.bits.photo_content == 1) {
2127                                         cn0_cn1_value = 1;
2128                                 } else {
2129                                         cn0_cn1_value = 0;
2130                                         itc_value = 0;
2131                                 }
2132                         } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_CINEMA) {
2133                                 if (support.bits.cinema_content == 1) {
2134                                         cn0_cn1_value = 2;
2135                                 } else {
2136                                         cn0_cn1_value = 0;
2137                                         itc_value = 0;
2138                                 }
2139                         } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GAME) {
2140                                 if (support.bits.game_content == 1) {
2141                                         cn0_cn1_value = 3;
2142                                 } else {
2143                                         cn0_cn1_value = 0;
2144                                         itc_value = 0;
2145                                 }
2146                         }
2147                 }
2148                 hdmi_info.bits.CN0_CN1 = cn0_cn1_value;
2149                 hdmi_info.bits.ITC = itc_value;
2150         }
2151
2152         /* TODO : We should handle YCC quantization */
2153         /* but we do not have matrix calculation */
2154         if (stream->qs_bit == 1 &&
2155                         stream->qy_bit == 1) {
2156                 if (color_space == COLOR_SPACE_SRGB ||
2157                         color_space == COLOR_SPACE_2020_RGB_FULLRANGE) {
2158                         hdmi_info.bits.Q0_Q1   = RGB_QUANTIZATION_FULL_RANGE;
2159                         hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_FULL_RANGE;
2160                 } else if (color_space == COLOR_SPACE_SRGB_LIMITED ||
2161                                         color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) {
2162                         hdmi_info.bits.Q0_Q1   = RGB_QUANTIZATION_LIMITED_RANGE;
2163                         hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
2164                 } else {
2165                         hdmi_info.bits.Q0_Q1   = RGB_QUANTIZATION_DEFAULT_RANGE;
2166                         hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
2167                 }
2168         } else {
2169                 hdmi_info.bits.Q0_Q1   = RGB_QUANTIZATION_DEFAULT_RANGE;
2170                 hdmi_info.bits.YQ0_YQ1   = YYC_QUANTIZATION_LIMITED_RANGE;
2171         }
2172
2173         ///VIC
2174         format = stream->timing.timing_3d_format;
2175         /*todo, add 3DStereo support*/
2176         if (format != TIMING_3D_FORMAT_NONE) {
2177                 // Based on HDMI specs hdmi vic needs to be converted to cea vic when 3D is enabled
2178                 switch (pipe_ctx->stream->timing.hdmi_vic) {
2179                 case 1:
2180                         vic = 95;
2181                         break;
2182                 case 2:
2183                         vic = 94;
2184                         break;
2185                 case 3:
2186                         vic = 93;
2187                         break;
2188                 case 4:
2189                         vic = 98;
2190                         break;
2191                 default:
2192                         break;
2193                 }
2194         }
2195         hdmi_info.bits.VIC0_VIC7 = vic;
2196
2197         /* pixel repetition
2198          * PR0 - PR3 start from 0 whereas pHwPathMode->mode.timing.flags.pixel
2199          * repetition start from 1 */
2200         hdmi_info.bits.PR0_PR3 = 0;
2201
2202         /* Bar Info
2203          * barTop:    Line Number of End of Top Bar.
2204          * barBottom: Line Number of Start of Bottom Bar.
2205          * barLeft:   Pixel Number of End of Left Bar.
2206          * barRight:  Pixel Number of Start of Right Bar. */
2207         hdmi_info.bits.bar_top = stream->timing.v_border_top;
2208         hdmi_info.bits.bar_bottom = (stream->timing.v_total
2209                         - stream->timing.v_border_bottom + 1);
2210         hdmi_info.bits.bar_left  = stream->timing.h_border_left;
2211         hdmi_info.bits.bar_right = (stream->timing.h_total
2212                         - stream->timing.h_border_right + 1);
2213
2214         /* check_sum - Calculate AFMT_AVI_INFO0 ~ AFMT_AVI_INFO3 */
2215         check_sum = &hdmi_info.packet_raw_data.sb[0];
2216
2217         *check_sum = HDMI_INFOFRAME_TYPE_AVI + HDMI_AVI_INFOFRAME_SIZE + 2;
2218
2219         for (byte_index = 1; byte_index <= HDMI_AVI_INFOFRAME_SIZE; byte_index++)
2220                 *check_sum += hdmi_info.packet_raw_data.sb[byte_index];
2221
2222         /* one byte complement */
2223         *check_sum = (uint8_t) (0x100 - *check_sum);
2224
2225         /* Store in hw_path_mode */
2226         info_packet->hb0 = hdmi_info.packet_raw_data.hb0;
2227         info_packet->hb1 = hdmi_info.packet_raw_data.hb1;
2228         info_packet->hb2 = hdmi_info.packet_raw_data.hb2;
2229
2230         for (byte_index = 0; byte_index < sizeof(hdmi_info.packet_raw_data.sb); byte_index++)
2231                 info_packet->sb[byte_index] = hdmi_info.packet_raw_data.sb[byte_index];
2232
2233         info_packet->valid = true;
2234 }
2235
2236 static void set_vendor_info_packet(
2237                 struct dc_info_packet *info_packet,
2238                 struct dc_stream_state *stream)
2239 {
2240         /* SPD info packet for FreeSync */
2241
2242         /* Check if Freesync is supported. Return if false. If true,
2243          * set the corresponding bit in the info packet
2244          */
2245         if (!stream->vsp_infopacket.valid)
2246                 return;
2247
2248         *info_packet = stream->vsp_infopacket;
2249 }
2250
2251 static void set_spd_info_packet(
2252                 struct dc_info_packet *info_packet,
2253                 struct dc_stream_state *stream)
2254 {
2255         /* SPD info packet for FreeSync */
2256
2257         /* Check if Freesync is supported. Return if false. If true,
2258          * set the corresponding bit in the info packet
2259          */
2260         if (!stream->vrr_infopacket.valid)
2261                 return;
2262
2263         *info_packet = stream->vrr_infopacket;
2264 }
2265
2266 static void set_hdr_static_info_packet(
2267                 struct dc_info_packet *info_packet,
2268                 struct dc_stream_state *stream)
2269 {
2270         /* HDR Static Metadata info packet for HDR10 */
2271
2272         if (!stream->hdr_static_metadata.valid ||
2273                         stream->use_dynamic_meta)
2274                 return;
2275
2276         *info_packet = stream->hdr_static_metadata;
2277 }
2278
2279 static void set_vsc_info_packet(
2280                 struct dc_info_packet *info_packet,
2281                 struct dc_stream_state *stream)
2282 {
2283         if (!stream->vsc_infopacket.valid)
2284                 return;
2285
2286         *info_packet = stream->vsc_infopacket;
2287 }
2288
2289 void dc_resource_state_destruct(struct dc_state *context)
2290 {
2291         int i, j;
2292
2293         for (i = 0; i < context->stream_count; i++) {
2294                 for (j = 0; j < context->stream_status[i].plane_count; j++)
2295                         dc_plane_state_release(
2296                                 context->stream_status[i].plane_states[j]);
2297
2298                 context->stream_status[i].plane_count = 0;
2299                 dc_stream_release(context->streams[i]);
2300                 context->streams[i] = NULL;
2301         }
2302 }
2303
2304 void dc_resource_state_copy_construct(
2305                 const struct dc_state *src_ctx,
2306                 struct dc_state *dst_ctx)
2307 {
2308         int i, j;
2309         struct kref refcount = dst_ctx->refcount;
2310
2311         *dst_ctx = *src_ctx;
2312
2313         for (i = 0; i < MAX_PIPES; i++) {
2314                 struct pipe_ctx *cur_pipe = &dst_ctx->res_ctx.pipe_ctx[i];
2315
2316                 if (cur_pipe->top_pipe)
2317                         cur_pipe->top_pipe =  &dst_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx];
2318
2319                 if (cur_pipe->bottom_pipe)
2320                         cur_pipe->bottom_pipe = &dst_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx];
2321
2322         }
2323
2324         for (i = 0; i < dst_ctx->stream_count; i++) {
2325                 dc_stream_retain(dst_ctx->streams[i]);
2326                 for (j = 0; j < dst_ctx->stream_status[i].plane_count; j++)
2327                         dc_plane_state_retain(
2328                                 dst_ctx->stream_status[i].plane_states[j]);
2329         }
2330
2331         /* context refcount should not be overridden */
2332         dst_ctx->refcount = refcount;
2333
2334 }
2335
2336 struct clock_source *dc_resource_find_first_free_pll(
2337                 struct resource_context *res_ctx,
2338                 const struct resource_pool *pool)
2339 {
2340         int i;
2341
2342         for (i = 0; i < pool->clk_src_count; ++i) {
2343                 if (res_ctx->clock_source_ref_count[i] == 0)
2344                         return pool->clock_sources[i];
2345         }
2346
2347         return NULL;
2348 }
2349
2350 void resource_build_info_frame(struct pipe_ctx *pipe_ctx)
2351 {
2352         enum signal_type signal = SIGNAL_TYPE_NONE;
2353         struct encoder_info_frame *info = &pipe_ctx->stream_res.encoder_info_frame;
2354
2355         /* default all packets to invalid */
2356         info->avi.valid = false;
2357         info->gamut.valid = false;
2358         info->vendor.valid = false;
2359         info->spd.valid = false;
2360         info->hdrsmd.valid = false;
2361         info->vsc.valid = false;
2362
2363         signal = pipe_ctx->stream->signal;
2364
2365         /* HDMi and DP have different info packets*/
2366         if (dc_is_hdmi_signal(signal)) {
2367                 set_avi_info_frame(&info->avi, pipe_ctx);
2368
2369                 set_vendor_info_packet(&info->vendor, pipe_ctx->stream);
2370
2371                 set_spd_info_packet(&info->spd, pipe_ctx->stream);
2372
2373                 set_hdr_static_info_packet(&info->hdrsmd, pipe_ctx->stream);
2374
2375         } else if (dc_is_dp_signal(signal)) {
2376                 set_vsc_info_packet(&info->vsc, pipe_ctx->stream);
2377
2378                 set_spd_info_packet(&info->spd, pipe_ctx->stream);
2379
2380                 set_hdr_static_info_packet(&info->hdrsmd, pipe_ctx->stream);
2381         }
2382
2383         patch_gamut_packet_checksum(&info->gamut);
2384 }
2385
2386 enum dc_status resource_map_clock_resources(
2387                 const struct dc  *dc,
2388                 struct dc_state *context,
2389                 struct dc_stream_state *stream)
2390 {
2391         /* acquire new resources */
2392         const struct resource_pool *pool = dc->res_pool;
2393         struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(
2394                                 &context->res_ctx, stream);
2395
2396         if (!pipe_ctx)
2397                 return DC_ERROR_UNEXPECTED;
2398
2399         if (dc_is_dp_signal(pipe_ctx->stream->signal)
2400                 || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
2401                 pipe_ctx->clock_source = pool->dp_clock_source;
2402         else {
2403                 pipe_ctx->clock_source = NULL;
2404
2405                 if (!dc->config.disable_disp_pll_sharing)
2406                         pipe_ctx->clock_source = resource_find_used_clk_src_for_sharing(
2407                                 &context->res_ctx,
2408                                 pipe_ctx);
2409
2410                 if (pipe_ctx->clock_source == NULL)
2411                         pipe_ctx->clock_source =
2412                                 dc_resource_find_first_free_pll(
2413                                         &context->res_ctx,
2414                                         pool);
2415         }
2416
2417         if (pipe_ctx->clock_source == NULL)
2418                 return DC_NO_CLOCK_SOURCE_RESOURCE;
2419
2420         resource_reference_clock_source(
2421                 &context->res_ctx, pool,
2422                 pipe_ctx->clock_source);
2423
2424         return DC_OK;
2425 }
2426
2427 /*
2428  * Note: We need to disable output if clock sources change,
2429  * since bios does optimization and doesn't apply if changing
2430  * PHY when not already disabled.
2431  */
2432 bool pipe_need_reprogram(
2433                 struct pipe_ctx *pipe_ctx_old,
2434                 struct pipe_ctx *pipe_ctx)
2435 {
2436         if (!pipe_ctx_old->stream)
2437                 return false;
2438
2439         if (pipe_ctx_old->stream->sink != pipe_ctx->stream->sink)
2440                 return true;
2441
2442         if (pipe_ctx_old->stream->signal != pipe_ctx->stream->signal)
2443                 return true;
2444
2445         if (pipe_ctx_old->stream_res.audio != pipe_ctx->stream_res.audio)
2446                 return true;
2447
2448         if (pipe_ctx_old->clock_source != pipe_ctx->clock_source
2449                         && pipe_ctx_old->stream != pipe_ctx->stream)
2450                 return true;
2451
2452         if (pipe_ctx_old->stream_res.stream_enc != pipe_ctx->stream_res.stream_enc)
2453                 return true;
2454
2455         if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream))
2456                 return true;
2457
2458         if (is_hdr_static_meta_changed(pipe_ctx_old->stream, pipe_ctx->stream))
2459                 return true;
2460
2461         if (pipe_ctx_old->stream->dpms_off != pipe_ctx->stream->dpms_off)
2462                 return true;
2463
2464         if (is_vsc_info_packet_changed(pipe_ctx_old->stream, pipe_ctx->stream))
2465                 return true;
2466
2467         return false;
2468 }
2469
2470 void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
2471                 struct bit_depth_reduction_params *fmt_bit_depth)
2472 {
2473         enum dc_dither_option option = stream->dither_option;
2474         enum dc_pixel_encoding pixel_encoding =
2475                         stream->timing.pixel_encoding;
2476
2477         memset(fmt_bit_depth, 0, sizeof(*fmt_bit_depth));
2478
2479         if (option == DITHER_OPTION_DEFAULT) {
2480                 switch (stream->timing.display_color_depth) {
2481                 case COLOR_DEPTH_666:
2482                         option = DITHER_OPTION_SPATIAL6;
2483                         break;
2484                 case COLOR_DEPTH_888:
2485                         option = DITHER_OPTION_SPATIAL8;
2486                         break;
2487                 case COLOR_DEPTH_101010:
2488                         option = DITHER_OPTION_SPATIAL10;
2489                         break;
2490                 default:
2491                         option = DITHER_OPTION_DISABLE;
2492                 }
2493         }
2494
2495         if (option == DITHER_OPTION_DISABLE)
2496                 return;
2497
2498         if (option == DITHER_OPTION_TRUN6) {
2499                 fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
2500                 fmt_bit_depth->flags.TRUNCATE_DEPTH = 0;
2501         } else if (option == DITHER_OPTION_TRUN8 ||
2502                         option == DITHER_OPTION_TRUN8_SPATIAL6 ||
2503                         option == DITHER_OPTION_TRUN8_FM6) {
2504                 fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
2505                 fmt_bit_depth->flags.TRUNCATE_DEPTH = 1;
2506         } else if (option == DITHER_OPTION_TRUN10        ||
2507                         option == DITHER_OPTION_TRUN10_SPATIAL6   ||
2508                         option == DITHER_OPTION_TRUN10_SPATIAL8   ||
2509                         option == DITHER_OPTION_TRUN10_FM8     ||
2510                         option == DITHER_OPTION_TRUN10_FM6     ||
2511                         option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) {
2512                 fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
2513                 fmt_bit_depth->flags.TRUNCATE_DEPTH = 2;
2514         }
2515
2516         /* special case - Formatter can only reduce by 4 bits at most.
2517          * When reducing from 12 to 6 bits,
2518          * HW recommends we use trunc with round mode
2519          * (if we did nothing, trunc to 10 bits would be used)
2520          * note that any 12->10 bit reduction is ignored prior to DCE8,
2521          * as the input was 10 bits.
2522          */
2523         if (option == DITHER_OPTION_SPATIAL6_FRAME_RANDOM ||
2524                         option == DITHER_OPTION_SPATIAL6 ||
2525                         option == DITHER_OPTION_FM6) {
2526                 fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
2527                 fmt_bit_depth->flags.TRUNCATE_DEPTH = 2;
2528                 fmt_bit_depth->flags.TRUNCATE_MODE = 1;
2529         }
2530
2531         /* spatial dither
2532          * note that spatial modes 1-3 are never used
2533          */
2534         if (option == DITHER_OPTION_SPATIAL6_FRAME_RANDOM            ||
2535                         option == DITHER_OPTION_SPATIAL6 ||
2536                         option == DITHER_OPTION_TRUN10_SPATIAL6      ||
2537                         option == DITHER_OPTION_TRUN8_SPATIAL6) {
2538                 fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
2539                 fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 0;
2540                 fmt_bit_depth->flags.HIGHPASS_RANDOM = 1;
2541                 fmt_bit_depth->flags.RGB_RANDOM =
2542                                 (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0;
2543         } else if (option == DITHER_OPTION_SPATIAL8_FRAME_RANDOM            ||
2544                         option == DITHER_OPTION_SPATIAL8 ||
2545                         option == DITHER_OPTION_SPATIAL8_FM6        ||
2546                         option == DITHER_OPTION_TRUN10_SPATIAL8      ||
2547                         option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) {
2548                 fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
2549                 fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 1;
2550                 fmt_bit_depth->flags.HIGHPASS_RANDOM = 1;
2551                 fmt_bit_depth->flags.RGB_RANDOM =
2552                                 (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0;
2553         } else if (option == DITHER_OPTION_SPATIAL10_FRAME_RANDOM ||
2554                         option == DITHER_OPTION_SPATIAL10 ||
2555                         option == DITHER_OPTION_SPATIAL10_FM8 ||
2556                         option == DITHER_OPTION_SPATIAL10_FM6) {
2557                 fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
2558                 fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 2;
2559                 fmt_bit_depth->flags.HIGHPASS_RANDOM = 1;
2560                 fmt_bit_depth->flags.RGB_RANDOM =
2561                                 (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0;
2562         }
2563
2564         if (option == DITHER_OPTION_SPATIAL6 ||
2565                         option == DITHER_OPTION_SPATIAL8 ||
2566                         option == DITHER_OPTION_SPATIAL10) {
2567                 fmt_bit_depth->flags.FRAME_RANDOM = 0;
2568         } else {
2569                 fmt_bit_depth->flags.FRAME_RANDOM = 1;
2570         }
2571
2572         //////////////////////
2573         //// temporal dither
2574         //////////////////////
2575         if (option == DITHER_OPTION_FM6           ||
2576                         option == DITHER_OPTION_SPATIAL8_FM6     ||
2577                         option == DITHER_OPTION_SPATIAL10_FM6     ||
2578                         option == DITHER_OPTION_TRUN10_FM6     ||
2579                         option == DITHER_OPTION_TRUN8_FM6      ||
2580                         option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) {
2581                 fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1;
2582                 fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 0;
2583         } else if (option == DITHER_OPTION_FM8        ||
2584                         option == DITHER_OPTION_SPATIAL10_FM8  ||
2585                         option == DITHER_OPTION_TRUN10_FM8) {
2586                 fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1;
2587                 fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 1;
2588         } else if (option == DITHER_OPTION_FM10) {
2589                 fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1;
2590                 fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 2;
2591         }
2592
2593         fmt_bit_depth->pixel_encoding = pixel_encoding;
2594 }
2595
2596 enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
2597 {
2598         struct dc  *core_dc = dc;
2599         struct dc_link *link = stream->link;
2600         struct timing_generator *tg = core_dc->res_pool->timing_generators[0];
2601         enum dc_status res = DC_OK;
2602
2603         calculate_phy_pix_clks(stream);
2604
2605         if (!tg->funcs->validate_timing(tg, &stream->timing))
2606                 res = DC_FAIL_CONTROLLER_VALIDATE;
2607
2608         if (res == DC_OK)
2609                 if (!link->link_enc->funcs->validate_output_with_stream(
2610                                                 link->link_enc, stream))
2611                         res = DC_FAIL_ENC_VALIDATE;
2612
2613         /* TODO: validate audio ASIC caps, encoder */
2614
2615         if (res == DC_OK)
2616                 res = dc_link_validate_mode_timing(stream,
2617                       link,
2618                       &stream->timing);
2619
2620         return res;
2621 }
2622
2623 enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
2624 {
2625         enum dc_status res = DC_OK;
2626
2627         /* TODO For now validates pixel format only */
2628         if (dc->res_pool->funcs->validate_plane)
2629                 return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
2630
2631         return res;
2632 }
2633
2634 unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format)
2635 {
2636         switch (format) {
2637         case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
2638                 return 8;
2639         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
2640         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
2641                 return 12;
2642         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
2643         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
2644         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
2645         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
2646                 return 16;
2647         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2648         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2649         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2650         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2651         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
2652                 return 32;
2653         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2654         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
2655         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2656                 return 64;
2657         default:
2658                 ASSERT_CRITICAL(false);
2659                 return -1;
2660         }
2661 }