drm/amd/display: Move wait for hpd ready out from edp power control.
authorYongqiang Sun <yongqiang.sun@amd.com>
Fri, 24 Nov 2017 21:31:03 +0000 (16:31 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 14 Dec 2017 16:00:35 +0000 (11:00 -0500)
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>
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index 13995893cac58bb8133c6f8837a279725f34caaa..00130152f366e488148febff8da9008ee3cc36c4 100644 (file)
@@ -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 pipe_ctx *pipe_ctx, int option)
        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);
index f2902569be2ef92138bfbd186ff7ee7b06bdb888..2096f2a179f2c5e3509ac1c60115049f3a6e9ee5 100644 (file)
@@ -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 *link, enum signal_type signal)
                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);
index bad70c6b3aad5214ad07d0c8a3fc4378c6bb15dc..a266e3f5e75fd7ae82a46f7d3e09f900660c72cc 100644 (file)
@@ -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(
index 21fc27aab9097fc604a40ee8c6581849d11acbb2..dd83867783616793c82ed8c4b1157c978126de5d 100644 (file)
@@ -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_ctx *pipe_ctx, int option)
        }
 
        /* 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_ctx *pipe_ctx,
                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 dc *dc)
 
                        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 dce110_funcs = {
        .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)
index 2dd6ac63757292365ebd69e65591c241b0440ba4..fc637647f64331a568d3c62f1a3ed7e73d07afc2 100644 (file)
@@ -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__ */
 
index f0be2b872668ab9830770f41780925f80577082e..31fd6ae8f61fbbc3976fd2b4ec495f79a222a73a 100644 (file)
@@ -2368,7 +2368,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .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,
 };
 
 
index 03431134c0881f65c14fb6dfe6497c9bc6db3d00..b6215ba514d83f48a3c2aefd7749ebfe4338a802 100644 (file)
@@ -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);
 
 };