}
 }
 
+static inline int find_acquired_dio_link_enc_for_link(
+               const struct resource_context *res_ctx,
+               const struct dc_link *link)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(res_ctx->dio_link_enc_ref_cnts); i++)
+               if (res_ctx->dio_link_enc_ref_cnts[i] > 0 &&
+                               res_ctx->dio_link_enc_to_link_idx[i] == link->link_index)
+                       return i;
+
+       return -1;
+}
+
+static inline int find_fixed_dio_link_enc(const struct dc_link *link)
+{
+       /* the 8b10b dp phy can only use fixed link encoder */
+       return link->eng_id;
+}
+
+static inline int find_free_dio_link_enc(const struct resource_context *res_ctx,
+               const struct dc_link *link, const struct resource_pool *pool)
+{
+       int i;
+       int enc_count = pool->dig_link_enc_count;
+
+       /* for dpia, check preferred encoder first and then the next one */
+       for (i = 0; i < enc_count; i++)
+               if (res_ctx->dio_link_enc_ref_cnts[(link->dpia_preferred_eng_id + i) % enc_count] == 0)
+                       break;
+
+       return (i >= 0 && i < enc_count) ? (link->dpia_preferred_eng_id + i) % enc_count : -1;
+}
+
+static inline void acquire_dio_link_enc(
+               struct resource_context *res_ctx,
+               unsigned int link_index,
+               int enc_index)
+{
+       res_ctx->dio_link_enc_to_link_idx[enc_index] = link_index;
+       res_ctx->dio_link_enc_ref_cnts[enc_index] = 1;
+}
+
+static inline void retain_dio_link_enc(
+               struct resource_context *res_ctx,
+               int enc_index)
+{
+       res_ctx->dio_link_enc_ref_cnts[enc_index]++;
+}
+
+static inline void release_dio_link_enc(
+               struct resource_context *res_ctx,
+               int enc_index)
+{
+       ASSERT(res_ctx->dio_link_enc_ref_cnts[enc_index] > 0);
+       res_ctx->dio_link_enc_ref_cnts[enc_index]--;
+}
+
+static bool is_dio_enc_acquired_by_other_link(const struct dc_link *link,
+               int enc_index,
+               int *link_index)
+{
+       const struct dc *dc  = link->dc;
+       const struct resource_context *res_ctx = &dc->current_state->res_ctx;
+
+       /* pass the link_index that acquired the enc_index */
+       if (res_ctx->dio_link_enc_ref_cnts[enc_index] > 0 &&
+                       res_ctx->dio_link_enc_to_link_idx[enc_index] != link->link_index) {
+               *link_index = res_ctx->dio_link_enc_to_link_idx[enc_index];
+               return true;
+       }
+
+       return false;
+}
+
+static void swap_dio_link_enc_to_muxable_ctx(struct dc_state *context,
+               const struct resource_pool *pool,
+               int new_encoder,
+               int old_encoder)
+{
+       struct resource_context *res_ctx = &context->res_ctx;
+       int stream_count = context->stream_count;
+       int i = 0;
+
+       res_ctx->dio_link_enc_ref_cnts[new_encoder] = res_ctx->dio_link_enc_ref_cnts[old_encoder];
+       res_ctx->dio_link_enc_to_link_idx[new_encoder] = res_ctx->dio_link_enc_to_link_idx[old_encoder];
+       res_ctx->dio_link_enc_ref_cnts[old_encoder] = 0;
+
+       for (i = 0; i < stream_count; i++) {
+               struct dc_stream_state *stream = context->streams[i];
+               struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream);
+
+               if (pipe_ctx && pipe_ctx->link_res.dio_link_enc == pool->link_encoders[old_encoder])
+                       pipe_ctx->link_res.dio_link_enc = pool->link_encoders[new_encoder];
+       }
+}
+
+static bool add_dio_link_enc_to_ctx(const struct dc *dc,
+               struct dc_state *context,
+               const struct resource_pool *pool,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_stream_state *stream)
+{
+       struct resource_context *res_ctx = &context->res_ctx;
+       int enc_index;
+
+       enc_index = find_acquired_dio_link_enc_for_link(res_ctx, stream->link);
+
+       if (enc_index >= 0) {
+               retain_dio_link_enc(res_ctx, enc_index);
+       } else {
+               if (stream->link->is_dig_mapping_flexible)
+                       enc_index = find_free_dio_link_enc(res_ctx, stream->link, pool);
+               else {
+                       int link_index = 0;
+
+                       enc_index = find_fixed_dio_link_enc(stream->link);
+                       /* Fixed mapping link can only use its fixed link encoder.
+                        * If the encoder is acquired by other link then get a new free encoder and swap the new
+                        * one into the acquiring link.
+                        */
+                       if (enc_index >= 0 && is_dio_enc_acquired_by_other_link(stream->link, enc_index, &link_index)) {
+                               int new_enc_index = find_free_dio_link_enc(res_ctx, dc->links[link_index], pool);
+
+                               if (new_enc_index >= 0)
+                                       swap_dio_link_enc_to_muxable_ctx(context, pool, new_enc_index, enc_index);
+                               else
+                                       return false;
+                       }
+               }
+
+               if (enc_index >= 0)
+                       acquire_dio_link_enc(res_ctx, stream->link->link_index, enc_index);
+       }
+
+       if (enc_index >= 0)
+               pipe_ctx->link_res.dio_link_enc = pool->link_encoders[enc_index];
+
+       return pipe_ctx->link_res.dio_link_enc != NULL;
+}
+
+static void remove_dio_link_enc_from_ctx(struct resource_context *res_ctx,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_stream_state *stream)
+{
+       int enc_index = -1;
+
+       if (stream->link)
+               enc_index = find_acquired_dio_link_enc_for_link(res_ctx, stream->link);
+
+       if (enc_index >= 0) {
+               release_dio_link_enc(res_ctx, enc_index);
+               pipe_ctx->link_res.dio_link_enc = NULL;
+       }
+}
+
 static int get_num_of_free_pipes(const struct resource_pool *pool, const struct dc_state *context)
 {
        int i;
                remove_hpo_dp_link_enc_from_ctx(
                                &context->res_ctx, otg_master, stream);
        }
