DC_LOG_DC("BIOS object table - end");
 
+       /* Create a link for each usb4 dpia port */
+       for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) {
+               struct link_init_data link_init_params = {0};
+               struct dc_link *link;
+
+               link_init_params.ctx = dc->ctx;
+               link_init_params.connector_index = i;
+               link_init_params.link_index = dc->link_count;
+               link_init_params.dc = dc;
+               link_init_params.is_dpia_link = true;
+
+               link = link_create(&link_init_params);
+               if (link) {
+                       dc->links[dc->link_count] = link;
+                       link->dc = dc;
+                       ++dc->link_count;
+               }
+       }
+
        for (i = 0; i < num_virtual_links; i++) {
                struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
                struct encoder_init_data enc_init = {0};
  */
 bool dc_enable_dmub_notifications(struct dc *dc)
 {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       /* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */
+       if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+           dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0)
+               return true;
+#endif
        /* dmub aux needs dmub notifications to be enabled */
        return dc->debug.enable_dmub_aux_for_legacy_ddc;
 }
 
        cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
        cmd.dp_aux_access.header.payload_bytes = 0;
-       cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
+       /* For dpia, ddc_pin is set to NULL */
+       if (!dc->links[link_index]->ddc->ddc_pin)
+               cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_DPIA;
+       else
+               cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
+
        cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst;
        cmd.dp_aux_access.aux_control.sw_crc_enabled = 0;
        cmd.dp_aux_access.aux_control.timeout = 0;
 
        }
 }
 
-static bool dc_link_construct(struct dc_link *link,
-                             const struct link_init_data *init_params)
+static bool dc_link_construct_legacy(struct dc_link *link,
+                                    const struct link_init_data *init_params)
 {
        uint8_t i;
        struct ddc_service_init_data ddc_service_init_data = { { 0 } };
        return false;
 }
 
+static bool dc_link_construct_dpia(struct dc_link *link,
+                                  const struct link_init_data *init_params)
+{
+       struct ddc_service_init_data ddc_service_init_data = { { 0 } };
+       struct dc_context *dc_ctx = init_params->ctx;
+
+       DC_LOGGER_INIT(dc_ctx->logger);
+
+       /* Initialized dummy hpd and hpd rx */
+       link->irq_source_hpd = DC_IRQ_SOURCE_USB4_DMUB_HPD;
+       link->irq_source_hpd_rx = DC_IRQ_SOURCE_USB4_DMUB_HPDRX;
+       link->link_status.dpcd_caps = &link->dpcd_caps;
+
+       link->dc = init_params->dc;
+       link->ctx = dc_ctx;
+       link->link_index = init_params->link_index;
+
+       memset(&link->preferred_training_settings, 0,
+              sizeof(struct dc_link_training_overrides));
+       memset(&link->preferred_link_setting, 0,
+              sizeof(struct dc_link_settings));
+
+       /* Dummy Init for linkid */
+       link->link_id.type = OBJECT_TYPE_CONNECTOR;
+       link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
+       link->is_internal_display = false;
+       link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
+       LINK_INFO("Connector[%d] description:signal %d\n",
+                 init_params->connector_index,
+                 link->connector_signal);
+
+       /* TODO: Initialize link : funcs->link_init */
+
+       ddc_service_init_data.ctx = link->ctx;
+       ddc_service_init_data.id = link->link_id;
+       ddc_service_init_data.link = link;
+       /* Set indicator for dpia link so that ddc won't be created */
+       ddc_service_init_data.is_dpia_link = true;
+
+       link->ddc = dal_ddc_service_create(&ddc_service_init_data);
+       if (!link->ddc) {
+               DC_ERROR("Failed to create ddc_service!\n");
+               goto ddc_create_fail;
+       }
+
+       /* Set dpia port index : 0 to number of dpia ports */
+       link->ddc_hw_inst = init_params->connector_index;
+
+       /* TODO: Create link encoder */
+
+       link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
+
+       return true;
+
+ddc_create_fail:
+       return false;
+}
+
+static bool dc_link_construct(struct dc_link *link,
+                             const struct link_init_data *init_params)
+{
+       /* Handle dpia case */
+       if (init_params->is_dpia_link)
+               return dc_link_construct_dpia(link, init_params);
+       else
+               return dc_link_construct_legacy(link, init_params);
+}
 /*******************************************************************************
  * Public functions
  ******************************************************************************/
 
        ddc_service->link = init_data->link;
        ddc_service->ctx = init_data->ctx;
 
-       if (BP_RESULT_OK != dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info)) {
+       if (init_data->is_dpia_link ||
+           dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
                ddc_service->ddc_pin = NULL;
        } else {
                DC_LOGGER_INIT(ddc_service->ctx->logger);
 
                if (hws->funcs.dsc_pg_control != NULL)
                        hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
 
+       /* Enables outbox notifications for usb4 dpia */
+       if (dc->res_pool->usb4_dpia_count)
+               dmub_enable_outbox_notification(dc);
+
        /* we want to turn off all dp displays before doing detection */
        if (dc->config.power_down_display_on_boot)
                blank_all_dp_displays(dc, true);
        if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
                dc->res_pool->hubbub->funcs->force_pstate_change_control(
                                dc->res_pool->hubbub, false, false);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
        if (dc->res_pool->hubbub->funcs->init_crb)
                dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+#endif
 }
 
 void dcn31_dsc_pg_control(
 
                pool->base.sw_i2cs[i] = NULL;
        }
 
+       if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+           dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+               /* YELLOW CARP B0 has 4 DPIA's */
+               pool->base.usb4_dpia_count = 4;
+       }
+
        /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
        if (!resource_construct(num_virtual_links, dc, &pool->base,
                        (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
 
        uint32_t connector_index; /* this will be mapped to the HPD pins */
        uint32_t link_index; /* this is mapped to DAL display_index
                                TODO: remove it when DC is complete. */
+       bool is_dpia_link;
 };
 
 struct dc_link *link_create(const struct link_init_data *init_params);
 
        struct graphics_object_id id;
        struct dc_context *ctx;
        struct dc_link *link;
+       bool is_dpia_link;
 };
 
 struct ddc_service *dal_ddc_service_create(
 
        DC_IRQ_SOURCE_DMCUB_OUTBOX,
        DC_IRQ_SOURCE_DMCUB_OUTBOX0,
        DC_IRQ_SOURCE_DMCUB_GENERAL_DATAOUT,
-       DAL_IRQ_SOURCES_NUMBER
+       DAL_IRQ_SOURCES_NUMBER,
+       /* Dummy interrupt source for USB4 HPD & HPD RX */
+       DC_IRQ_SOURCE_USB4_DMUB_HPD,
+       DC_IRQ_SOURCE_USB4_DMUB_HPDRX,
 };
 
 enum irq_type