[16/49] drm/amd/display: Make init_hw and init_pipes generic for seamless boot

Submitted by Li, Sun peng (Leo) on Aug. 9, 2019, 9:37 p.m.

Details

Message ID 20190809213742.30301-17-sunpeng.li@amd.com
State New
Headers show
Series "DC Patches 09 Aug, 2019" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Li, Sun peng (Leo) Aug. 9, 2019, 9:37 p.m.
From: Martin Leung <martin.leung@amd.com>

[Why]
For seamless boot the init_hw sequence must be split into
actual hardware vs pipes, in order to defer pipe initialization to set mode
and skip of pipe-destructive sequences

[How]
made dcn10_init_hw and dcn10_init_pipes generic for future dcns to inherit
deleted dcn20 specific versions. This is part 1 of a 2 partimplementation
of seamless boot

Signed-off-by: Martin Leung <martin.leung@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../display/dc/dce110/dce110_hw_sequencer.c   |  12 +-
 .../display/dc/dce110/dce110_hw_sequencer.h   |   6 +-
 .../drm/amd/display/dc/dcn10/dcn10_hubbub.c   |   4 +-
 .../drm/amd/display/dc/dcn10/dcn10_hubbub.h   |   2 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 182 ++++++---
 .../drm/amd/display/dc/dcn20/dcn20_hubbub.c   |   2 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 381 +++++++-----------
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h  |   4 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  32 ++
 9 files changed, 312 insertions(+), 313 deletions(-)

