return ret;
 }
 
-int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset)
+void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable)
+{
+       struct dp_ctrl_private *ctrl;
+
+       ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+
+       dp_catalog_ctrl_reset(ctrl->catalog);
+
+       if (enable)
+               dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
+}
+
+void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl)
 {
        struct dp_ctrl_private *ctrl;
        struct dp_io *dp_io;
        struct phy *phy;
 
-       if (!dp_ctrl) {
-               DRM_ERROR("Invalid input data\n");
-               return -EINVAL;
-       }
-
        ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
        dp_io = &ctrl->parser->io;
        phy = dp_io->phy;
 
-       ctrl->dp_ctrl.orientation = flip;
-
-       if (reset)
-               dp_catalog_ctrl_reset(ctrl->catalog);
-
-       DRM_DEBUG_DP("flip=%d\n", flip);
        dp_catalog_ctrl_phy_reset(ctrl->catalog);
        phy_init(phy);
-       dp_catalog_ctrl_enable_irq(ctrl->catalog, true);
-
-       return 0;
 }
 
-/**
- * dp_ctrl_host_deinit() - Uninitialize DP controller
- * @dp_ctrl: Display Port Driver data
- *
- * Perform required steps to uninitialize DP controller
- * and its resources.
- */
-void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl)
+void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl)
 {
        struct dp_ctrl_private *ctrl;
        struct dp_io *dp_io;
        struct phy *phy;
 
-       if (!dp_ctrl) {
-               DRM_ERROR("Invalid input data\n");
-               return;
-       }
-
        ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
        dp_io = &ctrl->parser->io;
        phy = dp_io->phy;
 
-       dp_catalog_ctrl_enable_irq(ctrl->catalog, false);
+       dp_catalog_ctrl_phy_reset(ctrl->catalog);
        phy_exit(phy);
-
-       DRM_DEBUG_DP("Host deinitialized successfully\n");
 }
 
 static bool dp_ctrl_use_fixed_nvid(struct dp_ctrl_private *ctrl)
        }
 
        phy_power_off(phy);
+
+       /* aux channel down, reinit phy */
        phy_exit(phy);
+       phy_init(phy);
 
        return 0;
 }
                return ret;
        }
 
+       DRM_DEBUG_DP("Before, phy=%x init_count=%d power_on=%d\n",
+               (u32)(uintptr_t)phy, phy->init_count, phy->power_count);
+
        phy_power_off(phy);
 
+       DRM_DEBUG_DP("After, phy=%x init_count=%d power_on=%d\n",
+               (u32)(uintptr_t)phy, phy->init_count, phy->power_count);
+
        /* aux channel down, reinit phy */
        phy_exit(phy);
        phy_init(phy);
        return ret;
 }
 
-void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl)
-{
-       struct dp_ctrl_private *ctrl;
-       struct dp_io *dp_io;
-       struct phy *phy;
-
-       ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-       dp_io = &ctrl->parser->io;
-       phy = dp_io->phy;
-
-       dp_catalog_ctrl_reset(ctrl->catalog);
-
-       phy_exit(phy);
-
-       DRM_DEBUG_DP("DP off phy done\n");
-}
-
 int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
 {
        struct dp_ctrl_private *ctrl;
                DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
        }
 
+       DRM_DEBUG_DP("Before, phy=%x init_count=%d power_on=%d\n",
+               (u32)(uintptr_t)phy, phy->init_count, phy->power_count);
+
        phy_power_off(phy);
-       phy_exit(phy);
 
-       DRM_DEBUG_DP("DP off done\n");
+       DRM_DEBUG_DP("After, phy=%x init_count=%d power_on=%d\n",
+               (u32)(uintptr_t)phy, phy->init_count, phy->power_count);
+
        return ret;
 }
 
 
 
        /* state variables */
        bool core_initialized;
+       bool phy_initialized;
        bool hpd_irq_on;
        bool audio_supported;
 
        return rc;
 }
 
