Blob Blame History Raw
From: Yongqiang Sun <yongqiang.sun@amd.com>
Date: Fri, 24 Nov 2017 16:31:03 -0500
Subject: drm/amd/display: Move wait for hpd ready out from edp power control.
Git-commit: 904623ee5936e2226009b2f238f28781aecd2565
Patch-mainline: v4.16-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

It may take over 200ms for wait hpd ready. To optimize the resume time,
we can power on eDP in init_hw, wait for hpd ready when doing link
training.

also create separate eDP enable function to make sure eDP is powered up
before doing and DPCD access, as HPD low will result in DPDC transaction
failure.

After optimization,
setpowerstate 145ms -> 9.8ms,
DPMS 387ms -> 18.9ms

Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c               |   25 +++++++++++-
 drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c          |   11 -----
 drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c       |   15 -------
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c |   16 +------
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h |    4 +
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c   |    3 -
 drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h           |    1 
 7 files changed, 36 insertions(+), 39 deletions(-)

--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1271,6 +1271,24 @@ static enum dc_status enable_link_dp(
 	return status;
 }
 
+static enum dc_status enable_link_edp(
+		struct dc_state *state,
+		struct pipe_ctx *pipe_ctx)
+{
+	enum dc_status status;
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->sink->link;
+
+	link->dc->hwss.edp_power_control(link, true);
+	link->dc->hwss.edp_wait_for_hpd_ready(link, true);
+
+	status = enable_link_dp(state, pipe_ctx);
+
+	link->dc->hwss.edp_backlight_control(link, true);
+
+	return status;
+}
+
 static enum dc_status enable_link_dp_mst(
 		struct dc_state *state,
 		struct pipe_ctx *pipe_ctx)
@@ -1746,9 +1764,11 @@ static enum dc_status enable_link(
 	enum dc_status status = DC_ERROR_UNEXPECTED;
 	switch (pipe_ctx->stream->signal) {
 	case SIGNAL_TYPE_DISPLAY_PORT:
-	case SIGNAL_TYPE_EDP:
 		status = enable_link_dp(state, pipe_ctx);
 		break;
+	case SIGNAL_TYPE_EDP:
+		status = enable_link_edp(state, pipe_ctx);
+		break;
 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
 		status = enable_link_dp_mst(state, pipe_ctx);
 		msleep(200);
@@ -2282,6 +2302,9 @@ void core_link_disable_stream(struct pip
 	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
 		deallocate_mst_payload(pipe_ctx);
 
+	if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP)
+		core_dc->hwss.edp_backlight_control(pipe_ctx->stream->sink->link, false);
+
 	core_dc->hwss.disable_stream(pipe_ctx, option);
 
 	disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -88,15 +88,7 @@ void dp_enable_link_phy(
 	}
 
 	if (dc_is_dp_sst_signal(signal)) {
-		if (signal == SIGNAL_TYPE_EDP) {
-			link->dc->hwss.edp_power_control(link, true);
-			link_enc->funcs->enable_dp_output(
-						link_enc,
-						link_settings,
-						clock_source);
-			link->dc->hwss.edp_backlight_control(link, true);
-		} else
-			link_enc->funcs->enable_dp_output(
+		link_enc->funcs->enable_dp_output(
 						link_enc,
 						link_settings,
 						clock_source);
@@ -138,7 +130,6 @@ void dp_disable_link_phy(struct dc_link
 		dp_receiver_power_ctrl(link, false);
 
 	if (signal == SIGNAL_TYPE_EDP) {
-		link->dc->hwss.edp_backlight_control(link, false);
 		edp_receiver_ready_T9(link);
 		link->link_enc->funcs->disable_output(link->link_enc, signal);
 		link->dc->hwss.edp_power_control(link, false);
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -1072,21 +1072,6 @@ void dce110_link_encoder_disable_output(
 	/* disable encoder */
 	if (dc_is_dp_signal(signal))
 		link_encoder_disable(enc110);
-
-	/*
-	 * TODO: Power control cause regression, we should implement
-	 * it properly, for now just comment it.
-	 */
-//	if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
-//		/* power down eDP panel */
-//		link_encoder_edp_wait_for_hpd_ready(
-//				enc,
-//				enc->connector,
-//				false);
-//
-//		link_encoder_edp_power_control(
-//				enc, false);
-//	}
 }
 
 void dce110_link_encoder_dp_set_lane_settings(
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -870,8 +870,6 @@ void hwss_edp_power_control(
 				"%s: Skipping Panel Power action: %s\n",
 				__func__, (power_up ? "On":"Off"));
 	}
-
-	hwss_edp_wait_for_hpd_ready(link, true);
 }
 
 /*todo: cloned in stream enc, fix*/
@@ -972,11 +970,9 @@ void dce110_disable_stream(struct pipe_c
 	}
 
 	/* blank at encoder level */
-	if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-		if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
-			hwss_edp_backlight_control(link, false);
+	if (dc_is_dp_signal(pipe_ctx->stream->signal))
 		pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
-	}
+
 	link->link_enc->funcs->connect_dig_be_to_fe(
 			link->link_enc,
 			pipe_ctx->stream_res.stream_enc->id,
@@ -988,15 +984,12 @@ void dce110_unblank_stream(struct pipe_c
 		struct dc_link_settings *link_settings)
 {
 	struct encoder_unblank_param params = { { 0 } };
-	struct dc_link *link = pipe_ctx->stream->sink->link;
 
 	/* only 3 items below are used by unblank */
 	params.pixel_clk_khz =
 		pipe_ctx->stream->timing.pix_clk_khz;
 	params.link_settings.link_rate = link_settings->link_rate;
 	pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
-	if (link->connector_signal == SIGNAL_TYPE_EDP)
-		hwss_edp_backlight_control(link, true);
 }
 
 
@@ -1342,10 +1335,8 @@ static void power_down_encoders(struct d
 
 			if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
 				dp_receiver_power_ctrl(dc->links[i], false);
-			if (connector_id == CONNECTOR_ID_EDP) {
+			if (connector_id == CONNECTOR_ID_EDP)
 				signal = SIGNAL_TYPE_EDP;
-				hwss_edp_backlight_control(dc->links[i], false);
-			}
 		}
 
 		dc->links[i]->link_enc->funcs->disable_output(
@@ -2976,6 +2967,7 @@ static const struct hw_sequencer_funcs d
 	.pplib_apply_display_requirements = pplib_apply_display_requirements,
 	.edp_backlight_control = hwss_edp_backlight_control,
 	.edp_power_control = hwss_edp_power_control,
+	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
 };
 
 void dce110_hw_sequencer_construct(struct dc *dc)
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
@@ -77,5 +77,9 @@ void hwss_edp_backlight_control(
 	struct dc_link *link,
 	bool enable);
 
+void hwss_edp_wait_for_hpd_ready(
+		struct dc_link *link,
+		bool power_up);
+
 #endif /* __DC_HWSS_DCE110_H__ */
 
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -2368,7 +2368,8 @@ static const struct hw_sequencer_funcs d
 	.pplib_apply_display_requirements =
 			dcn10_pplib_apply_display_requirements,
 	.edp_backlight_control = hwss_edp_backlight_control,
-	.edp_power_control = hwss_edp_power_control
+	.edp_power_control = hwss_edp_power_control,
+	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
 };
 
 
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -199,6 +199,7 @@ struct hw_sequencer_funcs {
 	void (*edp_backlight_control)(
 			struct dc_link *link,
 			bool enable);
+	void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
 
 };