diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index ec8359f03aaf..d2567dc3bc5e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6184,6 +6184,7 @@ static bool
 intel_dp_short_pulse(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
 	u8 old_sink_count = intel_dp->sink_count;
 	bool ret;
 
@@ -6211,6 +6212,11 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 	/* Handle CEC interrupts, if any */
 	drm_dp_cec_irq(&intel_dp->aux);
 
+	/* If LSPCON connected, try to set lspcon power state to D3 */
+	if (lspcon && lspcon->active)
+		lspcon_standby(dp_to_dig_port(intel_dp),
+			       intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base));
+
 	/* defer to the hotplug work for link retraining if needed */
 	if (intel_dp_needs_link_retrain(intel_dp))
 		return false;
@@ -6536,6 +6542,7 @@ intel_dp_detect(struct drm_connector *connector,
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
 	struct intel_encoder *encoder = &dig_port->base;
 	enum drm_connector_status status;
 
@@ -6632,9 +6639,13 @@ intel_dp_detect(struct drm_connector *connector,
 	intel_dp_check_service_irq(intel_dp);
 
 out:
-	if (status != connector_status_connected && !intel_dp->is_mst)
+	if (status != connector_status_connected && !intel_dp->is_mst) {
 		intel_dp_unset_edid(intel_dp);
 
+		if (lspcon && lspcon->active)
+			lspcon_standby(dp_to_dig_port(intel_dp), false);
+	}
+
 	/*
 	 * Make sure the refs for power wells enabled during detect are
 	 * dropped to avoid a new detect cycle triggered by HPD polling.
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index e37d45e531df..99eb67272552 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -550,6 +550,44 @@ static bool lspcon_init(struct intel_digital_port *dig_port)
 	return true;
 }
 
+void lspcon_standby(struct intel_digital_port *dig_port, bool connected)
+{
+	struct intel_dp *dp = &dig_port->dp;
+	u8 align_status = 0, training_pattern = 0, i;
+
+	if (connected) {
+		for (i = 0; i < 3; i++) {
+			usleep_range(10000, 11000);
+
+			if (drm_dp_dpcd_readb(&dp->aux, DP_LANE_ALIGN_STATUS_UPDATED,
+					      &align_status) <= 0) {
+				DRM_DEBUG_KMS("LSPCON failed to read align status\n");
+				return;
+			}
+
+			if (drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET,
+					      &training_pattern) <= 0) {
+				DRM_DEBUG_KMS("LSPCON failed to read training pattern set\n");
+				return;
+			}
+
+			/*
+			 * If link trainig is ongoing. Or sink updated link align status.
+			 * Source driver should not set lspcon power state to D3.
+			 */
+			if (align_status || training_pattern) {
+				DRM_DEBUG_KMS("LSPCON link training or display is working\n");
+				DRM_DEBUG_KMS("LSPCON DPCD register 0102h = %x, 0204h = 0x%x\n",
+					      training_pattern, align_status);
+				return;
+			}
+		}
+	}
+
+	if (drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3) <= 0)
+		DRM_DEBUG_KMS("LSPCON failed to write power state to D3\n");
+}
+
 void lspcon_resume(struct intel_digital_port *dig_port)
 {
 	struct intel_lspcon *lspcon = &dig_port->lspcon;
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h
index b03dcb7076d8..eef0e69bff32 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.h
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.h
@@ -16,6 +16,7 @@ struct intel_encoder;
 struct intel_lspcon;
 
 void lspcon_resume(struct intel_digital_port *dig_port);
+void lspcon_standby(struct intel_digital_port *dig_port, bool connected);
 void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon);
 void lspcon_write_infoframe(struct intel_encoder *encoder,
 			    const struct intel_crtc_state *crtc_state,