Patch hide | download patch | download mbox

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 919647166bce..5a046e5bc756 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
@@ -728,7 +728,7 @@  static enum bp_result link_transmitter_control(
  * @brief
  * eDP only.
  */
-void hwss_edp_wait_for_hpd_ready(
+void dce110_edp_wait_for_hpd_ready(
 		struct dc_link *link,
 		bool power_up)
 {
@@ -796,7 +796,7 @@  void hwss_edp_wait_for_hpd_ready(
 	}
 }
 
-void hwss_edp_power_control(
+void dce110_edp_power_control(
 		struct dc_link *link,
 		bool power_up)
 {
@@ -878,7 +878,7 @@  void hwss_edp_power_control(
  * @brief
  * eDP only. Control the backlight of the eDP panel
  */
-void hwss_edp_backlight_control(
+void dce110_edp_backlight_control(
 		struct dc_link *link,
 		bool enable)
 {
@@ -2755,9 +2755,9 @@  static const struct hw_sequencer_funcs dce110_funcs = {
 	.setup_stereo = NULL,
 	.set_avmute = dce110_set_avmute,
 	.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
-	.edp_backlight_control = hwss_edp_backlight_control,
-	.edp_power_control = hwss_edp_power_control,
-	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+	.edp_backlight_control = dce110_edp_backlight_control,
+	.edp_power_control = dce110_edp_power_control,
+	.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
 	.set_cursor_position = dce110_set_cursor_position,
 	.set_cursor_attribute = dce110_set_cursor_attribute
 };
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
index cd3e36d52a52..668feb0d169d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
@@ -73,15 +73,15 @@  void dce110_optimize_bandwidth(
 
 void dp_receiver_power_ctrl(struct dc_link *link, bool on);
 
-void hwss_edp_power_control(
+void dce110_edp_power_control(
 		struct dc_link *link,
 		bool power_up);
 
-void hwss_edp_backlight_control(
+void dce110_edp_backlight_control(
 	struct dc_link *link,
 	bool enable);
 
-void hwss_edp_wait_for_hpd_ready(
+void dce110_edp_wait_for_hpd_ready(
 		struct dc_link *link,
 		bool power_up);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index 0ab391446d3d..90c30a21bd09 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -102,7 +102,7 @@  void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
 }
 
-bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
+bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
 {
 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
 	uint32_t enable = 0;
@@ -943,6 +943,8 @@  static const struct hubbub_funcs hubbub1_funcs = {
 	.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
 	.wm_read_state = hubbub1_wm_read_state,
 	.program_watermarks = hubbub1_program_watermarks,
+	.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+	.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
 };
 
 void hubbub1_construct(struct hubbub *hubbub,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index 7c2559c9ae23..70e5d84fc69a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -247,7 +247,7 @@  void hubbub1_program_watermarks(
 
 void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow);
 
-bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubub);
+bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubub);
 
 void hubbub1_toggle_watermark_change_req(
 		struct hubbub *hubbub);
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 37424065987f..1bfc76cbddb8 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
@@ -437,7 +437,7 @@  bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx)
 	return false;
 }
 
-static void enable_power_gating_plane(
+static void dcn10_enable_power_gating_plane(
 	struct dce_hwseq *hws,
 	bool enable)
 {
@@ -459,7 +459,7 @@  static void enable_power_gating_plane(
 	REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
 }
 
-static void disable_vga(
+static void dcn10_disable_vga(
 	struct dce_hwseq *hws)
 {
 	unsigned int in_vga1_mode = 0;
@@ -492,7 +492,7 @@  static void disable_vga(
 	REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
 }
 
-static void dpp_pg_control(
+static void dcn10_dpp_pg_control(
 		struct dce_hwseq *hws,
 		unsigned int dpp_inst,
 		bool power_on)
@@ -544,7 +544,7 @@  static void dpp_pg_control(
 	}
 }
 
-static void hubp_pg_control(
+static void dcn10_hubp_pg_control(
 		struct dce_hwseq *hws,
 		unsigned int hubp_inst,
 		bool power_on)
@@ -604,8 +604,8 @@  static void power_on_plane(
 	if (REG(DC_IP_REQUEST_CNTL)) {
 		REG_SET(DC_IP_REQUEST_CNTL, 0,
 				IP_REQUEST_EN, 1);
-		dpp_pg_control(hws, plane_id, true);
-		hubp_pg_control(hws, plane_id, true);
+		hws->ctx->dc->hwss.dpp_pg_control(hws, plane_id, true);
+		hws->ctx->dc->hwss.hubp_pg_control(hws, plane_id, true);
 		REG_SET(DC_IP_REQUEST_CNTL, 0,
 				IP_REQUEST_EN, 0);
 		DC_LOG_DEBUG(
@@ -626,7 +626,7 @@  static void undo_DEGVIDCN10_253_wa(struct dc *dc)
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 1);
 
-	hubp_pg_control(hws, 0, false);
+	dc->hwss.hubp_pg_control(hws, 0, false);
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 0);
 
@@ -655,7 +655,7 @@  static void apply_DEGVIDCN10_253_wa(struct dc *dc)
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 1);
 
-	hubp_pg_control(hws, 0, true);
+	dc->hwss.hubp_pg_control(hws, 0, true);
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 0);
 
@@ -663,10 +663,23 @@  static void apply_DEGVIDCN10_253_wa(struct dc *dc)
 	hws->wa_state.DEGVIDCN10_253_applied = true;
 }
 
-static void bios_golden_init(struct dc *dc)
+static void dcn10_bios_golden_init(struct dc *dc)
 {
 	struct dc_bios *bp = dc->ctx->dc_bios;
 	int i;
+	bool allow_self_fresh_force_enable = true;
+
+	if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
+		allow_self_fresh_force_enable =
+				dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
+
+
+	/* 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.
+	 */
 
 	/* initialize dcn global */
 	bp->funcs->enable_disp_power_gating(bp,
@@ -677,6 +690,12 @@  static void bios_golden_init(struct dc *dc)
 		bp->funcs->enable_disp_power_gating(bp,
 				CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
 	}
+
+	if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+		if (allow_self_fresh_force_enable == false &&
+				dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub))
+			dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, true);
+
 }
 
 static void false_optc_underflow_wa(
@@ -970,7 +989,7 @@  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,
+static void dcn10_plane_atomic_power_down(struct dc *dc,
 		struct dpp *dpp,
 		struct hubp *hubp)
 {
@@ -980,8 +999,8 @@  static void plane_atomic_power_down(struct dc *dc,
 	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, hubp->inst, false);
+		dc->hwss.dpp_pg_control(hws, dpp->inst, false);
+		dc->hwss.hubp_pg_control(hws, hubp->inst, false);
 		dpp->funcs->dpp_reset(dpp);
 		REG_SET(DC_IP_REQUEST_CNTL, 0,
 				IP_REQUEST_EN, 0);
@@ -993,7 +1012,7 @@  static void plane_atomic_power_down(struct dc *dc,
 /* disable HW used by plane.
  * note:  cannot disable until disconnect is complete
  */
-static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+static void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
 {
 	struct hubp *hubp = pipe_ctx->plane_res.hubp;
 	struct dpp *dpp = pipe_ctx->plane_res.dpp;
@@ -1013,7 +1032,7 @@  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,
+	dc->hwss.plane_atomic_power_down(dc,
 			pipe_ctx->plane_res.dpp,
 			pipe_ctx->plane_res.hubp);
 
@@ -1032,7 +1051,7 @@  static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
 	if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
 		return;
 
-	plane_atomic_disable(dc, pipe_ctx);
+	dc->hwss.plane_atomic_disable(dc, pipe_ctx);
 
 	apply_DEGVIDCN10_253_wa(dc);
 
@@ -1067,9 +1086,14 @@  static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
 		 * command table.
 		 */
 		if (tg->funcs->is_tg_enabled(tg)) {
-			tg->funcs->lock(tg);
-			tg->funcs->set_blank(tg, true);
-			hwss_wait_for_blank_complete(tg);
+			if (dc->hwss.init_blank != NULL) {
+				dc->hwss.init_blank(dc, tg);
+				tg->funcs->lock(tg);
+			} else {
+				tg->funcs->lock(tg);
+				tg->funcs->set_blank(tg, true);
+				hwss_wait_for_blank_complete(tg);
+			}
 		}
 	}
 
@@ -1113,12 +1137,12 @@  static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
 		dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
 		pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
 
-		hwss1_plane_atomic_disconnect(dc, pipe_ctx);
+		dc->hwss.plane_atomic_disconnect(dc, pipe_ctx);
 
 		if (tg->funcs->is_tg_enabled(tg))
 			tg->funcs->unlock(tg);
 
-		dcn10_disable_plane(dc, pipe_ctx);
+		dc->hwss.disable_plane(dc, pipe_ctx);
 
 		pipe_ctx->stream_res.tg = NULL;
 		pipe_ctx->plane_res.hubp = NULL;
@@ -1134,8 +1158,17 @@  static void dcn10_init_hw(struct dc *dc)
 	struct dmcu *dmcu = dc->res_pool->dmcu;
 	struct dce_hwseq *hws = dc->hwseq;
 	struct dc_bios *dcb = dc->ctx->dc_bios;
+	struct resource_pool *res_pool = dc->res_pool;
+
+	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+	// Initialize the dccg
+	if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init)
+		dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
 
 	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);
@@ -1149,30 +1182,39 @@  static void dcn10_init_hw(struct dc *dc)
 			REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
 		}
 
-		enable_power_gating_plane(dc->hwseq, true);
+		//Enable ability to power gate / don't force power on permanently
+		dc->hwss.enable_power_gating_plane(hws, 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);
+		dc->hwss.bios_golden_init(dc);
+		if (dc->ctx->dc_bios->fw_info_valid) {
+			res_pool->ref_clocks.xtalin_clock_inKhz =
+					dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+			if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+				if (res_pool->dccg && res_pool->hubbub) {
+
+					(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+							dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+							&res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+					(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+							res_pool->ref_clocks.dccg_ref_clock_inKhz,
+							&res_pool->ref_clocks.dchub_ref_clock_inKhz);
+				} else {
+					// Not all ASICs have DCCG sw component
+					res_pool->ref_clocks.dccg_ref_clock_inKhz =
+							res_pool->ref_clocks.xtalin_clock_inKhz;
+					res_pool->ref_clocks.dchub_ref_clock_inKhz =
+							res_pool->ref_clocks.xtalin_clock_inKhz;
+				}
+			}
+		} else
+			ASSERT_CRITICAL(false);
+		dc->hwss.disable_vga(dc->hwseq);
 	}
 
 	for (i = 0; i < dc->link_count; i++) {
@@ -1190,6 +1232,13 @@  static void dcn10_init_hw(struct dc *dc)
 			link->link_status.link_active = true;
 	}
 
+	/* Power gate DSCs */
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	for (i = 0; i < res_pool->res_cap->num_dsc; i++)
+		if (dc->hwss.dsc_pg_control != NULL)
+			dc->hwss.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
+#endif
+
 	/* 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.
@@ -1198,10 +1247,21 @@  static void dcn10_init_hw(struct dc *dc)
 	 */
 	if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
 		dc->hwss.init_pipes(dc, dc->current_state);
+		for (i = 0; i < res_pool->pipe_count; i++) {
+			struct hubp *hubp = res_pool->hubps[i];
+			struct dpp *dpp = res_pool->dpps[i];
+
+			hubp->funcs->hubp_init(hubp);
+			res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
+			dc->hwss.plane_atomic_power_down(dc, dpp, hubp);
+		}
+
+		apply_DEGVIDCN10_253_wa(dc);
 	}
 
-	for (i = 0; i < dc->res_pool->audio_count; i++) {
-		struct audio *audio = dc->res_pool->audios[i];
+
+	for (i = 0; i < res_pool->audio_count; i++) {
+		struct audio *audio = res_pool->audios[i];
 
 		audio->funcs->hw_init(audio);
 	}
@@ -1229,7 +1289,7 @@  static void dcn10_init_hw(struct dc *dc)
 		REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
 	}
 
-	enable_power_gating_plane(dc->hwseq, true);
+	dc->hwss.enable_power_gating_plane(dc->hwseq, true);
 
 	memset(&dc->clk_mgr->clks, 0, sizeof(dc->clk_mgr->clks));
 }
@@ -1788,7 +1848,7 @@  static void dcn10_enable_plane(
 	}
 }
 
-static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
+static void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
 {
 	int i = 0;
 	struct dpp_grph_csc_adjustment adjust;
@@ -2219,7 +2279,7 @@  void update_dchubp_dpp(
 
 	if (plane_state->update_flags.bits.full_update) {
 		/*gamut remap*/
-		program_gamut_remap(pipe_ctx);
+		dc->hwss.program_gamut_remap(pipe_ctx);
 
 		dc->hwss.program_output_csc(dc,
 				pipe_ctx,
@@ -2456,7 +2516,7 @@  static void dcn10_apply_ctx_for_surface(
 			if (old_pipe_ctx->stream_res.tg == tg &&
 			    old_pipe_ctx->plane_res.hubp &&
 			    old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID)
-				dcn10_disable_plane(dc, old_pipe_ctx);
+				dc->hwss.disable_plane(dc, old_pipe_ctx);
 		}
 
 		if ((!pipe_ctx->plane_state ||
@@ -2504,7 +2564,7 @@  static void dcn10_apply_ctx_for_surface(
 
 	for (i = 0; i < dc->res_pool->pipe_count; i++)
 		if (removed_pipe[i])
-			dcn10_disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
+			dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
 
 	for (i = 0; i < dc->res_pool->pipe_count; i++)
 		if (removed_pipe[i]) {
@@ -2596,7 +2656,7 @@  static void dcn10_optimize_bandwidth(
 		dcn10_verify_allow_pstate_change_high(dc);
 }
 
-static void set_drr(struct pipe_ctx **pipe_ctx,
+static void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
 		int num_pipes, int vmin, int vmax)
 {
 	int i = 0;
@@ -2621,7 +2681,7 @@  static void set_drr(struct pipe_ctx **pipe_ctx,
 	}
 }
 
-static void get_position(struct pipe_ctx **pipe_ctx,
+static void dcn10_get_position(struct pipe_ctx **pipe_ctx,
 		int num_pipes,
 		struct crtc_position *position)
 {
@@ -2633,7 +2693,7 @@  static void get_position(struct pipe_ctx **pipe_ctx,
 		pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
 }
 
-static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
+static void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
 		int num_pipes, const struct dc_static_screen_events *events)
 {
 	unsigned int i;
@@ -3124,7 +3184,7 @@  static void dcn10_get_clock(struct dc *dc,
 }
 
 static const struct hw_sequencer_funcs dcn10_funcs = {
-	.program_gamut_remap = program_gamut_remap,
+	.program_gamut_remap = dcn10_program_gamut_remap,
 	.init_hw = dcn10_init_hw,
 	.init_pipes = dcn10_init_pipes,
 	.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
@@ -3157,18 +3217,18 @@  static const struct hw_sequencer_funcs dcn10_funcs = {
 	.optimize_bandwidth = dcn10_optimize_bandwidth,
 	.reset_hw_ctx_wrap = dcn10_reset_hw_ctx_wrap,
 	.enable_stream_timing = dcn10_enable_stream_timing,
-	.set_drr = set_drr,
-	.get_position = get_position,
-	.set_static_screen_control = set_static_screen_control,
+	.set_drr = dcn10_set_drr,
+	.get_position = dcn10_get_position,
+	.set_static_screen_control = dcn10_set_static_screen_control,
 	.setup_stereo = dcn10_setup_stereo,
 	.set_avmute = dce110_set_avmute,
 	.log_hw_state = dcn10_log_hw_state,
 	.get_hw_state = dcn10_get_hw_state,
 	.clear_status_bits = dcn10_clear_status_bits,
 	.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
-	.edp_backlight_control = hwss_edp_backlight_control,
-	.edp_power_control = hwss_edp_power_control,
-	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+	.edp_backlight_control = dce110_edp_backlight_control,
+	.edp_power_control = dce110_edp_power_control,
+	.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
 	.set_cursor_position = dcn10_set_cursor_position,
 	.set_cursor_attribute = dcn10_set_cursor_attribute,
 	.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
@@ -3178,6 +3238,16 @@  static const struct hw_sequencer_funcs dcn10_funcs = {
 	.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
 	.set_clock = dcn10_set_clock,
 	.get_clock = dcn10_get_clock,
+	.did_underflow_occur = dcn10_did_underflow_occur,
+	.init_blank = NULL,
+	.disable_vga = dcn10_disable_vga,
+	.bios_golden_init = dcn10_bios_golden_init,
+	.plane_atomic_disable = dcn10_plane_atomic_disable,
+	.plane_atomic_power_down = dcn10_plane_atomic_power_down,
+	.enable_power_gating_plane = dcn10_enable_power_gating_plane,
+	.dpp_pg_control = dcn10_dpp_pg_control,
+	.hubp_pg_control = dcn10_hubp_pg_control,
+	.dsc_pg_control = NULL,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
index 31d6e79ba2b8..cd101bbd8163 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -582,7 +582,7 @@  static const struct hubbub_funcs hubbub2_funcs = {
 	.get_dcc_compression_cap = hubbub2_get_dcc_compression_cap,
 	.wm_read_state = hubbub2_wm_read_state,
 	.get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
-	.program_watermarks = hubbub2_program_watermarks,
+	.program_watermarks = hubbub2_program_watermarks
 };
 
 void hubbub2_construct(struct dcn20_hubbub *hubbub,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index c11de6f0fe5c..c3635f5cd990 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -64,23 +64,7 @@ 
 #define FN(reg_name, field_name) \
 	hws->shifts->field_name, hws->masks->field_name
 
-static void bios_golden_init(struct dc *dc)
-{
-	struct dc_bios *bp = dc->ctx->dc_bios;
-	int i;
-
-	/* initialize dcn global */
-	bp->funcs->enable_disp_power_gating(bp,
-			CONTROLLER_ID_D0, ASIC_PIPE_INIT);
-
-	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		/* initialize dcn per pipe */
-		bp->funcs->enable_disp_power_gating(bp,
-				CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
-	}
-}
-
-static void enable_power_gating_plane(
+static void dcn20_enable_power_gating_plane(
 	struct dce_hwseq *hws,
 	bool enable)
 {
@@ -184,7 +168,7 @@  void dcn20_display_init(struct dc *dc)
 	REG_WRITE(AZALIA_CONTROLLER_CLOCK_GATING, 0x1);
 }
 
-static void disable_vga(
+void dcn20_disable_vga(
 	struct dce_hwseq *hws)
 {
 	REG_WRITE(D1VGA_CONTROL, 0);
@@ -487,29 +471,6 @@  static void dcn20_hubp_pg_control(
 }
 
 
-
-static void dcn20_plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-	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);
-		dcn20_dpp_pg_control(hws, dpp->inst, false);
-		dcn20_hubp_pg_control(hws, pipe_ctx->plane_res.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);
-	}
-}
-
-
-
 /* disable HW used by plane.
  * note:  cannot disable until disconnect is complete
  */
@@ -535,7 +496,9 @@  static void dcn20_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 */
 
-	dcn20_plane_atomic_power_down(dc, pipe_ctx);
+	dc->hwss.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));
@@ -559,204 +522,6 @@  void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
 					pipe_ctx->pipe_idx);
 }
 
-static void dcn20_init_hw(struct dc *dc)
-{
-	int i, j;
-	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 resource_pool *res_pool = dc->res_pool;
-	struct dc_state  *context = dc->current_state;
-
-	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-	// Initialize the dccg
-	if (res_pool->dccg->funcs->dccg_init)
-		res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-	//Enable ability to power gate / don't force power on permanently
-	enable_power_gating_plane(dc->hwseq, true);
-
-	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-		REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
-		REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
-
-		dcn20_dccg_init(hws);
-
-		REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
-		REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
-		REG_WRITE(REFCLK_CNTL, 0);
-	} else {
-		if (!dcb->funcs->is_accelerated_mode(dcb)) {
-			bios_golden_init(dc);
-			if (dc->ctx->dc_bios->fw_info_valid) {
-				res_pool->ref_clocks.xtalin_clock_inKhz =
-						dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-				if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-					if (res_pool->dccg && res_pool->hubbub) {
-
-						(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-								dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-								&res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-						(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-								res_pool->ref_clocks.dccg_ref_clock_inKhz,
-								&res_pool->ref_clocks.dchub_ref_clock_inKhz);
-					} else {
-						// Not all ASICs have DCCG sw component
-						res_pool->ref_clocks.dccg_ref_clock_inKhz =
-								res_pool->ref_clocks.xtalin_clock_inKhz;
-						res_pool->ref_clocks.dchub_ref_clock_inKhz =
-								res_pool->ref_clocks.xtalin_clock_inKhz;
-					}
-				}
-			} else
-				ASSERT_CRITICAL(false);
-			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];
-
-			link->link_enc->funcs->hw_init(link->link_enc);
-		}
-	}
-
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	/* Power gate DSCs */
-	for (i = 0; i < res_pool->res_cap->num_dsc; i++)
-		dcn20_dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
-#endif
-
-	/* Blank pixel data with OPP DPG */
-	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-		struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-		if (tg->funcs->is_tg_enabled(tg)) {
-			dcn20_init_blank(dc, tg);
-		}
-	}
-
-	for (i = 0; i < res_pool->timing_generator_count; i++) {
-		struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-		if (tg->funcs->is_tg_enabled(tg))
-			tg->funcs->lock(tg);
-	}
-
-	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		struct dpp *dpp = res_pool->dpps[i];
-
-		dpp->funcs->dpp_reset(dpp);
-	}
-
-	/* Reset all MPCC muxes */
-	res_pool->mpc->funcs->mpc_init(res_pool->mpc);
-
-	/* initialize OPP mpc_tree parameter */
-	for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-		res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
-		res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-		for (j = 0; j < MAX_PIPES; j++)
-			res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
-	}
-
-	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];
-
-		pipe_ctx->stream_res.tg = tg;
-		pipe_ctx->pipe_idx = i;
-
-		pipe_ctx->plane_res.hubp = hubp;
-		pipe_ctx->plane_res.dpp = dpp;
-		pipe_ctx->plane_res.mpcc_inst = dpp->inst;
-		hubp->mpcc_id = dpp->inst;
-		hubp->opp_id = OPP_ID_INVALID;
-		hubp->power_gated = false;
-		pipe_ctx->stream_res.opp = NULL;
-
-		hubp->funcs->hubp_init(hubp);
-
-		//dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
-		//dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-		dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-		pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
-		/*to do*/
-		hwss1_plane_atomic_disconnect(dc, pipe_ctx);
-	}
-
-	/* initialize DWB pointer to MCIF_WB */
-	for (i = 0; i < res_pool->res_cap->num_dwb; i++)
-		res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
-
-	for (i = 0; i < dc->res_pool->timing_generator_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 pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-		dc->hwss.disable_plane(dc, pipe_ctx);
-
-		pipe_ctx->stream_res.tg = NULL;
-		pipe_ctx->plane_res.hubp = NULL;
-	}
-
-	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-		struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-		tg->funcs->tg_init(tg);
-	}
-
-	/* end of FPGA. Below if real ASIC */
-	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
-		return;
-
-
-	for (i = 0; i < res_pool->audio_count; i++) {
-		struct audio *audio = res_pool->audios[i];
-
-		audio->funcs->hw_init(audio);
-	}
-
-	if (abm != NULL) {
-		abm->funcs->init_backlight(abm);
-		abm->funcs->abm_init(abm);
-	}
-
-	if (dmcu != NULL)
-		dmcu->funcs->dmcu_init(dmcu);
-
-	if (abm != NULL && dmcu != NULL)
-		abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
-
-	/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-	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);
-	}
-
-}
-
 enum dc_status dcn20_enable_stream_timing(
 		struct pipe_ctx *pipe_ctx,
 		struct dc_state *context,
@@ -1409,7 +1174,7 @@  static void dcn20_apply_ctx_for_surface(
 			if (old_pipe_ctx->stream_res.tg == tg &&
 			    old_pipe_ctx->plane_res.hubp &&
 			    old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID)
-				dcn20_disable_plane(dc, old_pipe_ctx);
+				dc->hwss.disable_plane(dc, old_pipe_ctx);
 		}
 
 		if ((!pipe_ctx->plane_state ||
@@ -2169,14 +1934,126 @@  static void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
 						hubp->inst, mode);
 }
 
+static void dcn20_fpga_init_hw(struct dc *dc)
+{
+	int i, j;
+	struct dce_hwseq *hws = dc->hwseq;
+	struct resource_pool *res_pool = dc->res_pool;
+	struct dc_state  *context = dc->current_state;
+
+	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+	// Initialize the dccg
+	if (res_pool->dccg->funcs->dccg_init)
+		res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+	//Enable ability to power gate / don't force power on permanently
+	dc->hwss.enable_power_gating_plane(hws, true);
+
+	// Specific to FPGA dccg and registers
+	REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
+	REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
+
+	dcn20_dccg_init(hws);
+
+	REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
+	REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
+	REG_WRITE(REFCLK_CNTL, 0);
+	//
+
+
+	/* Blank pixel data with OPP DPG */
+	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+		struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+		if (tg->funcs->is_tg_enabled(tg))
+			dcn20_init_blank(dc, tg);
+	}
+
+	for (i = 0; i < res_pool->timing_generator_count; i++) {
+		struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+		if (tg->funcs->is_tg_enabled(tg))
+			tg->funcs->lock(tg);
+	}
+
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		struct dpp *dpp = res_pool->dpps[i];
+
+		dpp->funcs->dpp_reset(dpp);
+	}
+
+	/* Reset all MPCC muxes */
+	res_pool->mpc->funcs->mpc_init(res_pool->mpc);
+
+	/* initialize OPP mpc_tree parameter */
+	for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+		res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
+		res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+		for (j = 0; j < MAX_PIPES; j++)
+			res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
+	}
+
+	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];
+
+		pipe_ctx->stream_res.tg = tg;
+		pipe_ctx->pipe_idx = i;
+
+		pipe_ctx->plane_res.hubp = hubp;
+		pipe_ctx->plane_res.dpp = dpp;
+		pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+		hubp->mpcc_id = dpp->inst;
+		hubp->opp_id = OPP_ID_INVALID;
+		hubp->power_gated = false;
+		pipe_ctx->stream_res.opp = NULL;
+
+		hubp->funcs->hubp_init(hubp);
+
+		//dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+		//dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+		dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+		pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
+		/*to do*/
+		hwss1_plane_atomic_disconnect(dc, pipe_ctx);
+	}
+
+	/* initialize DWB pointer to MCIF_WB */
+	for (i = 0; i < res_pool->res_cap->num_dwb; i++)
+		res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
+
+	for (i = 0; i < dc->res_pool->timing_generator_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 pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+		dc->hwss.disable_plane(dc, pipe_ctx);
+
+		pipe_ctx->stream_res.tg = NULL;
+		pipe_ctx->plane_res.hubp = NULL;
+	}
+
+	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+		struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+		tg->funcs->tg_init(tg);
+	}
+}
+
 void dcn20_hw_sequencer_construct(struct dc *dc)
 {
 	dcn10_hw_sequencer_construct(dc);
-	dc->hwss.init_hw = dcn20_init_hw;
-	dc->hwss.init_pipes = NULL;
 	dc->hwss.unblank_stream = dcn20_unblank_stream;
 	dc->hwss.update_plane_addr = dcn20_update_plane_addr;
-	dc->hwss.disable_plane = dcn20_disable_plane,
 	dc->hwss.enable_stream_timing = dcn20_enable_stream_timing;
 	dc->hwss.program_triplebuffer = dcn20_program_tripleBuffer;
 	dc->hwss.set_input_transfer_func = dcn20_set_input_transfer_func;
@@ -2204,5 +2081,19 @@  void dcn20_hw_sequencer_construct(struct dc *dc)
 	dc->hwss.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap;
 	dc->hwss.update_mpcc = dcn20_update_mpcc;
 	dc->hwss.set_flip_control_gsl = dcn20_set_flip_control_gsl;
-	dc->hwss.did_underflow_occur = dcn10_did_underflow_occur;
+	dc->hwss.init_blank = dcn20_init_blank;
+	dc->hwss.disable_plane = dcn20_disable_plane;
+	dc->hwss.plane_atomic_disable = dcn20_plane_atomic_disable;
+	dc->hwss.enable_power_gating_plane = dcn20_enable_power_gating_plane;
+	dc->hwss.dpp_pg_control = dcn20_dpp_pg_control;
+	dc->hwss.hubp_pg_control = dcn20_hubp_pg_control;
+	dc->hwss.dsc_pg_control = dcn20_dsc_pg_control;
+	dc->hwss.disable_vga = dcn20_disable_vga;
+
+	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+		dc->hwss.init_hw = dcn20_fpga_init_hw;
+		dc->hwss.init_pipes = NULL;
+	}
+
+
 }
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 9502478c4a1b..c1f29b1654d9 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -141,6 +141,10 @@  struct hubbub_funcs {
 			struct dcn_watermark_set *watermarks,
 			unsigned int refclk_mhz,
 			bool safe_to_lower);
