[24/39] drm/amd/dal: consolidate mem_input

Submitted by Harry Wentland on Nov. 24, 2016, 2:02 a.m.

Details

Message ID 20161124020308.28124-25-harry.wentland@amd.com
State New
Headers show
Series "dal patches for nov 23, 2016" ( rev: 1 ) in AMD X.Org drivers

Commit Message

Harry Wentland Nov. 24, 2016, 2:02 a.m.
From: Tony Cheng <tony.cheng@amd.com>

- dce_mem_input_allocate_dmif
- dce_mem_input_free_dmif
- mem_input_program_display_marks (DCE11.2)

- also fix MC_HUB_RDREQ_DMIF_LIMIT wa is different in different DCE

- also add more robust error checking in new programming model
-- more asserts

Change-Id: Iea64d3c771375ff3d09ea4e7d15be4c63fe0ca32
Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
---
 drivers/gpu/drm/amd/dal/dc/dc_helper.c             |   6 +-
 drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c     | 191 ++++++++++
 drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h     |  91 ++++-
 .../gpu/drm/amd/dal/dc/dce100/dce100_resource.c    |  16 +-
 .../gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c   | 205 +----------
 .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c    |  17 +-
 .../gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c   | 384 +--------------------
 drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c | 126 +------
 drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c  |  17 +-
 drivers/gpu/drm/amd/dal/dc/dm_services.h           |   8 +-
 drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h      |   1 +
 drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h        |   2 +-
 12 files changed, 334 insertions(+), 730 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/dal/dc/dc_helper.c b/drivers/gpu/drm/amd/dal/dc/dc_helper.c
index 96724ba17e4b..22b72f0bcbbc 100644
--- a/drivers/gpu/drm/amd/dal/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/dal/dc/dc_helper.c
@@ -114,7 +114,8 @@  uint32_t generic_reg_get(const struct dc_context *ctx,
 
 uint32_t generic_reg_wait(const struct dc_context *ctx,
 	uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value,
-	unsigned int delay_between_poll_us, unsigned int time_out_num_tries)
+	unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
+	const char *func_name)
 {
 	uint32_t field_value;
 	uint32_t reg_val;
@@ -137,6 +138,7 @@  uint32_t generic_reg_wait(const struct dc_context *ctx,
 			return reg_val;
 	}
 
-	BREAK_TO_DEBUGGER();
+	DC_ERR("REG_WAIT timeout %dus * %d tries - ",
+			delay_between_poll_us, time_out_num_tries, func_name);
 	return reg_val;
 }
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c
index 1b4a5b9bb8b6..654731cccdcd 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c
@@ -36,6 +36,78 @@ 
 	mi->shifts->field_name, mi->masks->field_name
 
 
+static void program_urgency_watermark(struct mem_input *mi,
+	uint32_t wm_select,
+	uint32_t urgency_low_wm,
+	uint32_t urgency_high_wm)
+{
+	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
+		URGENCY_WATERMARK_MASK, wm_select);
+
+	REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
+		URGENCY_LOW_WATERMARK, urgency_low_wm,
+		URGENCY_HIGH_WATERMARK, urgency_high_wm);
+}
+
+static void program_nbp_watermark(struct mem_input *mi,
+	uint32_t wm_select,
+	uint32_t nbp_wm)
+{
+	if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
+		REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
+				NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
+
+		REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
+				NB_PSTATE_CHANGE_ENABLE, 1,
+				NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
+				NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
+
+		REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
+				NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
+	}
+}
+
+static void program_stutter_watermark(struct mem_input *mi,
+	uint32_t wm_select,
+	uint32_t stutter_mark)
+{
+	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
+		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
+
+		REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
+				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
+}
+
+void dce_mem_input_program_display_marks(struct mem_input *mi,
+	struct bw_watermarks nbp,
+	struct bw_watermarks stutter,
+	struct bw_watermarks urgent,
+	uint32_t total_dest_line_time_ns)
+{
+	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
+
+	program_urgency_watermark(mi, 0, /* set a */
+			urgent.a_mark, total_dest_line_time_ns);
+	program_urgency_watermark(mi, 1, /* set b */
+			urgent.b_mark, total_dest_line_time_ns);
+	program_urgency_watermark(mi, 2, /* set c */
+			urgent.c_mark, total_dest_line_time_ns);
+	program_urgency_watermark(mi, 3, /* set d */
+			urgent.d_mark, total_dest_line_time_ns);
+
+	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
+		STUTTER_ENABLE, stutter_en,
+		STUTTER_IGNORE_FBC, 1);
+	program_nbp_watermark(mi, 0, nbp.a_mark); /* set a */
+	program_nbp_watermark(mi, 1, nbp.b_mark); /* set b */
+	program_nbp_watermark(mi, 2, nbp.c_mark); /* set c */
+	program_nbp_watermark(mi, 3, nbp.d_mark); /* set d */
+
+	program_stutter_watermark(mi, 0, stutter.a_mark); /* set a */
+	program_stutter_watermark(mi, 1, stutter.b_mark); /* set b */
+	program_stutter_watermark(mi, 2, stutter.c_mark); /* set c */
+	program_stutter_watermark(mi, 3, stutter.d_mark); /* set d */
+}
 
 static void program_tiling(struct mem_input *mi,
 	const union dc_tiling_info *info)
@@ -191,3 +263,122 @@  bool dce_mem_input_program_surface_config(struct mem_input *mi,
 
 	return true;
 }