-static void dp_display_host_init(struct dp_display_private *dp, int reset)
+static void dp_display_host_phy_init(struct dp_display_private *dp)
 {
-       bool flip = false;
+       DRM_DEBUG_DP("core_init=%d phy_init=%d\n",
+                       dp->core_initialized, dp->phy_initialized);
 
-       DRM_DEBUG_DP("core_initialized=%d\n", dp->core_initialized);
-       if (dp->core_initialized) {
-               DRM_DEBUG_DP("DP core already initialized\n");
-               return;
+       if (!dp->phy_initialized) {
+               dp_ctrl_phy_init(dp->ctrl);
+               dp->phy_initialized = true;
        }
+}
+
+static void dp_display_host_phy_exit(struct dp_display_private *dp)
+{
+       DRM_DEBUG_DP("core_init=%d phy_init=%d\n",
+                       dp->core_initialized, dp->phy_initialized);
 
-       if (dp->usbpd->orientation == ORIENTATION_CC2)
-               flip = true;
+       if (dp->phy_initialized) {
+               dp_ctrl_phy_exit(dp->ctrl);
+               dp->phy_initialized = false;
+       }
+}
+
+static void dp_display_host_init(struct dp_display_private *dp)
+{
+       DRM_DEBUG_DP("core_initialized=%d\n", dp->core_initialized);
 
-       dp_power_init(dp->power, flip);
-       dp_ctrl_host_init(dp->ctrl, flip, reset);
+       dp_power_init(dp->power, false);
+       dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
        dp_aux_init(dp->aux);
        dp->core_initialized = true;
 }
 
 static void dp_display_host_deinit(struct dp_display_private *dp)
 {
-       if (!dp->core_initialized) {
-               DRM_DEBUG_DP("DP core not initialized\n");
-               return;
-       }
+       DRM_DEBUG_DP("core_initialized=%d\n", dp->core_initialized);
 
-       dp_ctrl_host_deinit(dp->ctrl);
+       dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
        dp_aux_deinit(dp->aux);
        dp_power_deinit(dp->power);
-
        dp->core_initialized = false;
 }
 
        dp = container_of(g_dp_display,
                        struct dp_display_private, dp_display);
 
-       dp_display_host_init(dp, false);
+       dp_display_host_phy_init(dp);
 
        rc = dp_display_process_hpd_high(dp);
 end:
        ret = dp_display_usbpd_configure_cb(&dp->pdev->dev);
        if (ret) {      /* link train failed */
                dp->hpd_state = ST_DISCONNECTED;
-
-               if (ret == -ECONNRESET) { /* cable unplugged */
-                       dp->core_initialized = false;
-               }
-
        } else {
                /* start sentinel checking in case of missing uevent */
                dp_add_event(dp, EV_CONNECT_PENDING_TIMEOUT, 0, tout);
        if (state == ST_DISCONNECTED) {
                /* triggered by irq_hdp with sink_count = 0 */
                if (dp->link->sink_count == 0) {
-                       dp_ctrl_off_phy(dp->ctrl);
-                       dp->core_initialized = false;
+                       dp_display_host_phy_exit(dp);
                }
                mutex_unlock(&dp->event_mutex);
                return 0;
 static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
 {
        u32 state;
-       int ret;
 
        mutex_lock(&dp->event_mutex);
 
                return 0;
        }
 
-       /*
-        * dp core (ahb/aux clks) must be initialized before
-        * irq_hpd be handled
-        */
-       if (dp->core_initialized) {
-               ret = dp_display_usbpd_attention_cb(&dp->pdev->dev);
-               if (ret == -ECONNRESET) { /* cable unplugged */
-                       dp->core_initialized = false;
-               }
-       }
+       dp_display_usbpd_attention_cb(&dp->pdev->dev);
+
        DRM_DEBUG_DP("hpd_state=%d\n", state);
 
        mutex_unlock(&dp->event_mutex);
 
        dp_display->audio_enabled = false;
 
-       /* triggered by irq_hpd with sink_count = 0 */
        if (dp->link->sink_count == 0) {
+               /*
+                * irq_hpd with sink_count = 0
+                * hdmi unplugged out of dongle
+                */
                dp_ctrl_off_link_stream(dp->ctrl);
        } else {
+               /*
+                * unplugged interrupt
+                * dongle unplugged out of DUT
+                */
                dp_ctrl_off(dp->ctrl);
-               dp->core_initialized = false;
+               dp_display_host_phy_exit(dp);
        }
 
        dp_display->power_on = false;
 static void dp_display_config_hpd(struct dp_display_private *dp)
 {
 
-       dp_display_host_init(dp, true);
+       dp_display_host_init(dp);
        dp_catalog_ctrl_hpd_config(dp->catalog);
 
        /* Enable interrupt first time
        dp->hpd_state = ST_DISCONNECTED;
 
        /* turn on dp ctrl/phy */
-       dp_display_host_init(dp, true);
+       dp_display_host_init(dp);
 
        dp_catalog_ctrl_hpd_config(dp->catalog);
 
-       /*
-        * set sink to normal operation mode -- D0
-        * before dpcd read
-        */
-       dp_link_psm_config(dp->link, &dp->panel->link_info, false);
 
        if (dp_catalog_link_is_connected(dp->catalog)) {
+               /*
+                * set sink to normal operation mode -- D0
+                * before dpcd read
+                */
+               dp_display_host_phy_init(dp);
+               dp_link_psm_config(dp->link, &dp->panel->link_info, false);
                sink_count = drm_dp_read_sink_count(dp->aux);
                if (sink_count < 0)
                        sink_count = 0;
+
+               dp_display_host_phy_exit(dp);
        }
 
        dp->link->sink_count = sink_count;
        DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n",
                        dp->core_initialized, dp_display->power_on);
 
-       if (dp->core_initialized == true) {
-               /* mainlink enabled */
-               if (dp_power_clk_status(dp->power, DP_CTRL_PM))
-                       dp_ctrl_off_link_stream(dp->ctrl);
+       /* mainlink enabled */
+       if (dp_power_clk_status(dp->power, DP_CTRL_PM))
+               dp_ctrl_off_link_stream(dp->ctrl);
 
-               dp_display_host_deinit(dp);
-       }
-
-       dp->hpd_state = ST_SUSPENDED;
+       dp_display_host_phy_exit(dp);
 
        /* host_init will be called at pm_resume */
-       dp->core_initialized = false;
+       dp_display_host_deinit(dp);
+
+       dp->hpd_state = ST_SUSPENDED;
 
        DRM_DEBUG_DP("After, core_inited=%d power_on=%d\n",
                        dp->core_initialized, dp_display->power_on);
        state =  dp_display->hpd_state;
 
        if (state == ST_DISPLAY_OFF)
-               dp_display_host_init(dp_display, true);
+               dp_display_host_phy_init(dp_display);
 
        dp_display_enable(dp_display, 0);