diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1230-drm-amd-display-refactor-init_hw-to-isolate-pipe-rel.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1230-drm-amd-display-refactor-init_hw-to-isolate-pipe-rel.patch | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1230-drm-amd-display-refactor-init_hw-to-isolate-pipe-rel.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1230-drm-amd-display-refactor-init_hw-to-isolate-pipe-rel.patch new file mode 100644 index 00000000..0b550f5e --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1230-drm-amd-display-refactor-init_hw-to-isolate-pipe-rel.patch @@ -0,0 +1,287 @@ +From 15cd4c81a7286399e53745ea94ccee4c1c114f67 Mon Sep 17 00:00:00 2001 +From: Anthony Koo <Anthony.Koo@amd.com> +Date: Sun, 20 Jan 2019 01:23:07 -0500 +Subject: [PATCH 1230/2940] drm/amd/display: refactor init_hw to isolate pipe + related init + +[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 + +Change-Id: Idc1c378a0eea78b8d93faced686b19d9b14f77f3 +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> +--- + .../display/dc/dce110/dce110_hw_sequencer.c | 6 + + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 159 +++++++++--------- + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 + + 3 files changed, 85 insertions(+), 82 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 423abc28de7f..0c92f33e35f4 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -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, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index d1ad55c56ba7..ac021b2877ab 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -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( +@@ -2717,6 +2711,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, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index d6a85f48b6d1..341b4810288c 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -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); + +-- +2.17.1 + |