aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1230-drm-amd-display-refactor-init_hw-to-isolate-pipe-rel.patch
diff options
context:
space:
mode:
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.patch287
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
+