drm/amd/display: make seamless boot work generically
authorAnthony Koo <Anthony.Koo@amd.com>
Wed, 30 Jan 2019 21:14:38 +0000 (16:14 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 5 Mar 2019 20:09:32 +0000 (15:09 -0500)
[Why]
Seamless boot code not working on all ASICs because of
some underflow issues caused by some uninitialized HW
state.

[How]
Keep some logical and power gating init code in hw_init.
Move some per pipe init code to enable accelerated mode

Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

index 5c7fb92d081c910f668f4a2281a01a7ccb247ee0..21a621822a59a116555a6e519fa59dc319b4a382 100644 (file)
@@ -1551,6 +1551,9 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
                }
        }
 
+       if (dc->hwss.init_pipes)
+               dc->hwss.init_pipes(dc, context);
+
        if (edp_link) {
                /* this seems to cause blank screens on DCE8 */
                if ((dc->ctx->dce_version == DCE_VERSION_8_0) ||
index 8ba895c4b445fa5d8f8dee3aa3b881cd5cd32e50..62a059d99d33c77a2fcf20d21dd62edfcb78e85b 100644 (file)
@@ -889,22 +889,23 @@ void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
                dcn10_verify_allow_pstate_change_high(dc);
 }
 
-static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
+static void plane_atomic_power_down(struct dc *dc,
+               struct dpp *dpp,
+               struct hubp *hubp)
 {
        struct dce_hwseq *hws = dc->hwseq;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
        DC_LOGGER_INIT(dc->ctx->logger);
 
        if (REG(DC_IP_REQUEST_CNTL)) {
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 1);
                dpp_pg_control(hws, dpp->inst, false);
-               hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, false);
+               hubp_pg_control(hws, hubp->inst, false);
                dpp->funcs->dpp_reset(dpp);
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 0);
                DC_LOG_DEBUG(
-                               "Power gated front end %d\n", pipe_ctx->pipe_idx);
+                               "Power gated front end %d\n", hubp->inst);
        }
 }
 
@@ -931,7 +932,9 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
        hubp->power_gated = true;
        dc->optimized_required = false; /* We're powering off, no need to optimize */
 
-       plane_atomic_power_down(dc, pipe_ctx);
+       plane_atomic_power_down(dc,
+                       pipe_ctx->plane_res.dpp,
+                       pipe_ctx->plane_res.hubp);
 
        pipe_ctx->stream = NULL;
        memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
@@ -1001,9 +1004,6 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
                struct dpp *dpp = dc->res_pool->dpps[i];
                struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
 
-               // W/A for issue with dc_post_update_surfaces_to_stream
-               hubp->power_gated = true;
-
                /* There is assumption that pipe_ctx is not mapping irregularly
                 * to non-preferred front end. If pipe_ctx->stream is not NULL,
                 * we will use the pipe, so don't disable
@@ -1108,6 +1108,22 @@ static void dcn10_init_hw(struct dc *dc)
                        link->link_status.link_active = true;
        }
 
+       /* If taking control over from VBIOS, we may want to optimize our first
+        * mode set, so we need to skip powering down pipes until we know which
+        * pipes we want to use.
+        * Otherwise, if taking control is not possible, we need to power
+        * everything down.
+        */
+       if (dcb->funcs->is_accelerated_mode(dcb)) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       struct hubp *hubp = dc->res_pool->hubps[i];
+                       struct dpp *dpp = dc->res_pool->dpps[i];
+
+                       dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+                       plane_atomic_power_down(dc, dpp, hubp);
+               }
+       }
+
        for (i = 0; i < dc->res_pool->audio_count; i++) {
                struct audio *audio = dc->res_pool->audios[i];
 
@@ -1137,9 +1153,6 @@ static void dcn10_init_hw(struct dc *dc)
        enable_power_gating_plane(dc->hwseq, true);
 
        memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks));
-
-       if (dc->hwss.init_pipes)
-               dc->hwss.init_pipes(dc, dc->current_state);
 }
 
 static void reset_hw_ctx_wrap(