[66/76] drm/amd/dal: consolidate DCE hw_sequencer

Submitted by Harry Wentland on Nov. 21, 2016, 11:01 p.m.

Details

Message ID 20161121230136.5208-67-harry.wentland@amd.com
State New
Headers show
Series "DAL Patches Nov 21, 2016" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Harry Wentland Nov. 21, 2016, 11:01 p.m.
From: Tony Cheng <tony.cheng@amd.com>

- store register offset / shift / mask in dce_hwseq
- retire func_ptr enable_fe_clock and replace with direct call

- add debug assert guarding read/write to uninitialized offset

Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
---
 drivers/gpu/drm/amd/dal/dc/core/dc_resource.c      |  2 +
 drivers/gpu/drm/amd/dal/dc/dce/Makefile            |  2 +-
 drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.c         | 43 +++++++++++
 drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.h         | 78 +++++++++++++++++++
 .../drm/amd/dal/dc/dce100/dce100_hw_sequencer.c    | 19 -----
 .../gpu/drm/amd/dal/dc/dce100/dce100_resource.c    | 33 +++++++-
 .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c    | 33 +-------
 .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c    | 33 +++++++-
 .../drm/amd/dal/dc/dce112/dce112_hw_sequencer.c    | 30 +-------
 .../gpu/drm/amd/dal/dc/dce112/dce112_resource.c    | 33 +++++++-
 .../gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c  | 20 +----
 drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c  | 33 +++++++-
 drivers/gpu/drm/amd/dal/dc/dm_services.h           | 90 ++++++++++++----------
 drivers/gpu/drm/amd/dal/dc/inc/core_dc.h           |  1 +
 drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h      |  3 -
 drivers/gpu/drm/amd/dal/dc/inc/resource.h          |  7 +-
 16 files changed, 313 insertions(+), 147 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.h

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
index 0578052859e3..25b03cba906e 100644
--- a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
@@ -193,6 +193,8 @@  bool resource_construct(
 		pool->stream_enc_count++;
 	}
 
+	dc->hwseq = create_funcs->create_hwseq(ctx);
+
 	return true;
 }
 
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/Makefile b/drivers/gpu/drm/amd/dal/dc/dce/Makefile
index 306070dd5455..738f33f64d64 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce/Makefile
+++ b/drivers/gpu/drm/amd/dal/dc/dce/Makefile
@@ -5,7 +5,7 @@ 
 #   - register programming through common macros that look up register 
 #     offset/shift/mask stored in dce_hw struct
 
-DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o
+DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o
 
 AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
 
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.c b/drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.c
new file mode 100644
index 000000000000..2eab8fb3be7d
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.c
@@ -0,0 +1,43 @@ 
+/*
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dce_hwseq.h"
+#include "reg_helper.h"
+
+#define CTX \
+	hws->ctx
+#define REG(reg)\
+	hws->regs->reg
+
+#undef FN
+#define FN(reg_name, field_name) \
+	hws->shifts->field_name, hws->masks->field_name
+
+void dce_enable_fe_clock(struct dce_hwseq *hws,
+		unsigned int fe_inst, bool enable)
+{
+	REG_UPDATE(DCFE_CLOCK_CONTROL[fe_inst],
+			DCFE_CLOCK_ENABLE, enable);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.h
new file mode 100644
index 000000000000..b12b2a3b1405
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_hwseq.h
@@ -0,0 +1,78 @@ 
+/*
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __DCE_HWSEQ_H__
+#define __DCE_HWSEQ_H__
+
+#include "hw_sequencer.h"
+
+#define HWSEQ_DCE8_REG_LIST_BASE() \
+	.DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
+	.DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \
+	.DCFE_CLOCK_CONTROL[2] = mmCRTC2_CRTC_DCFE_CLOCK_CONTROL, \
+	.DCFE_CLOCK_CONTROL[3] = mmCRTC3_CRTC_DCFE_CLOCK_CONTROL, \
+	.DCFE_CLOCK_CONTROL[4] = mmCRTC4_CRTC_DCFE_CLOCK_CONTROL, \
+	.DCFE_CLOCK_CONTROL[5] = mmCRTC5_CRTC_DCFE_CLOCK_CONTROL, \
+
+#define HWSEQ_COMMON_REG_LIST_BASE() \
+	SRII(DCFE_CLOCK_CONTROL, DCFE, 0), \
+	SRII(DCFE_CLOCK_CONTROL, DCFE, 1), \
+	SRII(DCFE_CLOCK_CONTROL, DCFE, 2), \
+	SRII(DCFE_CLOCK_CONTROL, DCFE, 3), \
+	SRII(DCFE_CLOCK_CONTROL, DCFE, 4), \
+	SRII(DCFE_CLOCK_CONTROL, DCFE, 5), \
+
+ /* set field name */
+#define SF(reg_name, field_name, post_fix)\
+	.field_name = reg_name ## __ ## field_name ## post_fix
+
+#define HWSEQ_DCE8_MASK_SH_LIST_BASE(mask_sh)\
+	.DCFE_CLOCK_ENABLE = CRTC_DCFE_CLOCK_CONTROL__CRTC_DCFE_CLOCK_ENABLE ## mask_sh, \
+
+#define HWSEQ_COMMON_MASK_SH_LIST_BASE(mask_sh)\
+	SF(DCFE_CLOCK_CONTROL, DCFE_CLOCK_ENABLE, mask_sh),\
+
+struct dce_hwseq_registers {
+	uint32_t DCFE_CLOCK_CONTROL[6];
+};
+
+struct dce_hwseq_shift {
+	uint8_t DCFE_CLOCK_ENABLE;
+};
+
+struct dce_hwseq_mask {
+	uint32_t DCFE_CLOCK_ENABLE;
+};
+
+struct dce_hwseq {
+	struct dc_context *ctx;
+	const struct dce_hwseq_registers *regs;
+	const struct dce_hwseq_shift *shifts;
+	const struct dce_hwseq_mask *masks;
+};
+
+void dce_enable_fe_clock(struct dce_hwseq *hwss,
+		unsigned int inst, bool enable);
+
+#endif   /*__DCE_HWSEQ_H__*/
diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_hw_sequencer.c
index 713291d7853f..b17cdf702fec 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_hw_sequencer.c
@@ -83,24 +83,6 @@  static const struct dce100_hw_seq_reg_offsets reg_offsets[] = {
  * Private definitions
  ******************************************************************************/
 /***************************PIPE_CONTROL***********************************/
-static void dce100_enable_fe_clock(
-	struct dc_context *ctx, uint8_t controller_id, bool enable)
-{
-	uint32_t value = 0;
-	uint32_t addr;
-
-	addr = HW_REG_CRTC(mmDCFE_CLOCK_CONTROL, controller_id);
-
-	value = dm_read_reg(ctx, addr);
-
-	set_reg_field_value(
-		value,
-		enable,
-		DCFE_CLOCK_CONTROL,
-		DCFE_CLOCK_ENABLE);
-
-	dm_write_reg(ctx, addr, value);
-}
 
 static bool dce100_pipe_control_lock(
 	struct dc_context *ctx,
@@ -287,7 +269,6 @@  bool dce100_hw_sequencer_construct(struct core_dc *dc)
 	dc->hwss.clock_gating_power_up = dal_dc_clock_gating_dce100_power_up;
 
 	dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating;
-	dc->hwss.enable_fe_clock = dce100_enable_fe_clock;
 	dc->hwss.pipe_control_lock = dce100_pipe_control_lock;
 	dc->hwss.set_blender_mode = dce100_set_blender_mode;
 	dc->hwss.set_displaymarks = set_displaymarks;
diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
index 9062ca209fd9..2451327de092 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
@@ -43,6 +43,7 @@ 
 #include "dce110/dce110_opp.h"
 #include "dce110/dce110_clock_source.h"
 #include "dce/dce_audio.h"
+#include "dce/dce_hwseq.h"
 #include "dce100/dce100_hw_sequencer.h"
 
 #include "reg_helper.h"
@@ -446,10 +447,40 @@  static struct stream_encoder *dce100_stream_encoder_create(
 	return NULL;
 }
 
+#define SRII(reg_name, block, id)\
+	.reg_name[id] = mm ## block ## id ## _ ## reg_name
+
+static const struct dce_hwseq_registers hwseq_reg = {
+		HWSEQ_COMMON_REG_LIST_BASE()
+};
+
+static const struct dce_hwseq_shift hwseq_shift = {
+		HWSEQ_COMMON_MASK_SH_LIST_BASE(__SHIFT)
+};
+
+static const struct dce_hwseq_mask hwseq_mask = {
+		HWSEQ_COMMON_MASK_SH_LIST_BASE(_MASK)
+};
+
+static struct dce_hwseq *dce100_hwseq_create(
+	struct dc_context *ctx)
+{
+	struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
+
+	if (hws) {
+		hws->ctx = ctx;
+		hws->regs = &hwseq_reg;
+		hws->shifts = &hwseq_shift;
+		hws->masks = &hwseq_mask;
+	}
+	return hws;
+}
+
 static const struct resource_create_funcs res_create_funcs = {
 	.read_dce_straps = read_dce_straps,
 	.create_audio = create_audio,
-	.create_stream_encoder = dce100_stream_encoder_create
+	.create_stream_encoder = dce100_stream_encoder_create,
+	.create_hwseq = dce100_hwseq_create,
 };
 
 static struct mem_input *dce100_mem_input_create(
diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
index 249438456f73..c4a2bbf57dcd 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
@@ -46,13 +46,13 @@ 
 #include "clock_source.h"
 #include "gamma_calcs.h"
 #include "audio.h"
+#include "dce/dce_hwseq.h"
 
 /* include DCE11 register header files */
 #include "dce/dce_11_0_d.h"
 #include "dce/dce_11_0_sh_mask.h"
 
 struct dce110_hw_seq_reg_offsets {
-	uint32_t dcfe;
 	uint32_t blnd;
 	uint32_t crtc;
 };
@@ -66,30 +66,23 @@  enum blender_mode {
 
 static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
 {
-	.dcfe = (mmDCFE0_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND0_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE1_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND1_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE2_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND2_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFEV_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLNDV_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 }
 };
 
-#define HW_REG_DCFE(reg, id)\
-	(reg + reg_offsets[id].dcfe)
-
 #define HW_REG_BLND(reg, id)\
 	(reg + reg_offsets[id].blnd)
 
@@ -103,25 +96,6 @@  static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
  * Private definitions
  ******************************************************************************/
 /***************************PIPE_CONTROL***********************************/
-static void dce110_enable_fe_clock(
-	struct dc_context *ctx, uint8_t controller_id, bool enable)
-{
-	uint32_t value = 0;
-	uint32_t addr;
-
-	addr = HW_REG_DCFE(mmDCFE_CLOCK_CONTROL, controller_id);
-
-	value = dm_read_reg(ctx, addr);
-
-	set_reg_field_value(
-		value,
-		enable,
-		DCFE_CLOCK_CONTROL,
-		DCFE_CLOCK_ENABLE);
-
-	dm_write_reg(ctx, addr, value);
-}
-
 static void dce110_init_pte(struct dc_context *ctx)
 {
 	uint32_t addr;
@@ -1616,7 +1590,7 @@  static void set_plane_config(
 	memset(&tbl_entry, 0, sizeof(tbl_entry));
 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
 
-	dc->hwss.enable_fe_clock(ctx, pipe_ctx->pipe_idx, true);
+	dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
 
 	set_default_colors(pipe_ctx);
 	if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment
@@ -1958,7 +1932,7 @@  static void dce110_program_front_end_for_pipe(
 	memset(&adjust, 0, sizeof(adjust));
 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
 
-	dc->hwss.enable_fe_clock(ctx, pipe_ctx->pipe_idx, true);
+	dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
 
 	set_default_colors(pipe_ctx);
 	if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment
@@ -2160,7 +2134,6 @@  static const struct hw_sequencer_funcs dce110_funcs = {
 	.crtc_switch_to_clk_src = dce110_crtc_switch_to_clk_src,
 	.enable_display_power_gating = dce110_enable_display_power_gating,
 	.power_down_front_end = dce110_power_down_fe,
-	.enable_fe_clock = dce110_enable_fe_clock,
 	.pipe_control_lock = dce110_pipe_control_lock,
 	.set_blender_mode = dce110_set_blender_mode,
 	.clock_gating_power_up = dal_dc_clock_gating_dce110_power_up,
diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
index cac8a19f28ed..e0e3178b9134 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
@@ -46,6 +46,7 @@ 
 #include "dce110/dce110_opp.h"
 #include "dce110/dce110_opp_v.h"
 #include "dce110/dce110_clock_source.h"
+#include "dce/dce_hwseq.h"
 #include "dce110/dce110_hw_sequencer.h"
 
 #include "reg_helper.h"
@@ -421,10 +422,40 @@  static struct stream_encoder *dce110_stream_encoder_create(
 	return NULL;
 }
 
+#define SRII(reg_name, block, id)\
+	.reg_name[id] = mm ## block ## id ## _ ## reg_name
+
+static const struct dce_hwseq_registers hwseq_reg = {
+		HWSEQ_COMMON_REG_LIST_BASE()
+};
+
+static const struct dce_hwseq_shift hwseq_shift = {
+		HWSEQ_COMMON_MASK_SH_LIST_BASE(__SHIFT)
+};
+
+static const struct dce_hwseq_mask hwseq_mask = {
+		HWSEQ_COMMON_MASK_SH_LIST_BASE(_MASK)
+};
+
+static struct dce_hwseq *dce110_hwseq_create(
+	struct dc_context *ctx)
+{
+	struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
+
+	if (hws) {
+		hws->ctx = ctx;
+		hws->regs = &hwseq_reg;
+		hws->shifts = &hwseq_shift;
+		hws->masks = &hwseq_mask;
+	}
+	return hws;
+}
+
 static const struct resource_create_funcs res_create_funcs = {
 	.read_dce_straps = read_dce_straps,
 	.create_audio = create_audio,
-	.create_stream_encoder = dce110_stream_encoder_create
+	.create_stream_encoder = dce110_stream_encoder_create,
+	.create_hwseq = dce110_hwseq_create,
 };
 
 
diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c
index f5611d14dbc9..f8c2cfb64b11 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c
@@ -29,6 +29,7 @@ 
 #include "core_types.h"
 #include "dce112_hw_sequencer.h"
 
+#include "dce/dce_hwseq.h"
 #include "dce110/dce110_hw_sequencer.h"
 #include "gpu/dce112/dc_clock_gating_dce112.h"
 
@@ -37,7 +38,6 @@ 
 #include "dce/dce_11_2_sh_mask.h"
 
 struct dce112_hw_seq_reg_offsets {
-	uint32_t dcfe;
 	uint32_t blnd;
 	uint32_t crtc;
 };
@@ -51,40 +51,31 @@  enum blender_mode {
 
 static const struct dce112_hw_seq_reg_offsets reg_offsets[] = {
 {
-	.dcfe = (mmDCFE0_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND0_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE1_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND1_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE2_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND2_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE3_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND3_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE4_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND4_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 },
 {
-	.dcfe = (mmDCFE5_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL),
 	.blnd = (mmBLND5_BLND_CONTROL - mmBLND_CONTROL),
 	.crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 }
 };
 
-#define HW_REG_DCFE(reg, id)\
-	(reg + reg_offsets[id].dcfe)
-
 #define HW_REG_BLND(reg, id)\
 	(reg + reg_offsets[id].blnd)
 
@@ -95,24 +86,6 @@  static const struct dce112_hw_seq_reg_offsets reg_offsets[] = {
  * Private definitions
  ******************************************************************************/
 /***************************PIPE_CONTROL***********************************/
-static void dce112_enable_fe_clock(
-	struct dc_context *ctx, uint8_t controller_id, bool enable)
-{
-	uint32_t value = 0;
-	uint32_t addr;
-
-	addr = HW_REG_DCFE(mmDCFE_CLOCK_CONTROL, controller_id);
-
-	value = dm_read_reg(ctx, addr);
-
-	set_reg_field_value(
-		value,
-		enable,
-		DCFE_CLOCK_CONTROL,
-		DCFE_CLOCK_ENABLE);
-
-	dm_write_reg(ctx, addr, value);
-}
 
 static bool dce112_pipe_control_lock(
 	struct dc_context *ctx,
@@ -350,7 +323,6 @@  bool dce112_hw_sequencer_construct(struct core_dc *dc)
 	dc->hwss.clock_gating_power_up = dal_dc_clock_gating_dce112_power_up;
 	dc->hwss.pipe_control_lock = dce112_pipe_control_lock;
 	dc->hwss.set_blender_mode = dce112_set_blender_mode;
-	dc->hwss.enable_fe_clock = dce112_enable_fe_clock;
 
 	return true;
 }
diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c
index 9f47bec557ea..01534872d3b8 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c
@@ -44,6 +44,7 @@ 
 #include "dce110/dce110_ipp.h"
 #include "dce112/dce112_clock_source.h"
 
+#include "dce/dce_hwseq.h"
 #include "dce112/dce112_hw_sequencer.h"
 
 #include "reg_helper.h"
@@ -471,10 +472,40 @@  static struct stream_encoder *dce112_stream_encoder_create(
 	return NULL;
 }
 
+#define SRII(reg_name, block, id)\
+	.reg_name[id] = mm ## block ## id ## _ ## reg_name
+
+static const struct dce_hwseq_registers hwseq_reg = {
+		HWSEQ_COMMON_REG_LIST_BASE()
+};
+
+static const struct dce_hwseq_shift hwseq_shift = {
+		HWSEQ_COMMON_MASK_SH_LIST_BASE(__SHIFT)
+};
+
+static const struct dce_hwseq_mask hwseq_mask = {
+		HWSEQ_COMMON_MASK_SH_LIST_BASE(_MASK)
+};
+
+static struct dce_hwseq *dce112_hwseq_create(
+	struct dc_context *ctx)
+{
+	struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
+
+	if (hws) {
+		hws->ctx = ctx;
+		hws->regs = &hwseq_reg;
+		hws->shifts = &hwseq_shift;
+		hws->masks = &hwseq_mask;
+	}
+	return hws;
+}
+
 static const struct resource_create_funcs res_create_funcs = {
 	.read_dce_straps = read_dce_straps,
 	.create_audio = create_audio,
-	.create_stream_encoder = dce112_stream_encoder_create
+	.create_stream_encoder = dce112_stream_encoder_create,
+	.create_hwseq = dce112_hwseq_create,
 };
 
 static struct mem_input *dce112_mem_input_create(
diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c
index 2841e3b7cb71..d52513ba46a8 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c
@@ -29,6 +29,7 @@ 
 #include "core_types.h"
 #include "dce80_hw_sequencer.h"
 
+#include "dce/dce_hwseq.h"
 #include "dce110/dce110_hw_sequencer.h"
 
 #include "gpu/dce80/dc_clock_gating_dce80.h"
@@ -87,24 +88,6 @@  static const struct dce80_hw_seq_reg_offsets reg_offsets[] = {
  ******************************************************************************/
 
 /***************************PIPE_CONTROL***********************************/
-static void dce80_enable_fe_clock(
-	struct dc_context *ctx, uint8_t controller_id, bool enable)
-{
-	uint32_t value = 0;
-	uint32_t addr;
-
-	addr = HW_REG_CRTC(mmCRTC_DCFE_CLOCK_CONTROL, controller_id);
-
-	value = dm_read_reg(ctx, addr);
-
-	set_reg_field_value(
-		value,
-		enable,
-		CRTC_DCFE_CLOCK_CONTROL,
-		CRTC_DCFE_CLOCK_ENABLE);
-
-	dm_write_reg(ctx, addr, value);
-}
 
 static bool dce80_pipe_control_lock(
 	struct dc_context *ctx,
@@ -241,7 +224,6 @@  bool dce80_hw_sequencer_construct(struct core_dc *dc)
 	dce110_hw_sequencer_construct(dc);
 
 	dc->hwss.clock_gating_power_up = dal_dc_clock_gating_dce80_power_up;
-	dc->hwss.enable_fe_clock = dce80_enable_fe_clock;
 	dc->hwss.enable_display_power_gating = dce80_enable_display_power_gating;
 	dc->hwss.pipe_control_lock = dce80_pipe_control_lock;
 	dc->hwss.set_blender_mode = dce80_set_blender_mode;
diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
index 7bf277e7bada..100c8c01aa21 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
@@ -46,6 +46,7 @@ 
 #include "dce110/dce110_ipp.h"
 #include "dce110/dce110_clock_source.h"
 #include "dce/dce_audio.h"
+#include "dce/dce_hwseq.h"
 #include "dce80/dce80_hw_sequencer.h"
 
 #include "reg_helper.h"
@@ -437,10 +438,40 @@  static struct stream_encoder *dce80_stream_encoder_create(
 	return NULL;
 }
 
+#define SRII(reg_name, block, id)\
+	.reg_name[id] = mm ## block ## id ## _ ## reg_name
+
+static const struct dce_hwseq_registers hwseq_reg = {
+		HWSEQ_DCE8_REG_LIST_BASE()
+};
+
+static const struct dce_hwseq_shift hwseq_shift = {
+		HWSEQ_DCE8_MASK_SH_LIST_BASE(__SHIFT)
+};
+
+static const struct dce_hwseq_mask hwseq_mask = {
+		HWSEQ_DCE8_MASK_SH_LIST_BASE(_MASK)
+};
+
+static struct dce_hwseq *dce80_hwseq_create(
+	struct dc_context *ctx)
+{
+	struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
+
+	if (hws) {
+		hws->ctx = ctx;
+		hws->regs = &hwseq_reg;
+		hws->shifts = &hwseq_shift;
+		hws->masks = &hwseq_mask;
+	}
+	return hws;
+}
+
 static const struct resource_create_funcs res_create_funcs = {
 	.read_dce_straps = read_dce_straps,
 	.create_audio = create_audio,
-	.create_stream_encoder = dce80_stream_encoder_create
+	.create_stream_encoder = dce80_stream_encoder_create,
+	.create_hwseq = dce80_hwseq_create,
 };
 
 static struct mem_input *dce80_mem_input_create(
diff --git a/drivers/gpu/drm/amd/dal/dc/dm_services.h b/drivers/gpu/drm/amd/dal/dc/dm_services.h
index 016df3468a12..6385ed48ad36 100644
--- a/drivers/gpu/drm/amd/dal/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/dal/dc/dm_services.h
@@ -38,6 +38,44 @@ 
 
 #undef DEPRECATED
 
+/*
+ *
+ * general debug capabilities
+ *
+ */
+#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
+
+#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
+#define ASSERT_CRITICAL(expr) do {	\
+	if (WARN_ON(!(expr))) { \
+		kgdb_breakpoint(); \
+	} \
+} while (0)
+#else
+#define ASSERT_CRITICAL(expr) do {	\
+	if (WARN_ON(!(expr))) { \
+		; \
+	} \
+} while (0)
+#endif
+
+#if defined(CONFIG_DEBUG_KERNEL_DAL)
+#define ASSERT(expr) ASSERT_CRITICAL(expr)
+
+#else
+#define ASSERT(expr) WARN_ON(!(expr))
+#endif
+
+#define BREAK_TO_DEBUGGER() ASSERT(0)
+
+#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
+
+
+#define DC_ERR(err_msg)  do { \
+	BREAK_TO_DEBUGGER(); \
+	dm_error(err_msg); \
+} while (0)
+
 #define dm_alloc(size) kzalloc(size, GFP_KERNEL)
 #define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
 #define dm_free(ptr) kfree(ptr)
@@ -63,7 +101,14 @@  static inline uint32_t dm_read_reg_func(
 	uint32_t address,
 	const char *func_name)
 {
-	uint32_t value = cgs_read_register(ctx->cgs_device, address);
+	uint32_t value;
+
+	if (address == 0) {
+		DC_ERR("invalid register read. address = 0");
+		return 0;
+	}
+
+	value = cgs_read_register(ctx->cgs_device, address);
 
 #if defined(__DAL_REGISTER_LOGGER__)
 	if (true == dal_reg_logger_should_dump_register()) {
@@ -89,6 +134,11 @@  static inline void dm_write_reg_func(
 		DRM_INFO("%s DC_WRITE_REG: 0x%x 0x%x\n", func_name, address, value);
 	}
 #endif
+
+	if (address == 0) {
+		DC_ERR("invalid register write. address = 0");
+		return;
+	}
 	cgs_write_register(ctx->cgs_device, address, value);
 }
 
@@ -370,42 +420,4 @@  bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
 long dm_get_pid(void);
 long dm_get_tgid(void);
 
-/*
- *
- * general debug capabilities
- *
- */
-#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
-
-#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
-#define ASSERT_CRITICAL(expr) do {	\
-	if (WARN_ON(!(expr))) { \
-		kgdb_breakpoint(); \
-	} \
-} while (0)
-#else
-#define ASSERT_CRITICAL(expr) do {	\
-	if (WARN_ON(!(expr))) { \
-		; \
-	} \
-} while (0)
-#endif
-
-#if defined(CONFIG_DEBUG_KERNEL_DAL)
-#define ASSERT(expr) ASSERT_CRITICAL(expr)
-
-#else
-#define ASSERT(expr) WARN_ON(!(expr))
-#endif
-
-#define BREAK_TO_DEBUGGER() ASSERT(0)
-
-#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
-
-
-#define DC_ERR(err_msg)  do { \
-	BREAK_TO_DEBUGGER(); \
-	dm_error(err_msg); \
-} while (0)
-
 #endif /* __DM_SERVICES_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h b/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h
index 826ae7a8998f..7d6dc8ea75ab 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h
@@ -39,6 +39,7 @@  struct core_dc {
 
 	/* HW functions */
 	struct hw_sequencer_funcs hwss;
+	struct dce_hwseq *hwseq;
 
 	/* temp store of dm_pp_display_configuration
 	 * to compare to see if display config changed
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h
index 6435247a41e8..7091dc731d09 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h
@@ -121,9 +121,6 @@  struct hw_sequencer_funcs {
 	void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
 			struct dc_link_settings *link_settings);
 
-	void (*enable_fe_clock)(
-		struct dc_context *ctx, uint8_t controller_id, bool enable);
-
 	bool (*pipe_control_lock)(
 				struct dc_context *ctx,
 				uint8_t controller_idx,
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/resource.h b/drivers/gpu/drm/amd/dal/dc/inc/resource.h
index 9606cb28cd62..33fb7d98b294 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/resource.h
@@ -52,15 +52,16 @@  struct resource_straps {
 
 struct resource_create_funcs {
 	void (*read_dce_straps)(
-		struct dc_context *ctx, struct resource_straps *straps);
+			struct dc_context *ctx, struct resource_straps *straps);
 
 	struct audio *(*create_audio)(
 			struct dc_context *ctx, unsigned int inst);
 
 	struct stream_encoder *(*create_stream_encoder)(
-			enum engine_id eng_id,
-			struct dc_context *ctx);
+			enum engine_id eng_id, struct dc_context *ctx);
 
+	struct dce_hwseq *(*create_hwseq)(
+			struct dc_context *ctx);
 };
 
 bool resource_construct(