]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/amd/display: refactor init_hw to isolate pipe related init
authorAnthony Koo <Anthony.Koo@amd.com>
Sun, 20 Jan 2019 06:23:07 +0000 (01:23 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 6 Feb 2019 18:31:22 +0000 (13:31 -0500)
[Why]
Pipe related init is possible to optimized if we know what we
intend to program, and if we can determine it matches what is
already programmed for the pipe.

[How]
First step is to isolate the pipe related init code

Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@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
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index a4386348a981fe7614012779b502f44f0b65b4ac..4df8a43b501855332408051a28854553d8e1b9ee 100644 (file)
@@ -2275,6 +2275,11 @@ static void dce110_enable_per_frame_crtc_position_reset(
 
 }
 
+static void init_pipes(struct dc *dc, struct dc_state *context)
+{
+       // Do nothing
+}
+
 static void init_hw(struct dc *dc)
 {
        int i;
@@ -2642,6 +2647,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
        .program_gamut_remap = program_gamut_remap,
        .program_output_csc = program_output_csc,
        .init_hw = init_hw,
+       .init_pipes = init_pipes,
        .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
        .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
        .update_plane_addr = update_plane_addr,
index a03bbbf94d5d624099f4ad00ca08b311c6390675..117d9d8227f7429f09871abfa6823ebccc6849e3 100644 (file)
@@ -956,97 +956,34 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
                                        pipe_ctx->pipe_idx);
 }
 
-static void dcn10_init_hw(struct dc *dc)
+static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
 {
        int i;
-       struct abm *abm = dc->res_pool->abm;
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       struct dc_state  *context = dc->current_state;
-
-       if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-               REG_WRITE(REFCLK_CNTL, 0);
-               REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
-               REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-               if (!dc->debug.disable_clock_gate) {
-                       /* enable all DCN clock gating */
-                       REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-                       REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
-                       REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-               }
-
-               enable_power_gating_plane(dc->hwseq, true);
-       } else {
-
-               if (!dcb->funcs->is_accelerated_mode(dcb)) {
-                       bool allow_self_fresh_force_enable =
-                                       hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub);
-
-                       bios_golden_init(dc);
-
-                       /* WA for making DF sleep when idle after resume from S0i3.
-                        * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
-                        * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
-                        * before calling command table and it changed to 1 after,
-                        * it should be set back to 0.
-                        */
-                       if (allow_self_fresh_force_enable == false &&
-                                       hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub))
-                               hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true);
-
-                       disable_vga(dc->hwseq);
-               }
-
-               for (i = 0; i < dc->link_count; i++) {
-                       /* Power up AND update implementation according to the
-                        * required signal (which may be different from the
-                        * default signal on connector).
-                        */
-                       struct dc_link *link = dc->links[i];
-
-                       if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
-                               dc->hwss.edp_power_control(link, true);
-
-                       link->link_enc->funcs->hw_init(link->link_enc);
-
-                       /* Check for enabled DIG to identify enabled display */
-                       if (link->link_enc->funcs->is_dig_enabled &&
-                               link->link_enc->funcs->is_dig_enabled(link->link_enc))
-                               link->link_status.link_active = true;
-               }
-       }
 
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                struct timing_generator *tg = dc->res_pool->timing_generators[i];
 
                if (tg->funcs->is_tg_enabled(tg))
                        tg->funcs->lock(tg);
-       }
-
-       /* Blank controller using driver code instead of
-        * command table.
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
 
+               /* Blank controller using driver code instead of
+                * command table.
+                */
                if (tg->funcs->is_tg_enabled(tg)) {
                        tg->funcs->set_blank(tg, true);
                        hwss_wait_for_blank_complete(tg);
                }
        }
 
-       /* Reset all MPCC muxes */
        dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc);
 
-       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
                struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
                struct hubp *hubp = dc->res_pool->hubps[i];
                struct dpp *dpp = dc->res_pool->dpps[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               dpp->funcs->dpp_reset(dpp);
 
                pipe_ctx->stream_res.tg = tg;
                pipe_ctx->pipe_idx = i;
@@ -1064,18 +1001,9 @@ static void dcn10_init_hw(struct dc *dc)
                pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
 
                hwss1_plane_atomic_disconnect(dc, pipe_ctx);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
 
                if (tg->funcs->is_tg_enabled(tg))
                        tg->funcs->unlock(tg);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
 
                dcn10_disable_plane(dc, pipe_ctx);
 
@@ -1084,10 +1012,73 @@ static void dcn10_init_hw(struct dc *dc)
 
                tg->funcs->tg_init(tg);
        }
+}
+
+static void dcn10_init_hw(struct dc *dc)
+{
+       int i;
+       struct abm *abm = dc->res_pool->abm;
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+
+       if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+               REG_WRITE(REFCLK_CNTL, 0);
+               REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
+               REG_WRITE(DIO_MEM_PWR_CTRL, 0);
 
-       /* end of FPGA. Below if real ASIC */
-       if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+               if (!dc->debug.disable_clock_gate) {
+                       /* enable all DCN clock gating */
+                       REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+                       REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+                       REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+               }
+
+               enable_power_gating_plane(dc->hwseq, true);
+
+               /* end of FPGA. Below if real ASIC */
                return;
+       }
+
+       if (!dcb->funcs->is_accelerated_mode(dcb)) {
+               bool allow_self_fresh_force_enable =
+                       hububu1_is_allow_self_refresh_enabled(
+                                               dc->res_pool->hubbub);
+
+               bios_golden_init(dc);
+
+               /* WA for making DF sleep when idle after resume from S0i3.
+                * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
+                * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
+                * before calling command table and it changed to 1 after,
+                * it should be set back to 0.
+                */
+               if (allow_self_fresh_force_enable == false &&
+                               hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub))
+                       hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true);
+
+               disable_vga(dc->hwseq);
+       }
+
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
+                       dc->hwss.edp_power_control(link, true);
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+
+               /* Check for enabled DIG to identify enabled display */
+               if (link->link_enc->funcs->is_dig_enabled &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc))
+                       link->link_status.link_active = true;
+       }
 
        for (i = 0; i < dc->res_pool->audio_count; i++) {
                struct audio *audio = dc->res_pool->audios[i];
@@ -1118,6 +1109,9 @@ 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(
@@ -2718,6 +2712,7 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
 static const struct hw_sequencer_funcs dcn10_funcs = {
        .program_gamut_remap = program_gamut_remap,
        .init_hw = dcn10_init_hw,
+       .init_pipes = dcn10_init_pipes,
        .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
        .apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
        .update_plane_addr = dcn10_update_plane_addr,
index d6a85f48b6d17434cc62b07629c17463ad1fac18..341b4810288c25315fc2d6dc1ef1b03487b4b412 100644 (file)
@@ -70,6 +70,8 @@ struct hw_sequencer_funcs {
 
        void (*init_hw)(struct dc *dc);
 
+       void (*init_pipes)(struct dc *dc, struct dc_state *context);
+
        enum dc_status (*apply_ctx_to_hw)(
                        struct dc *dc, struct dc_state *context);