+
+	bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
+	void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
+
 };
 
 struct hubbub {
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 28645e10f854..80de2febd7cb 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -78,6 +78,8 @@  struct stream_resource;
 struct dc_phy_addr_space_config;
 struct dc_virtual_addr_space_config;
 #endif
+struct hubp;
+struct dpp;
 
 struct hw_sequencer_funcs {
 
@@ -280,6 +282,36 @@  struct hw_sequencer_funcs {
 	void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx);
 	bool (*did_underflow_occur)(struct dc *dc, struct pipe_ctx *pipe_ctx);
 
+	void (*init_blank)(struct dc *dc, struct timing_generator *tg);
+	void (*disable_vga)(struct dce_hwseq *hws);
+	void (*bios_golden_init)(struct dc *dc);
+	void (*plane_atomic_power_down)(struct dc *dc,
+			struct dpp *dpp,
+			struct hubp *hubp);
+
+	void (*plane_atomic_disable)(
+			struct dc *dc, struct pipe_ctx *pipe_ctx);
+
+	void (*enable_power_gating_plane)(
+		struct dce_hwseq *hws,
+		bool enable);
+
+	void (*dpp_pg_control)(
+			struct dce_hwseq *hws,
+			unsigned int dpp_inst,
+			bool power_on);
+
+	void (*hubp_pg_control)(
+			struct dce_hwseq *hws,
+			unsigned int hubp_inst,
+			bool power_on);
+
+	void (*dsc_pg_control)(
+			struct dce_hwseq *hws,
+			unsigned int dsc_inst,
+			bool power_on);
+
+
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 	void (*update_odm)(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
 	void (*program_all_writeback_pipes_in_tree)(