+
+       if (stream->ctx->dc->config.unify_link_enc_assignment)
+               remove_dio_link_enc_from_ctx(&context->res_ctx, otg_master, stream);
+
        if (otg_master->stream_res.audio)
                update_audio_usage(
                        &context->res_ctx,
        if (pool->funcs->remove_stream_from_ctx)
                pool->funcs->remove_stream_from_ctx(
                                stream->ctx->dc, context, stream);
+
        memset(otg_master, 0, sizeof(*otg_master));
 }
 
        struct pipe_ctx *pipe_ctx = NULL;
        int pipe_idx = -1;
        bool acquired = false;
+       bool is_dio_encoder = true;
 
        calculate_phy_pix_clks(stream);
 
                }
        }
 
+       if (dc->config.unify_link_enc_assignment && is_dio_encoder)
+               if (!add_dio_link_enc_to_ctx(dc, context, pool, pipe_ctx, stream))
+                       return DC_NO_LINK_ENC_RESOURCE;
+
        /* TODO: Add check if ASIC support and EDID audio */
        if (!stream->converter_disable_audio &&
            dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
        }
 }
 
+static struct link_encoder *get_temp_dio_link_enc(
+               const struct resource_context *res_ctx,
+               const struct resource_pool *const pool,
+               const struct dc_link *link)
+{
+       struct link_encoder *link_enc = NULL;
+       int enc_index;
+
+       if (link->is_dig_mapping_flexible)
+               enc_index = find_acquired_dio_link_enc_for_link(res_ctx, link);
+       else
+               enc_index = link->eng_id;
+
+       if (enc_index < 0)
+               enc_index = find_free_dio_link_enc(res_ctx, link, pool);
+
+       if (enc_index >= 0)
+               link_enc = pool->link_encoders[enc_index];
+
+       return link_enc;
+}
+
 static struct hpo_dp_link_encoder *get_temp_hpo_dp_link_enc(
                const struct resource_context *res_ctx,
                const struct resource_pool *const pool,
        memset(link_res, 0, sizeof(*link_res));
 
        if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
-               link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx,
-                               dc->res_pool, link);
+               link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx, dc->res_pool, link);
                if (!link_res->hpo_dp_link_enc)
                        return false;
+       } else if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
+                               dc->config.unify_link_enc_assignment) {
+               link_res->dio_link_enc = get_temp_dio_link_enc(res_ctx,
+                               dc->res_pool, link);
+               if (!link_res->dio_link_enc)
+                       return false;
        }
+
        return true;
 }
 
                        remove_hpo_dp_link_enc_from_ctx(&context->res_ctx, pipe_ctx, pipe_ctx->stream);
        }
 
+       if (pipe_ctx->link_res.dio_link_enc == NULL && dc->config.unify_link_enc_assignment)
+               if (!add_dio_link_enc_to_ctx(dc, context, dc->res_pool, pipe_ctx, pipe_ctx->stream))
+                       return DC_NO_LINK_ENC_RESOURCE;
+
        return DC_OK;
 }