* transitioned to PUSH_IDLE. In order to start transmitting
         * a link training pattern, we have to first do soft reset.
         */
-       if (*training_step == DP_TRAINING_1)
-               dp_catalog_ctrl_reset(ctrl->catalog);
 
        ret = dp_ctrl_link_train(ctrl, cr, training_step);
 
        return ret;
 }
 
-int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip)
+int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset)
 {
        struct dp_ctrl_private *ctrl;
        struct dp_io *dp_io;
 
        ctrl->dp_ctrl.orientation = flip;
 
+       if (reset)
+               dp_catalog_ctrl_reset(ctrl->catalog);
+
        dp_catalog_ctrl_phy_reset(ctrl->catalog);
        phy_init(phy);
        dp_catalog_ctrl_enable_irq(ctrl->catalog, true);
        return 0;
 }
 
-static void dp_ctrl_link_idle_reset(struct dp_ctrl_private *ctrl)
-{
-       dp_ctrl_push_idle(&ctrl->dp_ctrl);
-       dp_catalog_ctrl_reset(ctrl->catalog);
-}
-
 static int dp_ctrl_link_maintenance(struct dp_ctrl_private *ctrl)
 {
        int ret = 0;
        struct dp_cr_status cr;
        int training_step = DP_TRAINING_NONE;
 
+       dp_ctrl_push_idle(&ctrl->dp_ctrl);
+
        ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
 
        ret = dp_ctrl_setup_main_link(ctrl, &cr, &training_step);
 
        if (sink_request & DP_TEST_LINK_TRAINING) {
                dp_link_send_test_response(ctrl->link);
-               dp_ctrl_link_idle_reset(ctrl);
                if (dp_ctrl_link_maintenance(ctrl)) {
                        DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
                        return;
                        break;
                }
 
-               training_step = DP_TRAINING_1;
+               training_step = DP_TRAINING_NONE;
                rc = dp_ctrl_setup_main_link(ctrl, &cr, &training_step);
                if (rc == 0) {
                        /* training completed successfully */
         * Set up transfer unit values and set controller state to send
         * video.
         */
+       reinit_completion(&ctrl->video_comp);
+
        dp_ctrl_configure_source_params(ctrl);
 
        dp_catalog_ctrl_config_msa(ctrl->catalog,
                ctrl->link->link_params.rate,
                ctrl->dp_ctrl.pixel_rate, dp_ctrl_use_fixed_nvid(ctrl));
 
-       reinit_completion(&ctrl->video_comp);
-
        dp_ctrl_setup_tr_unit(ctrl);
 
        dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
 
        return rc;
 }
 
-static void dp_display_host_init(struct dp_display_private *dp)
+static void dp_display_host_init(struct dp_display_private *dp, int reset)
 {
        bool flip = false;
 
        dp_display_set_encoder_mode(dp);
 
        dp_power_init(dp->power, flip);
-       dp_ctrl_host_init(dp->ctrl, flip);
+       dp_ctrl_host_init(dp->ctrl, flip, reset);
        dp_aux_init(dp->aux);
        dp->core_initialized = true;
 }
                goto end;
        }
 
-       dp_display_host_init(dp);
+       dp_display_host_init(dp, false);
 
        /*
         * set sink to normal operation mode -- D0
                return 0;
        }
 
-       if (state == ST_CONNECT_PENDING) {
+       if (state == ST_CONNECT_PENDING || state == ST_DISCONNECT_PENDING) {
                /* wait until ST_CONNECTED */
                dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */
                mutex_unlock(&dp->event_mutex);
 static void dp_display_config_hpd(struct dp_display_private *dp)
 {
 
-       dp_display_host_init(dp);
+       dp_display_host_init(dp, true);
        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);
+       dp_display_host_init(dp, true);
 
        dp_catalog_ctrl_hpd_config(dp->catalog);
 
        state =  dp_display->hpd_state;
 
        if (state == ST_DISPLAY_OFF)
-               dp_display_host_init(dp_display);
+               dp_display_host_init(dp_display, true);
 
        dp_display_enable(dp_display, 0);