+
+static uint32_t get_dmif_switch_time_us(
+	uint32_t h_total,
+	uint32_t v_total,
+	uint32_t pix_clk_khz)
+{
+	uint32_t frame_time;
+	uint32_t pixels_per_second;
+	uint32_t pixels_per_frame;
+	uint32_t refresh_rate;
+	const uint32_t us_in_sec = 1000000;
+	const uint32_t min_single_frame_time_us = 30000;
+	/*return double of frame time*/
+	const uint32_t single_frame_time_multiplier = 2;
+
+	if (!h_total || v_total || !pix_clk_khz)
+		return single_frame_time_multiplier * min_single_frame_time_us;
+
+	/*TODO: should we use pixel format normalized pixel clock here?*/
+	pixels_per_second = pix_clk_khz * 1000;
+	pixels_per_frame = h_total * v_total;
+
+	if (!pixels_per_second || !pixels_per_frame) {
+		/* avoid division by zero */
+		ASSERT(pixels_per_frame);
+		ASSERT(pixels_per_second);
+		return single_frame_time_multiplier * min_single_frame_time_us;
+	}
+
+	refresh_rate = pixels_per_second / pixels_per_frame;
+
+	if (!refresh_rate) {
+		/* avoid division by zero*/
+		ASSERT(refresh_rate);
+		return single_frame_time_multiplier * min_single_frame_time_us;
+	}
+
+	frame_time = us_in_sec / refresh_rate;
+
+	if (frame_time < min_single_frame_time_us)
+		frame_time = min_single_frame_time_us;
+
+	frame_time *= single_frame_time_multiplier;
+
+	return frame_time;
+}
+
+void dce_mem_input_allocate_dmif(struct mem_input *mi,
+	uint32_t h_total,
+	uint32_t v_total,
+	uint32_t pix_clk_khz,
+	uint32_t total_stream_num)
+{
+	const uint32_t retry_delay = 10;
+	uint32_t retry_count = get_dmif_switch_time_us(
+			h_total,
+			v_total,
+			pix_clk_khz) / retry_delay;
+
+	uint32_t pix_dur;
+	uint32_t buffers_allocated;
+	uint32_t dmif_buffer_control;
+
+	dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
+			DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
+
+	if (buffers_allocated == 2)
+		return;
+
+	REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
+			DMIF_BUFFERS_ALLOCATED, 2);
+
+	REG_WAIT(DMIF_BUFFER_CONTROL,
+			DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
+			retry_delay, retry_count);
+
+	if (pix_clk_khz != 0) {
+		pix_dur = 1000000000ULL / pix_clk_khz;
+
+		REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
+			PIXEL_DURATION, pix_dur);
+	}
+
+	if (mi->wa.single_head_rdreq_dmif_limit) {
+		uint32_t eanble =  (total_stream_num > 1) ? 0 :
+				mi->wa.single_head_rdreq_dmif_limit;
+
+		REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
+				ENABLE, eanble);
+	}
+}
+
+void dce_mem_input_free_dmif(struct mem_input *mi,
+		uint32_t total_stream_num)
+{
+	uint32_t buffers_allocated;
+	uint32_t dmif_buffer_control;
+
+	dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
+			DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
+
+	if (buffers_allocated == 0)
+		return;
+
+	REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
+			DMIF_BUFFERS_ALLOCATED, 0);
+
+	REG_WAIT(DMIF_BUFFER_CONTROL,
+			DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
+			10, 0xBB8);
+
+	if (mi->wa.single_head_rdreq_dmif_limit) {
+		uint32_t eanble =  (total_stream_num > 1) ? 0 :
+				mi->wa.single_head_rdreq_dmif_limit;
+
+		REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
+				ENABLE, eanble);
+	}
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h
index 96c7736e223b..d5930a925fcb 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h
+++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h
@@ -25,7 +25,7 @@ 
 #ifndef __DCE_MEM_INPUT_H__
 #define __DCE_MEM_INPUT_H__
 
-#define MI_REG_LIST(id)\
+#define MI_DCE_BASE_REG_LIST(id)\
 	SRI(GRPH_ENABLE, DCP, id),\
 	SRI(GRPH_CONTROL, DCP, id),\
 	SRI(GRPH_X_START, DCP, id),\
@@ -35,9 +35,19 @@ 
 	SRI(GRPH_PITCH, DCP, id),\
 	SRI(HW_ROTATION, DCP, id),\
 	SRI(GRPH_SWAP_CNTL, DCP, id),\
-	SRI(PRESCALE_GRPH_CONTROL, DCP, id)
+	SRI(PRESCALE_GRPH_CONTROL, DCP, id),\
+	SRI(DPG_PIPE_ARBITRATION_CONTROL1, DMIF_PG, id),\
+	SRI(DPG_WATERMARK_MASK_CONTROL, DMIF_PG, id),\
+	SRI(DPG_PIPE_URGENCY_CONTROL, DMIF_PG, id),\
+	SRI(DPG_PIPE_STUTTER_CONTROL, DMIF_PG, id),\
+	SRI(DMIF_BUFFER_CONTROL, PIPE, id)
+
+#define MI_REG_LIST(id)\
+	MI_DCE_BASE_REG_LIST(id),\
+	SRI(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, DMIF_PG, id)
 
 struct dce_mem_input_registers {
+	/* DCP */
 	uint32_t GRPH_ENABLE;
 	uint32_t GRPH_CONTROL;
 	uint32_t GRPH_X_START;
@@ -48,6 +58,18 @@  struct dce_mem_input_registers {
 	uint32_t HW_ROTATION;
 	uint32_t GRPH_SWAP_CNTL;
 	uint32_t PRESCALE_GRPH_CONTROL;
+	/* DMIF_PG */
+	uint32_t DPG_PIPE_ARBITRATION_CONTROL1;
+	uint32_t DPG_WATERMARK_MASK_CONTROL;
+	uint32_t DPG_PIPE_URGENCY_CONTROL;
+	uint32_t DPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
+	uint32_t DPG_PIPE_LOW_POWER_CONTROL;
+	uint32_t DPG_PIPE_STUTTER_CONTROL;
+	uint32_t DPG_PIPE_STUTTER_CONTROL2;
+	/* DCI */
+	uint32_t DMIF_BUFFER_CONTROL;
+	/* MC_HUB */
+	uint32_t MC_HUB_RDREQ_DMIF_LIMIT;
 };
 
 /* Set_Filed_for_Block */
@@ -81,9 +103,30 @@  struct dce_mem_input_registers {
 	SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_G_SIGN, mask_sh),\
 	SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_B_SIGN, mask_sh)
 
