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