drm/amd/display: add dpms state to DC
authorHersen Wu <hersenxs.wu@amd.com>
Fri, 29 Sep 2017 20:36:34 +0000 (16:36 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Sat, 21 Oct 2017 20:47:47 +0000 (16:47 -0400)
- avoid eDP screen flash 4 times when resume from s3
- improve s3 and boot time

Signed-off-by: Hersen Wu <hersenxs.wu@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.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

index 09bab93815a3c33f2ab7eddbb2019ac65b339d54..d963de753e63182a557372d04e8bcf7a7d84ae45 100644 (file)
@@ -332,7 +332,16 @@ static void set_dither_option(struct dc_stream_state *stream,
 {
        struct bit_depth_reduction_params params;
        struct dc_link *link = stream->status.link;
-       struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
+       struct pipe_ctx *pipes;
+       int i;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
+                               stream) {
+                       pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
+                       break;
+               }
+       }
 
        memset(&params, 0, sizeof(params));
        if (!stream)
@@ -349,6 +358,31 @@ static void set_dither_option(struct dc_stream_state *stream,
                opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
 }
 
+void set_dpms(
+       struct dc *dc,
+       struct dc_stream_state *stream,
+       bool dpms_off)
+{
+       struct pipe_ctx *pipe_ctx;
+       int i;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
+                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+                       break;
+               }
+       }
+
+       if (stream->dpms_off != dpms_off) {
+               stream->dpms_off = dpms_off;
+               if (dpms_off)
+                       core_link_disable_stream(pipe_ctx,
+                                       KEEP_ACQUIRED_RESOURCE);
+               else
+                       core_link_enable_stream(dc->current_state, pipe_ctx);
+       }
+}
+
 static void allocate_dc_stream_funcs(struct dc  *dc)
 {
        if (dc->hwss.set_drr != NULL) {
@@ -371,6 +405,9 @@ static void allocate_dc_stream_funcs(struct dc  *dc)
        dc->stream_funcs.set_dither_option =
                        set_dither_option;
 
+       dc->stream_funcs.set_dpms =
+                       set_dpms;
+
        dc->link_funcs.set_drive_settings =
                        set_drive_settings;
 
index 2d59f77fa9a27f64d5b6176b010c77492997b72f..72e56fbe4a427b489d7a593270c6f9bcabc4178c 100644 (file)
@@ -2321,6 +2321,10 @@ void core_link_enable_stream(
 
        if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
                allocate_mst_payload(pipe_ctx);
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal))
+               core_dc->hwss.unblank_stream(pipe_ctx,
+                       &pipe_ctx->stream->sink->link->cur_link_settings);
 }
 
 void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
index 5a378cc5daafc8c74a6efd8ac1c0c48d72a8a979..7a5e53ffac2e8f5881acc34ccaa7a627dad3b27d 100644 (file)
@@ -133,6 +133,10 @@ struct dc_stream_state_funcs {
 
        void (*set_dither_option)(struct dc_stream_state *stream,
                        enum dc_dither_option option);
+
+       void (*set_dpms)(struct dc *dc,
+                       struct dc_stream_state *stream,
+                       bool dpms_off);
 };
 
 struct link_training_settings;
@@ -566,6 +570,7 @@ struct dc_stream_state {
 
        int phy_pix_clk;
        enum signal_type signal;
+       bool dpms_off;
 
        struct dc_stream_status status;
 
index 453d2ffd5c4a07803a589bf4f0758e10b3f4f5ba..81ebf2b9c71dc82123b4007a61a0387f15850005 100644 (file)
@@ -1364,12 +1364,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
        resource_build_info_frame(pipe_ctx);
        dce110_update_info_frame(pipe_ctx);
        if (!pipe_ctx_old->stream) {
-               core_link_enable_stream(context, pipe_ctx);
-
-
-               if (dc_is_dp_signal(pipe_ctx->stream->signal))
-                       dce110_unblank_stream(pipe_ctx,
-                               &stream->sink->link->cur_link_settings);
+               if (!pipe_ctx->stream->dpms_off)
+                       core_link_enable_stream(context, pipe_ctx);
        }
 
        pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
@@ -1879,7 +1875,10 @@ static void dce110_reset_hw_ctx_wrap(
                                pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
                        struct clock_source *old_clk = pipe_ctx_old->clock_source;
 
-                       core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
+                       /* disable already, no need to disable again */
+                       if (!pipe_ctx->stream->dpms_off)
+                               core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
+
                        pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
                        if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
                                dm_error("DC: failed to blank crtc!\n");
index 012ba7c9ca8de5cf8b18260ded307a6a747cc8af..494f833208f929bb85df3b309491121c30e78663 100644 (file)
@@ -1037,12 +1037,11 @@ static void reset_back_end_for_pipe(
                return;
        }
 
-       /* TODOFPGA break core_link_disable_stream into 2 functions:
-        * disable_stream and disable_link. disable_link will disable PHYPLL
-        * which is used by otg. Move disable_link after disable_crtc
-        */
-       if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
-               core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+       if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+               /* DPMS may already disable */
+               if (!pipe_ctx->stream->dpms_off)
+                       core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+       }
 
        /* by upper caller loop, parent pipe: pipe0, will be reset last.
         * back end share by all pipes and will be disable only when disable