+#define MI_DMIF_PG_MASK_SH_LIST(mask_sh, blk)\
+	SFB(blk, DPG_PIPE_ARBITRATION_CONTROL1, PIXEL_DURATION, mask_sh),\
+	SFB(blk, DPG_WATERMARK_MASK_CONTROL, URGENCY_WATERMARK_MASK, mask_sh),\
+	SFB(blk, DPG_WATERMARK_MASK_CONTROL, STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, mask_sh),\
+	SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_LOW_WATERMARK, mask_sh),\
+	SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_HIGH_WATERMARK, mask_sh),\
+	SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE, mask_sh),\
+	SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_IGNORE_FBC, mask_sh),\
+	SF(PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED, mask_sh),\
+	SF(PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATION_COMPLETED, mask_sh)
+
+#define MI_DMIF_PG_MASK_SH_DCE(mask_sh, blk)\
+	SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_EXIT_SELF_REFRESH_WATERMARK, mask_sh),\
+	SFB(blk, DPG_WATERMARK_MASK_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\
+	SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_ENABLE, mask_sh),\
+	SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, mask_sh),\
+	SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, mask_sh),\
+	SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_WATERMARK, mask_sh)
+
 #define MI_DCE_MASK_SH_LIST(mask_sh)\
-		MI_DCP_MASK_SH_LIST(mask_sh, ),\
-		MI_GFX8_TILE_MASK_SH_LIST(mask_sh, )
+	MI_DCP_MASK_SH_LIST(mask_sh,),\
+	MI_DMIF_PG_MASK_SH_LIST(mask_sh,),\
+	MI_DMIF_PG_MASK_SH_DCE(mask_sh,),\
+	MI_GFX8_TILE_MASK_SH_LIST(mask_sh,)
 
 #define MI_REG_FIELD_LIST(type) \
 	type GRPH_ENABLE; \
@@ -113,6 +156,27 @@  struct dce_mem_input_registers {
 	type GRPH_SW_MODE; \
 	type GRPH_NUM_SHADER_ENGINES; \
 	type GRPH_NUM_PIPES; \
+	type PIXEL_DURATION; \
+	type URGENCY_WATERMARK_MASK; \
+	type PSTATE_CHANGE_WATERMARK_MASK; \
+	type NB_PSTATE_CHANGE_WATERMARK_MASK; \
+	type STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK; \
+	type URGENCY_LOW_WATERMARK; \
+	type URGENCY_HIGH_WATERMARK; \
+	type NB_PSTATE_CHANGE_ENABLE; \
+	type NB_PSTATE_CHANGE_URGENT_DURING_REQUEST; \
+	type NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
+	type NB_PSTATE_CHANGE_WATERMARK; \
+	type PSTATE_CHANGE_ENABLE; \
+	type PSTATE_CHANGE_URGENT_DURING_REQUEST; \
+	type PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
+	type PSTATE_CHANGE_WATERMARK; \
+	type STUTTER_ENABLE; \
+	type STUTTER_IGNORE_FBC; \
+	type STUTTER_EXIT_SELF_REFRESH_WATERMARK; \
+	type DMIF_BUFFERS_ALLOCATED; \
+	type DMIF_BUFFERS_ALLOCATION_COMPLETED; \
+	type ENABLE; /* MC_HUB_RDREQ_DMIF_LIMIT */\
 
 struct dce_mem_input_shift {
 	MI_REG_FIELD_LIST(uint8_t)
@@ -122,6 +186,10 @@  struct dce_mem_input_mask {
 	MI_REG_FIELD_LIST(uint32_t)
 };
 
+struct dce_mem_input_wa {
+	uint8_t single_head_rdreq_dmif_limit;
+};
+
 struct mem_input;
 bool dce_mem_input_program_surface_config(struct mem_input *mi,
 	enum surface_pixel_format format,
@@ -131,4 +199,19 @@  bool dce_mem_input_program_surface_config(struct mem_input *mi,
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror);
 
+void dce_mem_input_allocate_dmif(struct mem_input *mi,
+	uint32_t h_total,
+	uint32_t v_total,
+	uint32_t pix_clk_khz,
+	uint32_t total_stream_num);
+
+void dce_mem_input_free_dmif(struct mem_input *mi,
+	uint32_t total_stream_num);
+
+void dce_mem_input_program_display_marks(struct mem_input *mi,
+	struct bw_watermarks nbp,
+	struct bw_watermarks stutter,
+	struct bw_watermarks urgent,
+	uint32_t total_dest_line_time_ns);
+
 #endif /*__DCE_MEM_INPUT_H__*/
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 6c17a52df574..851247c647a1 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
@@ -51,6 +51,10 @@ 
 #include "dce/dce_10_0_d.h"
 #include "dce/dce_10_0_sh_mask.h"
 
+#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
+#include "gmc/gmc_8_2_d.h"
+#include "gmc/gmc_8_2_sh_mask.h"
+#endif
 
 #ifndef mmDP_DPHY_INTERNAL_CTRL
 	#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
@@ -471,7 +475,10 @@  static const struct resource_create_funcs res_create_funcs = {
 	.create_hwseq = dce100_hwseq_create,
 };
 
-#define mi_inst_regs(id) { MI_REG_LIST(id) }
+#define mi_inst_regs(id) { \
+	MI_REG_LIST(id), \
+	.MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
+}
 static const struct dce_mem_input_registers mi_regs[] = {
 		mi_inst_regs(0),
 		mi_inst_regs(1),
@@ -482,11 +489,13 @@  static const struct dce_mem_input_registers mi_regs[] = {
 };
 
 static const struct dce_mem_input_shift mi_shifts = {
-		MI_DCE_MASK_SH_LIST(__SHIFT)
+		MI_DCE_MASK_SH_LIST(__SHIFT),
+		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 };
 
 static const struct dce_mem_input_mask mi_masks = {
-		MI_DCE_MASK_SH_LIST(_MASK)
+		MI_DCE_MASK_SH_LIST(_MASK),
+		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 };
 
 static struct mem_input *dce100_mem_input_create(
@@ -506,6 +515,7 @@  static struct mem_input *dce100_mem_input_create(
 		mi->regs = &mi_regs[inst];
 		mi->shifts = &mi_shifts;
 		mi->masks = &mi_masks;
+		mi->wa.single_head_rdreq_dmif_limit = 2;
 		return mi;
 	}
 
diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
index 4092abe3812d..c0a68c6f585e 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
@@ -494,212 +494,11 @@  void dce110_mem_input_program_display_marks(
 		stutter);
 }
 
-static uint32_t get_dmif_switch_time_us(
-	uint32_t h_total,
-	uint32_t v_total,
-	uint32_t pix_clk_khz)
-{
-	uint32_t frame_time;
-	uint32_t pixels_per_second;
-	uint32_t pixels_per_frame;
-	uint32_t refresh_rate;
-	const uint32_t us_in_sec = 1000000;
-	const uint32_t min_single_frame_time_us = 30000;
-	/*return double of frame time*/
-	const uint32_t single_frame_time_multiplier = 2;
-
-	if (!h_total || v_total || !pix_clk_khz)
-		return single_frame_time_multiplier * min_single_frame_time_us;
-
-	/*TODO: should we use pixel format normalized pixel clock here?*/
-	pixels_per_second = pix_clk_khz * 1000;
-	pixels_per_frame = h_total * v_total;
-
-	if (!pixels_per_second || !pixels_per_frame) {
-		/* avoid division by zero */
-		ASSERT(pixels_per_frame);
-		ASSERT(pixels_per_second);
-		return single_frame_time_multiplier * min_single_frame_time_us;
-	}
-
-	refresh_rate = pixels_per_second / pixels_per_frame;
-
-	if (!refresh_rate) {
-		/* avoid division by zero*/
-		ASSERT(refresh_rate);
-		return single_frame_time_multiplier * min_single_frame_time_us;
-	}
-
-	frame_time = us_in_sec / refresh_rate;
-
-	if (frame_time < min_single_frame_time_us)
-		frame_time = min_single_frame_time_us;
-
-	frame_time *= single_frame_time_multiplier;
-
-	return frame_time;
-}
-
-void dce110_allocate_mem_input(
-	struct mem_input *mi,
-	uint32_t h_total,/* for current stream */
-	uint32_t v_total,/* for current stream */
-	uint32_t pix_clk_khz,/* for current stream */
-	uint32_t total_stream_num)
-{
-	const uint32_t retry_delay = 10;
-	uint32_t retry_count = get_dmif_switch_time_us(
-			h_total,
-			v_total,
-			pix_clk_khz) / retry_delay;
-
-	struct dce110_mem_input *bm110 = TO_DCE110_MEM_INPUT(mi);
-	uint32_t addr = bm110->offsets.pipe + mmPIPE0_DMIF_BUFFER_CONTROL;
-	uint32_t value;
-	uint32_t field;
-	uint32_t pix_dur;
-
-	/*Allocate DMIF buffer*/
-	value = dm_read_reg(mi->ctx, addr);
-	field = get_reg_field_value(
-		value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
-	if (field == 2)
-		goto register_underflow_int;
-
-	set_reg_field_value(
-			value,
-			2,
-			PIPE0_DMIF_BUFFER_CONTROL,
-			DMIF_BUFFERS_ALLOCATED);
-
-	dm_write_reg(mi->ctx, addr, value);
-
-	do {
-		value = dm_read_reg(mi->ctx, addr);
-		field = get_reg_field_value(
-			value,
-			PIPE0_DMIF_BUFFER_CONTROL,
-			DMIF_BUFFERS_ALLOCATION_COMPLETED);
-
-		if (field)
-			break;
-
-		udelay(retry_delay);
-		retry_count--;
-
-	} while (retry_count > 0);
-
-	if (field == 0)
-		dm_logger_write(mi->ctx->logger, LOG_ERROR,
-				"%s: DMIF allocation failed",
-				__func__);
-
-	if (pix_clk_khz != 0) {
-		addr = mmDPG_PIPE_ARBITRATION_CONTROL1 + bm110->offsets.dmif;
-		value = dm_read_reg(mi->ctx, addr);
-		pix_dur = 1000000000ULL / pix_clk_khz;
-
-		set_reg_field_value(
-			value,
-			pix_dur,
-			DPG_PIPE_ARBITRATION_CONTROL1,
-			PIXEL_DURATION);
-
-		dm_write_reg(mi->ctx, addr, value);
-	}
-
-	/*
-	 * Stella Wong proposed the following change
-	 *
-	 * Value of mcHubRdReqDmifLimit.ENABLE:
-	 * 00 - disable DMIF rdreq limit
-	 * 01 - enable DMIF rdreq limit, disabled by DMIF stall = 1 || urg != 0
-	 * 02 - enable DMIF rdreq limit, disable by DMIF stall = 1
-	 * 03 - force enable DMIF rdreq limit, ignore DMIF stall / urgent
-	 */
-	if (!IS_FPGA_MAXIMUS_DC(mi->ctx->dce_environment)) {
-		addr = mmMC_HUB_RDREQ_DMIF_LIMIT;
-		value = dm_read_reg(mi->ctx, addr);
-
-		if (total_stream_num > 1)
-			set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-		else
-			set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-		dm_write_reg(mi->ctx, addr, value);
-	}
-
-register_underflow_int:
-	/*todo*/;
-	/*register_interrupt(bm110, irq_source, ctrl_id);*/
-}
-
-static void deallocate_dmif_buffer_helper(
-				struct dc_context *ctx, uint32_t offset)
-{
-	uint32_t value;
-	uint32_t count = 0xBB8; /* max retry count */
-
-	value = dm_read_reg(ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset);
-
-	if (!get_reg_field_value(
-		value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED))
-		return;
-
-	set_reg_field_value(
-		value, 0, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
-
-	dm_write_reg(
-		ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset, value);
-
-	do {
-		value = dm_read_reg(ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset);
-		udelay(10);
-		count--;
-	} while (count > 0 &&
-		!get_reg_field_value(
-			value,
-			PIPE0_DMIF_BUFFER_CONTROL,
-			DMIF_BUFFERS_ALLOCATION_COMPLETED));
-}
-
-void dce110_free_mem_input(
-	struct mem_input *mi,
-	uint32_t total_stream_num)
-{
-	struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mi);
-	uint32_t value;
-
-	/* De-allocate DMIF buffer first */
-	if (mmPIPE0_DMIF_BUFFER_CONTROL + bm_dce110->offsets.pipe != 0)
-		deallocate_dmif_buffer_helper(
-				mi->ctx, bm_dce110->offsets.pipe);
-
-	/* TODO: unregister underflow interrupt
-	unregisterInterrupt();
-	*/
-
-	/* Value of mcHubRdReqDmifLimit.ENABLE.
-	 * 00 - disable dmif rdreq limit
-	 * 01 - enable dmif rdreq limit, disable by dmif stall=1||urg!=0
-	 * 02 - enable dmif rdreq limit, disable by dmif stall=1
-	 * 03 - force enable dmif rdreq limit, ignore dmif stall/urgent
-	 * Stella Wong proposed this change. */
-	if (!IS_FPGA_MAXIMUS_DC(mi->ctx->dce_environment)) {
-		value = dm_read_reg(mi->ctx, mmMC_HUB_RDREQ_DMIF_LIMIT);
-		if (total_stream_num > 1)
-			set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-		else
-			set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-
-		dm_write_reg(mi->ctx, mmMC_HUB_RDREQ_DMIF_LIMIT, value);
-	}
-}
-
 static struct mem_input_funcs dce110_mem_input_funcs = {
 	.mem_input_program_display_marks =
 			dce110_mem_input_program_display_marks,
-	.allocate_mem_input = dce110_allocate_mem_input,
-	.free_mem_input = dce110_free_mem_input,
+	.allocate_mem_input = dce_mem_input_allocate_dmif,
+	.free_mem_input = dce_mem_input_free_dmif,
 	.mem_input_program_surface_flip_and_addr =
 			dce110_mem_input_program_surface_flip_and_addr,
 	.mem_input_program_pte_vm =
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 7731f80db2fb..dac53df2cb86 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
@@ -54,6 +54,11 @@ 
 #include "dce/dce_11_0_d.h"
 #include "dce/dce_11_0_sh_mask.h"
 
+#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
+#include "gmc/gmc_8_2_d.h"
+#include "gmc/gmc_8_2_sh_mask.h"
+#endif
+
 #ifndef mmDP_DPHY_INTERNAL_CTRL
 	#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
 	#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
@@ -464,7 +469,10 @@  static const struct resource_create_funcs res_create_funcs = {
 	.create_hwseq = dce110_hwseq_create,
 };
 
-#define mi_inst_regs(id) { MI_REG_LIST(id) }
+#define mi_inst_regs(id) { \
+	MI_REG_LIST(id), \
+	.MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
+}
 static const struct dce_mem_input_registers mi_regs[] = {
 		mi_inst_regs(0),
 		mi_inst_regs(1),
@@ -472,11 +480,13 @@  static const struct dce_mem_input_registers mi_regs[] = {
 };
 
 static const struct dce_mem_input_shift mi_shifts = {
-		MI_DCE_MASK_SH_LIST(__SHIFT)
+		MI_DCE_MASK_SH_LIST(__SHIFT),
+		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 };
 
 static const struct dce_mem_input_mask mi_masks = {
-		MI_DCE_MASK_SH_LIST(_MASK)
+		MI_DCE_MASK_SH_LIST(_MASK),
+		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 };
 
 static struct mem_input *dce110_mem_input_create(
@@ -496,6 +506,7 @@  static struct mem_input *dce110_mem_input_create(
 		mi->regs = &mi_regs[inst];
 		mi->shifts = &mi_shifts;
 		mi->masks = &mi_masks;
+		mi->wa.single_head_rdreq_dmif_limit = 3;
 		return mi;
 	}
 
diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
index 24b1b91abd71..c29007dafe21 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
@@ -34,388 +34,6 @@ 
 #define DMIF_REG(reg) (reg + mem_input110->offsets.dmif)
 #define PIPE_REG(reg) (reg + mem_input110->offsets.pipe)
 
-static void program_urgency_watermark(
-	const struct dc_context *ctx,
-	const uint32_t offset,
-	struct bw_watermarks marks_low,
-	uint32_t total_dest_line_time_ns)
-{
-	/* register value */
-	uint32_t urgency_cntl = 0;
-	uint32_t wm_mask_cntl = 0;
-
-	uint32_t urgency_addr = offset + mmDPG_PIPE_URGENCY_CONTROL;
-	uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-
-	/*Write mask to enable reading/writing of watermark set A*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-			0,
-			DPG_WATERMARK_MASK_CONTROL,
-			URGENCY_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
-	set_reg_field_value(
-		urgency_cntl,
-		marks_low.a_mark,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_LOW_WATERMARK);
-
-	set_reg_field_value(
-		urgency_cntl,
-		total_dest_line_time_ns,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_HIGH_WATERMARK);
-	dm_write_reg(ctx, urgency_addr, urgency_cntl);
-
-	/*Write mask to enable reading/writing of watermark set B*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-			1,
-			DPG_WATERMARK_MASK_CONTROL,
-			URGENCY_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
-	set_reg_field_value(urgency_cntl,
-		marks_low.b_mark,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_LOW_WATERMARK);
-
-	set_reg_field_value(urgency_cntl,
-		total_dest_line_time_ns,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_HIGH_WATERMARK);
-	dm_write_reg(ctx, urgency_addr, urgency_cntl);
-
-	/*Write mask to enable reading/writing of watermark set C*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-			2,
-			DPG_WATERMARK_MASK_CONTROL,
-			URGENCY_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
-	set_reg_field_value(urgency_cntl,
-		marks_low.c_mark,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_LOW_WATERMARK);
-
-	set_reg_field_value(urgency_cntl,
-		total_dest_line_time_ns,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_HIGH_WATERMARK);
-	dm_write_reg(ctx, urgency_addr, urgency_cntl);
-
-	/*Write mask to enable reading/writing of watermark set D*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-			3,
-			DPG_WATERMARK_MASK_CONTROL,
-			URGENCY_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
-	set_reg_field_value(urgency_cntl,
-		marks_low.d_mark,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_LOW_WATERMARK);
-
-	set_reg_field_value(urgency_cntl,
-		total_dest_line_time_ns,
-		DPG_PIPE_URGENCY_CONTROL,
-		URGENCY_HIGH_WATERMARK);
-	dm_write_reg(ctx, urgency_addr, urgency_cntl);
-}
-
-static void program_stutter_watermark(
-	const struct dc_context *ctx,
-	const uint32_t offset,
-	struct bw_watermarks marks)
-{
-	/* register value */
-	uint32_t stutter_cntl = 0;
-	uint32_t wm_mask_cntl = 0;
-
-	uint32_t stutter_addr = offset + mmDPG_PIPE_STUTTER_CONTROL;
-	uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-
-	/*Write mask to enable reading/writing of watermark set A*/
-
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-		0,
-		DPG_WATERMARK_MASK_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	stutter_cntl = dm_read_reg(ctx, stutter_addr);
-
-	if (ctx->dc->debug.disable_stutter) {
-		set_reg_field_value(stutter_cntl,
-			0,
-			DPG_PIPE_STUTTER_CONTROL,
-			STUTTER_ENABLE);
-	} else {
-		set_reg_field_value(stutter_cntl,
-			1,
-			DPG_PIPE_STUTTER_CONTROL,
-			STUTTER_ENABLE);
-	}
-
-	set_reg_field_value(stutter_cntl,
-		1,
-		DPG_PIPE_STUTTER_CONTROL,
-		STUTTER_IGNORE_FBC);
-
-	/*Write watermark set A*/
-	set_reg_field_value(stutter_cntl,
-		marks.a_mark,
-		DPG_PIPE_STUTTER_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-	dm_write_reg(ctx, stutter_addr, stutter_cntl);
-
-	/*Write mask to enable reading/writing of watermark set B*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-		1,
-		DPG_WATERMARK_MASK_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	stutter_cntl = dm_read_reg(ctx, stutter_addr);
-	/*Write watermark set B*/
-	set_reg_field_value(stutter_cntl,
-		marks.b_mark,
-		DPG_PIPE_STUTTER_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-	dm_write_reg(ctx, stutter_addr, stutter_cntl);
-
-	/*Write mask to enable reading/writing of watermark set C*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-		2,
-		DPG_WATERMARK_MASK_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	stutter_cntl = dm_read_reg(ctx, stutter_addr);
-	/*Write watermark set C*/
-	set_reg_field_value(stutter_cntl,
-		marks.c_mark,
-		DPG_PIPE_STUTTER_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-	dm_write_reg(ctx, stutter_addr, stutter_cntl);
-
-	/*Write mask to enable reading/writing of watermark set D*/
-	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-	set_reg_field_value(wm_mask_cntl,
-		3,
-		DPG_WATERMARK_MASK_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
-	stutter_cntl = dm_read_reg(ctx, stutter_addr);
-	/*Write watermark set D*/
-	set_reg_field_value(stutter_cntl,
-		marks.d_mark,
-		DPG_PIPE_STUTTER_CONTROL,
-		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-	dm_write_reg(ctx, stutter_addr, stutter_cntl);
-}
-
-static void program_nbp_watermark(
-	const struct dc_context *ctx,
-	const uint32_t offset,
-	struct bw_watermarks marks)
-{
-	uint32_t value;
-	uint32_t addr;
-	/* Write mask to enable reading/writing of watermark set A */
-	addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		0,
-		DPG_WATERMARK_MASK_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK_MASK);
-	dm_write_reg(ctx, addr, value);
-
-	addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_ENABLE);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write watermark set A */
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		marks.a_mark,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write mask to enable reading/writing of watermark set B */
-	addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_WATERMARK_MASK_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK_MASK);
-	dm_write_reg(ctx, addr, value);
-
-	addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_ENABLE);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write watermark set B */
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		marks.b_mark,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write mask to enable reading/writing of watermark set C */
-	addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		2,
-		DPG_WATERMARK_MASK_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK_MASK);
-	dm_write_reg(ctx, addr, value);
-
-	addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_ENABLE);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write watermark set C */
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		marks.c_mark,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write mask to enable reading/writing of watermark set D */
-	addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		3,
-		DPG_WATERMARK_MASK_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK_MASK);
-	dm_write_reg(ctx, addr, value);
-
-	addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_ENABLE);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-	set_reg_field_value(
-		value,
-		1,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-	dm_write_reg(ctx, addr, value);
-
-	/* Write watermark set D */
-	value = dm_read_reg(ctx, addr);
-	set_reg_field_value(
-		value,
-		marks.d_mark,
-		DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-		NB_PSTATE_CHANGE_WATERMARK);
-	dm_write_reg(ctx, addr, value);
-}
-
-static void dce112_mem_input_program_display_marks(
-	struct mem_input *mem_input,
-	struct bw_watermarks nbp,
-	struct bw_watermarks stutter,
-	struct bw_watermarks urgent,
-	uint32_t total_dest_line_time_ns)
-{
-	struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mem_input);
-
-	program_urgency_watermark(
-		mem_input->ctx,
-		bm_dce110->offsets.dmif,
-		urgent,
-		total_dest_line_time_ns);
-
-	program_nbp_watermark(
-		mem_input->ctx,
-		bm_dce110->offsets.dmif,
-		nbp);
-
-	program_stutter_watermark(
-		mem_input->ctx,
-		bm_dce110->offsets.dmif,
-		stutter);
-}
-
 /*****************************************/
 /* Constructor, Destructor               */
 /*****************************************/
@@ -430,7 +48,7 @@  bool dce112_mem_input_construct(
 		return false;
 
 	mem_input110->base.funcs->mem_input_program_display_marks =
-					dce112_mem_input_program_display_marks;
+			dce_mem_input_program_display_marks;
 
 	return true;
 }
diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
index 8da0e31f1b6a..ebb8df3cdf4a 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
@@ -43,133 +43,11 @@ 
 #define DMIF_REG(reg) (reg + mem_input80->offsets.dmif)
 #define PIPE_REG(reg) (reg + mem_input80->offsets.pipe)
 
-static uint32_t get_dmif_switch_time_us(
-		uint32_t h_total,
-		uint32_t v_total,
-		uint32_t pix_clk_khz)
-{
-	uint32_t frame_time;
-	uint32_t pixels_per_second;
-	uint32_t pixels_per_frame;
-	uint32_t refresh_rate;
-	const uint32_t us_in_sec = 1000000;
-	const uint32_t min_single_frame_time_us = 30000;
-	/*return double of frame time*/
-	const uint32_t single_frame_time_multiplier = 2;
-
-	if (!h_total || v_total || !pix_clk_khz)
-		return single_frame_time_multiplier * min_single_frame_time_us;
-
-	/*TODO: should we use pixel format normalized pixel clock here?*/
-	pixels_per_second = pix_clk_khz * 1000;
-	pixels_per_frame = h_total * v_total;
-
-	if (!pixels_per_second || !pixels_per_frame) {
-		/* avoid division by zero */
-		ASSERT(pixels_per_frame);
-		ASSERT(pixels_per_second);
-		return single_frame_time_multiplier * min_single_frame_time_us;
-	}
-
-	refresh_rate = pixels_per_second / pixels_per_frame;
-
-	if (!refresh_rate) {
-		/* avoid division by zero*/
-		ASSERT(refresh_rate);
-		return single_frame_time_multiplier * min_single_frame_time_us;
-	}
-
-	frame_time = us_in_sec / refresh_rate;
-
-	if (frame_time < min_single_frame_time_us)
-		frame_time = min_single_frame_time_us;
-
-	frame_time *= single_frame_time_multiplier;
-
-	return frame_time;
-}
-
-static void allocate_mem_input(
-		struct mem_input *mi,
-		uint32_t h_total,
-		uint32_t v_total,
-		uint32_t pix_clk_khz,
-		uint32_t total_targets_num)
-{
-	const uint32_t retry_delay = 10;
-	uint32_t retry_count = get_dmif_switch_time_us(
-			h_total,
-			v_total,
-			pix_clk_khz) / retry_delay;
-
-	struct dce110_mem_input *bm80 = TO_DCE110_MEM_INPUT(mi);
-	uint32_t addr = bm80->offsets.pipe + mmPIPE0_DMIF_BUFFER_CONTROL;
-	uint32_t value;
-	uint32_t field;
-
-	/*Allocate DMIF buffer*/
-	value = dm_read_reg(mi->ctx, addr);
-	field = get_reg_field_value(
-		value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
-	if (field == 2)
-		goto register_underflow_int;
-
-	set_reg_field_value(
-			value,
-			2,
-			PIPE0_DMIF_BUFFER_CONTROL,
-			DMIF_BUFFERS_ALLOCATED);
-
-	dm_write_reg(mi->ctx, addr, value);
-
-	do {
-		value = dm_read_reg(mi->ctx, addr);
-		field = get_reg_field_value(
-			value,
-			PIPE0_DMIF_BUFFER_CONTROL,
-			DMIF_BUFFERS_ALLOCATION_COMPLETED);
-
-		if (field)
-			break;
-
-		udelay(retry_delay);
-		retry_count--;
-
-	} while (retry_count > 0);
-
-	if (field == 0)
-		dm_logger_write(mi->ctx->logger, LOG_ERROR,
-				"%s: DMIF allocation failed",
-				__func__);
-
-	/*
-	 * Stella Wong proposed the following change
-	 *
-	 * Value of mcHubRdReqDmifLimit.ENABLE:
-	 * 00 - disable DMIF rdreq limit
-	 * 01 - enable DMIF rdreq limit, disabled by DMIF stall = 1 || urg != 0
-	 * 02 - enable DMIF rdreq limit, disable by DMIF stall = 1
-	 * 03 - force enable DMIF rdreq limit, ignore DMIF stall / urgent
-	 */
-	addr = mmMC_HUB_RDREQ_DMIF_LIMIT;
-	value = dm_read_reg(mi->ctx, addr);
-	if (total_targets_num > 1)
-		set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-	else
-		set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-	dm_write_reg(mi->ctx, addr, value);
-
-register_underflow_int:
-	/*todo*/;
-	/*register_interrupt(bm80, irq_source, ctrl_id);*/
-}
-
 static struct mem_input_funcs dce80_mem_input_funcs = {
 	.mem_input_program_display_marks =
 			dce110_mem_input_program_display_marks,
-	.allocate_mem_input = allocate_mem_input,
-	.free_mem_input =
-			dce110_free_mem_input,
+	.allocate_mem_input = dce_mem_input_allocate_dmif,
+	.free_mem_input = dce_mem_input_free_dmif,
 	.mem_input_program_surface_flip_and_addr =
 			dce110_mem_input_program_surface_flip_and_addr,
 	.mem_input_program_surface_config =
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 d2fd25b97996..73110341cb4d 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
@@ -56,6 +56,11 @@ 
 
 /* TODO remove this include */
 
+#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
+#include "gmc/gmc_7_1_d.h"
+#include "gmc/gmc_7_1_sh_mask.h"
+#endif
+
 #ifndef mmDP_DPHY_INTERNAL_CTRL
 #define mmDP_DPHY_INTERNAL_CTRL                         0x1CDE
 #define mmDP0_DP_DPHY_INTERNAL_CTRL                     0x1CDE
@@ -453,7 +458,10 @@  static const struct resource_create_funcs res_create_funcs = {
 	.create_hwseq = dce80_hwseq_create,
 };
 
-#define mi_inst_regs(id) { MI_REG_LIST(id) }
+#define mi_inst_regs(id) { \
+	MI_REG_LIST(id), \
+	.MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
+}
 static const struct dce_mem_input_registers mi_regs[] = {
 		mi_inst_regs(0),
 		mi_inst_regs(1),
@@ -464,11 +472,13 @@  static const struct dce_mem_input_registers mi_regs[] = {
 };
 
 static const struct dce_mem_input_shift mi_shifts = {
-		MI_DCE_MASK_SH_LIST(__SHIFT)
+		MI_DCE_MASK_SH_LIST(__SHIFT),
+		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 };
 
 static const struct dce_mem_input_mask mi_masks = {
-		MI_DCE_MASK_SH_LIST(_MASK)
+		MI_DCE_MASK_SH_LIST(_MASK),
+		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 };
 
 static struct mem_input *dce80_mem_input_create(
@@ -488,6 +498,7 @@  static struct mem_input *dce80_mem_input_create(
 		mi->regs = &mi_regs[inst];
 		mi->shifts = &mi_shifts;
 		mi->masks = &mi_masks;
+		mi->wa.single_head_rdreq_dmif_limit = 2;
 		return mi;
 	}
 
diff --git a/drivers/gpu/drm/amd/dal/dc/dm_services.h b/drivers/gpu/drm/amd/dal/dc/dm_services.h
index 289264403983..9cb874a03d54 100644
--- a/drivers/gpu/drm/amd/dal/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/dal/dc/dm_services.h
@@ -70,10 +70,9 @@ 
 
 #endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
 
-
-#define DC_ERR(err_msg)  do { \
+#define DC_ERR(...)  do { \
+	dm_error(__VA_ARGS__); \
 	BREAK_TO_DEBUGGER(); \
-	dm_error(err_msg); \
 } while (0)
 
 #define dm_alloc(size) kzalloc(size, GFP_KERNEL)
@@ -202,7 +201,8 @@  uint32_t generic_reg_update_ex(const struct dc_context *ctx,
  */
 unsigned int generic_reg_wait(const struct dc_context *ctx,
 	uint32_t addr, uint32_t mask, uint32_t shift, uint32_t condition_value,
-	unsigned int delay_between_poll_us, unsigned int time_out_num_tries);
+	unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
+	const char *func_name);
 
 /**************************************
  * Power Play (PP) interfaces
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h
index e7026ec87bce..78dab74edc2d 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h
@@ -48,6 +48,7 @@  struct mem_input {
 	const struct dce_mem_input_registers *regs;
 	const struct dce_mem_input_shift *shifts;
 	const struct dce_mem_input_mask *masks;
+	struct dce_mem_input_wa wa;
 };
 
 struct mem_input_funcs {
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
index 7a05141484c9..92a699337322 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
@@ -156,7 +156,7 @@ 
 #define REG_WAIT(reg_name, field, val, delay, max_try)	\
 		generic_reg_wait(CTX, \
 				REG(reg_name), FN(reg_name, field), val,\
-				delay, max_try)
+				delay, max_try, __func__)
 
 /* macro to update (read, modify, write) register fields
  */