Blob Blame History Raw
From: Anthony Koo <Anthony.Koo@amd.com>
Date: Mon, 23 Jan 2017 16:55:20 -0500
Subject: drm/amd/display: DMCU Compile and Load
Git-commit: 5e7773a219f7821163ad2b17be0d02f8be8ce0c6
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Signed-off-by: Anthony Koo <anthony.koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c                    |   16 
 drivers/gpu/drm/amd/display/dc/core/dc_link.c               |   12 
 drivers/gpu/drm/amd/display/dc/dc.h                         |    4 
 drivers/gpu/drm/amd/display/dc/dce/Makefile                 |    2 
 drivers/gpu/drm/amd/display/dc/dce/dce_abm.c                |  214 ++++++++++++
 drivers/gpu/drm/amd/display/dc/dce/dce_abm.h                |  157 ++++++++
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c               |  127 +++++++
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h               |   91 +++++
 drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c       |   40 --
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c |    6 
 drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c     |   52 ++
 drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c     |   51 ++
 drivers/gpu/drm/amd/display/dc/inc/core_types.h             |    3 
 drivers/gpu/drm/amd/display/dc/inc/hw/abm.h                 |   40 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h                |   42 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h        |    1 
 16 files changed, 788 insertions(+), 70 deletions(-)

--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -268,19 +268,6 @@ static bool init_dmcu_backlight_settings
 	return true;
 }
 
-
-static bool set_abm_level(struct dc *dc, unsigned int abm_level)
-{
-	struct core_dc *core_dc = DC_TO_CORE(dc);
-	int i;
-
-	for (i = 0; i < core_dc->link_count; i++)
-		dc_link_set_abm_level(&core_dc->links[i]->public,
-				abm_level);
-
-	return true;
-}
-
 static bool set_psr_enable(struct dc *dc, bool enable)
 {
 	struct core_dc *core_dc = DC_TO_CORE(dc);
@@ -409,9 +396,6 @@ static void allocate_dc_stream_funcs(str
 	core_dc->public.stream_funcs.init_dmcu_backlight_settings =
 			init_dmcu_backlight_settings;
 
-	core_dc->public.stream_funcs.set_abm_level =
-			set_abm_level;
-
 	core_dc->public.stream_funcs.set_psr_enable =
 			set_psr_enable;
 
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1432,18 +1432,6 @@ bool dc_link_init_dmcu_backlight_setting
 	return true;
 }
 
-bool dc_link_set_abm_level(const struct dc_link *dc_link, uint32_t level)
-{
-	struct core_link *link = DC_LINK_TO_CORE(dc_link);
-	struct dc_context *ctx = link->ctx;
-
-	dm_logger_write(ctx->logger, LOG_BACKLIGHT,
-			"New abm level: %d (0x%X)\n", level, level);
-
-	link->link_enc->funcs->set_dmcu_abm_level(link->link_enc, level);
-	return true;
-}
-
 bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable)
 {
 	struct core_link *link = DC_LINK_TO_CORE(dc_link);
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -103,7 +103,6 @@ struct dc_stream_funcs {
 	bool (*set_backlight)(struct dc *dc, unsigned int backlight_level,
 		unsigned int frame_ramp, const struct dc_stream *stream);
 	bool (*init_dmcu_backlight_settings)(struct dc *dc);
-	bool (*set_abm_level)(struct dc *dc, unsigned int abm_level);
 	bool (*set_psr_enable)(struct dc *dc, bool enable);
 	bool (*setup_psr)(struct dc *dc, const struct dc_stream *stream);
 };
@@ -575,8 +574,6 @@ bool dc_link_set_backlight_level(const s
 
 bool dc_link_init_dmcu_backlight_settings(const struct dc_link *dc_link);
 
-bool dc_link_set_abm_level(const struct dc_link *dc_link, uint32_t level);
-
 bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable);
 
 bool dc_link_setup_psr(const struct dc_link *dc_link,
@@ -730,4 +727,5 @@ bool dc_submit_i2c(
 		uint32_t link_index,
 		struct i2c_command *cmd);
 
+
 #endif /* DC_INTERFACE_H_ */
--- a/drivers/gpu/drm/amd/display/dc/dce/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce/Makefile
@@ -7,7 +7,7 @@
 
 DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
 dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
-dce_clocks.o dce_opp.o
+dce_clocks.o dce_opp.o dce_dmcu.o dce_abm.o
 
 
 AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2012-16 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_abm.h"
+#include "dm_services.h"
+#include "reg_helper.h"
+#include "fixed32_32.h"
+#include "dc.h"
+
+#define TO_DCE_ABM(abm)\
+	container_of(abm, struct dce_abm, base)
+
+#define REG(reg) \
+	(abm_dce->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+	abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name
+
+#define CTX \
+	abm_dce->base.ctx
+
+#define MCP_ABM_LEVEL_SET 0x65
+
+static unsigned int get_current_backlight(struct dce_abm *abm_dce)
+{
+	uint64_t current_backlight;
+	uint32_t round_result;
+	uint32_t pwm_period_cntl, bl_period, bl_int_count;
+	uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en;
+	uint32_t bl_period_mask, bl_pwm_mask;
+
+	pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL);
+	REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
+	REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
+
+	bl_pwm_cntl = REG_READ(BL_PWM_CNTL);
+	REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm));
+	REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);
+
+	if (bl_int_count == 0)
+		bl_int_count = 16;
+
+	bl_period_mask = (1 << bl_int_count) - 1;
+	bl_period &= bl_period_mask;
+
+	bl_pwm_mask = bl_period_mask << (16 - bl_int_count);
+
+	if (fractional_duty_cycle_en == 0)
+		bl_pwm &= bl_pwm_mask;
+	else
+		bl_pwm &= 0xFFFF;
+
+	current_backlight = bl_pwm << (1 + bl_int_count);
+
+	if (bl_period == 0)
+		bl_period = 0xFFFF;
+
+	current_backlight /= bl_period;
+	current_backlight = (current_backlight + 1) >> 1;
+
+	current_backlight = (uint64_t)(current_backlight) * bl_period;
+
+	round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
+
+	round_result = (round_result >> (bl_int_count-1)) & 1;
+
+	current_backlight >>= bl_int_count;
+	current_backlight += round_result;
+
+	return (uint32_t)(current_backlight);
+}
+
+void dce_abm_init(struct abm *abm)
+{
+	struct dce_abm *abm_dce = TO_DCE_ABM(abm);
+	unsigned int backlight = get_current_backlight(abm_dce);
+
+	REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
+	REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
+	REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x103);
+	REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x101);
+	REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x101);
+
+	REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
+			ABM1_HG_NUM_OF_BINS_SEL, 0,
+			ABM1_HG_VMAX_SEL, 1,
+			ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
+
+	REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
+			ABM1_IPCSC_COEFF_SEL_R, 2,
+			ABM1_IPCSC_COEFF_SEL_G, 4,
+			ABM1_IPCSC_COEFF_SEL_B, 2);
+
+	REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
+			BL1_PWM_CURRENT_ABM_LEVEL, backlight);
+
+	REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
+			BL1_PWM_TARGET_ABM_LEVEL, backlight);
+
+	REG_UPDATE(BL1_PWM_USER_LEVEL,
+			BL1_PWM_USER_LEVEL, backlight);
+
+	REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
+			ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
+			ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
+
+	REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
+			ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
+			ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
+			ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
+}
+
+bool dce_abm_set_level(struct abm *abm, uint32_t level)
+{
+	struct dce_abm *abm_dce = TO_DCE_ABM(abm);
+	struct dc_context *ctx = abm_dce->base.ctx;
+
+	unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
+	unsigned int dmcu_wait_reg_ready_interval = 100;
+	unsigned int value;
+
+	/* waitDMCUReadyForCmd */
+	do {
+		dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval);
+		REG_GET(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, &value);
+		dmcu_max_retry_on_wait_reg_ready--;
+	} while
+	/* expected value is 0, loop while not 0*/
+	((value & abm_dce->abm_mask->MASTER_COMM_INTERRUPT) &&
+		dmcu_max_retry_on_wait_reg_ready > 0);
+
+	/* setDMCUParam_ABMLevel */
+	REG_UPDATE_2(MASTER_COMM_CMD_REG,
+			MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET,
+			MASTER_COMM_CMD_REG_BYTE2, level);
+
+	/* notifyDMCUMsg */
+	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
+
+	return true;
+}
+
+static const struct abm_funcs dce_funcs = {
+	.abm_init = dce_abm_init,
+	.set_abm_level = dce_abm_set_level,
+};
+
+static void dce_abm_construct(
+	struct dce_abm *abm_dce,
+	struct dc_context *ctx,
+	const struct dce_abm_registers *regs,
+	const struct dce_abm_shift *abm_shift,
+	const struct dce_abm_mask *abm_mask)
+{
+	struct abm *base = &abm_dce->base;
+
+	base->ctx = ctx;
+	base->funcs = &dce_funcs;
+
+	abm_dce->regs = regs;
+	abm_dce->abm_shift = abm_shift;
+	abm_dce->abm_mask = abm_mask;
+}
+
+struct abm *dce_abm_create(
+	struct dc_context *ctx,
+	const struct dce_abm_registers *regs,
+	const struct dce_abm_shift *abm_shift,
+	const struct dce_abm_mask *abm_mask)
+{
+	struct dce_abm *abm_dce = dm_alloc(sizeof(*abm_dce));
+
+	if (abm_dce == NULL) {
+		BREAK_TO_DEBUGGER();
+		return NULL;
+	}
+
+	dce_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
+
+	abm_dce->base.funcs = &dce_funcs;
+
+	return &abm_dce->base;
+}
+
+void dce_abm_destroy(struct abm **abm)
+{
+	struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
+
+	dm_free(abm_dce);
+	*abm = NULL;
+}
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012-16 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_ABM_H_
+#define _DCE_ABM_H_
+
+#include "abm.h"
+
+#define ABM_COMMON_REG_LIST_DCE_BASE() \
+	SR(BL_PWM_PERIOD_CNTL), \
+	SR(BL_PWM_CNTL), \
+	SR(MASTER_COMM_CNTL_REG), \
+	SR(MASTER_COMM_CMD_REG)
+
+#define ABM_DCE110_COMMON_REG_LIST() \
+	ABM_COMMON_REG_LIST_DCE_BASE(), \
+	SR(DC_ABM1_HG_SAMPLE_RATE), \
+	SR(DC_ABM1_LS_SAMPLE_RATE), \
+	SR(BL1_PWM_BL_UPDATE_SAMPLE_RATE), \
+	SR(DC_ABM1_HG_MISC_CTRL), \
+	SR(DC_ABM1_IPCSC_COEFF_SEL), \
+	SR(BL1_PWM_CURRENT_ABM_LEVEL), \
+	SR(BL1_PWM_TARGET_ABM_LEVEL), \
+	SR(BL1_PWM_USER_LEVEL), \
+	SR(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES), \
+	SR(DC_ABM1_HGLS_REG_READ_PROGRESS)
+
+#define ABM_SF(reg_name, field_name, post_fix)\
+	.field_name = reg_name ## __ ## field_name ## post_fix
+
+#define ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
+	ABM_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
+	ABM_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \
+	ABM_SF(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \
+	ABM_SF(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \
+	ABM_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh), \
+	ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, mask_sh), \
+	ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE2, mask_sh)
+
+#define ABM_MASK_SH_LIST_DCE110(mask_sh) \
+	ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
+	ABM_SF(DC_ABM1_HG_MISC_CTRL, \
+			ABM1_HG_NUM_OF_BINS_SEL, mask_sh), \
+	ABM_SF(DC_ABM1_HG_MISC_CTRL, \
+			ABM1_HG_VMAX_SEL, mask_sh), \
+	ABM_SF(DC_ABM1_HG_MISC_CTRL, \
+			ABM1_HG_BIN_BITWIDTH_SIZE_SEL, mask_sh), \
+	ABM_SF(DC_ABM1_IPCSC_COEFF_SEL, \
+			ABM1_IPCSC_COEFF_SEL_R, mask_sh), \
+	ABM_SF(DC_ABM1_IPCSC_COEFF_SEL, \
+			ABM1_IPCSC_COEFF_SEL_G, mask_sh), \
+	ABM_SF(DC_ABM1_IPCSC_COEFF_SEL, \
+			ABM1_IPCSC_COEFF_SEL_B, mask_sh), \
+	ABM_SF(BL1_PWM_CURRENT_ABM_LEVEL, \
+			BL1_PWM_CURRENT_ABM_LEVEL, mask_sh), \
+	ABM_SF(BL1_PWM_TARGET_ABM_LEVEL, \
+			BL1_PWM_TARGET_ABM_LEVEL, mask_sh), \
+	ABM_SF(BL1_PWM_USER_LEVEL, \
+			BL1_PWM_USER_LEVEL, mask_sh), \
+	ABM_SF(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
+			ABM1_LS_MIN_PIXEL_VALUE_THRES, mask_sh), \
+	ABM_SF(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
+			ABM1_LS_MAX_PIXEL_VALUE_THRES, mask_sh), \
+	ABM_SF(DC_ABM1_HGLS_REG_READ_PROGRESS, \
+			ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
+	ABM_SF(DC_ABM1_HGLS_REG_READ_PROGRESS, \
+			ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
+	ABM_SF(DC_ABM1_HGLS_REG_READ_PROGRESS, \
+			ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, mask_sh)
+
+#define ABM_REG_FIELD_LIST(type) \
+	type ABM1_HG_NUM_OF_BINS_SEL; \
+	type ABM1_HG_VMAX_SEL; \
+	type ABM1_HG_BIN_BITWIDTH_SIZE_SEL; \
+	type ABM1_IPCSC_COEFF_SEL_R; \
+	type ABM1_IPCSC_COEFF_SEL_G; \
+	type ABM1_IPCSC_COEFF_SEL_B; \
+	type BL1_PWM_CURRENT_ABM_LEVEL; \
+	type BL1_PWM_TARGET_ABM_LEVEL; \
+	type BL1_PWM_USER_LEVEL; \
+	type ABM1_LS_MIN_PIXEL_VALUE_THRES; \
+	type ABM1_LS_MAX_PIXEL_VALUE_THRES; \
+	type ABM1_HG_REG_READ_MISSED_FRAME_CLEAR; \
+	type ABM1_LS_REG_READ_MISSED_FRAME_CLEAR; \
+	type ABM1_BL_REG_READ_MISSED_FRAME_CLEAR; \
+	type BL_PWM_PERIOD; \
+	type BL_PWM_PERIOD_BITCNT; \
+	type BL_ACTIVE_INT_FRAC_CNT; \
+	type BL_PWM_FRACTIONAL_EN; \
+	type MASTER_COMM_INTERRUPT; \
+	type MASTER_COMM_CMD_REG_BYTE0; \
+	type MASTER_COMM_CMD_REG_BYTE2
+
+struct dce_abm_shift {
+	ABM_REG_FIELD_LIST(uint8_t);
+};
+
+struct dce_abm_mask {
+	ABM_REG_FIELD_LIST(uint32_t);
+};
+
+struct dce_abm_registers {
+	uint32_t BL_PWM_PERIOD_CNTL;
+	uint32_t BL_PWM_CNTL;
+	uint32_t DC_ABM1_HG_SAMPLE_RATE;
+	uint32_t DC_ABM1_LS_SAMPLE_RATE;
+	uint32_t BL1_PWM_BL_UPDATE_SAMPLE_RATE;
+	uint32_t DC_ABM1_HG_MISC_CTRL;
+	uint32_t DC_ABM1_IPCSC_COEFF_SEL;
+	uint32_t BL1_PWM_CURRENT_ABM_LEVEL;
+	uint32_t BL1_PWM_TARGET_ABM_LEVEL;
+	uint32_t BL1_PWM_USER_LEVEL;
+	uint32_t DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES;
+	uint32_t DC_ABM1_HGLS_REG_READ_PROGRESS;
+	uint32_t MASTER_COMM_CNTL_REG;
+	uint32_t MASTER_COMM_CMD_REG;
+};
+
+struct dce_abm {
+	struct abm base;
+	const struct dce_abm_registers *regs;
+	const struct dce_abm_shift *abm_shift;
+	const struct dce_abm_mask *abm_mask;
+};
+
+struct abm *dce_abm_create(
+	struct dc_context *ctx,
+	const struct dce_abm_registers *regs,
+	const struct dce_abm_shift *abm_shift,
+	const struct dce_abm_mask *abm_mask);
+
+void dce_abm_destroy(struct abm **abm);
+
+#endif /* _DCE_ABM_H_ */
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012-16 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_dmcu.h"
+#include "dm_services.h"
+#include "reg_helper.h"
+#include "fixed32_32.h"
+#include "dc.h"
+
+#define TO_DCE_DMCU(dmcu)\
+	container_of(dmcu, struct dce_dmcu, base)
+
+#define REG(reg) \
+	(dmcu_dce->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+	dmcu_dce->dmcu_shift->field_name, dmcu_dce->dmcu_mask->field_name
+
+#define CTX \
+	dmcu_dce->base.ctx
+
+bool dce_dmcu_load_iram(struct dmcu *dmcu,
+		unsigned int start_offset,
+		const char *src,
+		unsigned int bytes)
+{
+	struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
+	unsigned int count = 0;
+	uint32_t status;
+
+	/* Enable write access to IRAM */
+	REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
+			IRAM_HOST_ACCESS_EN, 1,
+			IRAM_WR_ADDR_AUTO_INC, 1);
+
+	do {
+		dm_delay_in_microseconds(dmcu->ctx, 2);
+		REG_GET(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, &status);
+		count++;
+	} while
+	((status & dmcu_dce->dmcu_mask->DMCU_IRAM_MEM_PWR_STATE) && count < 10);
+
+	REG_WRITE(DMCU_IRAM_WR_CTRL, start_offset);
+
+	for (count = 0; count < bytes; count++)
+		REG_WRITE(DMCU_IRAM_WR_DATA, src[count]);
+
+	/* Disable write access to IRAM to allow dynamic sleep state */
+	REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
+			IRAM_HOST_ACCESS_EN, 0,
+			IRAM_WR_ADDR_AUTO_INC, 0);
+
+	return true;
+}
+
+static const struct dmcu_funcs dce_funcs = {
+	.load_iram = dce_dmcu_load_iram,
+};
+
+static void dce_dmcu_construct(
+	struct dce_dmcu *dmcu_dce,
+	struct dc_context *ctx,
+	const struct dce_dmcu_registers *regs,
+	const struct dce_dmcu_shift *dmcu_shift,
+	const struct dce_dmcu_mask *dmcu_mask)
+{
+	struct dmcu *base = &dmcu_dce->base;
+
+	base->ctx = ctx;
+	base->funcs = &dce_funcs;
+
+	dmcu_dce->regs = regs;
+	dmcu_dce->dmcu_shift = dmcu_shift;
+	dmcu_dce->dmcu_mask = dmcu_mask;
+}
+
+struct dmcu *dce_dmcu_create(
+	struct dc_context *ctx,
+	const struct dce_dmcu_registers *regs,
+	const struct dce_dmcu_shift *dmcu_shift,
+	const struct dce_dmcu_mask *dmcu_mask)
+{
+	struct dce_dmcu *dmcu_dce = dm_alloc(sizeof(*dmcu_dce));
+
+	if (dmcu_dce == NULL) {
+		BREAK_TO_DEBUGGER();
+		return NULL;
+	}
+
+	dce_dmcu_construct(
+		dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);
+
+	dmcu_dce->base.funcs = &dce_funcs;
+
+	return &dmcu_dce->base;
+}
+
+void dce_dmcu_destroy(struct dmcu **dmcu)
+{
+	struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(*dmcu);
+
+	dm_free(dmcu_dce);
+	*dmcu = NULL;
+}
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012-16 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_DMCU_H_
+#define _DCE_DMCU_H_
+
+#include "dmcu.h"
+
+#define DMCU_COMMON_REG_LIST_DCE_BASE() \
+	SR(DMCU_RAM_ACCESS_CTRL), \
+	SR(DMCU_IRAM_WR_CTRL), \
+	SR(DMCU_IRAM_WR_DATA)
+
+#define DMCU_DCE110_COMMON_REG_LIST() \
+	DMCU_COMMON_REG_LIST_DCE_BASE(), \
+	SR(DCI_MEM_PWR_STATUS)
+
+#define DMCU_SF(reg_name, field_name, post_fix)\
+	.field_name = reg_name ## __ ## field_name ## post_fix
+
+#define DMCU_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
+	DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
+			IRAM_HOST_ACCESS_EN, mask_sh), \
+	DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
+			IRAM_WR_ADDR_AUTO_INC, mask_sh)
+
+#define DMCU_MASK_SH_LIST_DCE110(mask_sh) \
+	DMCU_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
+	DMCU_SF(DCI_MEM_PWR_STATUS, \
+			DMCU_IRAM_MEM_PWR_STATE, mask_sh)
+
+#define DMCU_REG_FIELD_LIST(type) \
+	type DMCU_IRAM_MEM_PWR_STATE; \
+	type IRAM_HOST_ACCESS_EN; \
+	type IRAM_WR_ADDR_AUTO_INC
+
+struct dce_dmcu_shift {
+	DMCU_REG_FIELD_LIST(uint8_t);
+};
+
+struct dce_dmcu_mask {
+	DMCU_REG_FIELD_LIST(uint32_t);
+};
+
+struct dce_dmcu_registers {
+	uint32_t DMCU_RAM_ACCESS_CTRL;
+	uint32_t DCI_MEM_PWR_STATUS;
+	uint32_t DMU_MEM_PWR_CNTL;
+	uint32_t DMCU_IRAM_WR_CTRL;
+	uint32_t DMCU_IRAM_WR_DATA;
+};
+
+struct dce_dmcu {
+	struct dmcu base;
+	const struct dce_dmcu_registers *regs;
+	const struct dce_dmcu_shift *dmcu_shift;
+	const struct dce_dmcu_mask *dmcu_mask;
+};
+
+struct dmcu *dce_dmcu_create(
+	struct dc_context *ctx,
+	const struct dce_dmcu_registers *regs,
+	const struct dce_dmcu_shift *dmcu_shift,
+	const struct dce_dmcu_mask *dmcu_mask);
+
+void dce_dmcu_destroy(struct dmcu **dmcu);
+
+#endif /* _DCE_ABM_H_ */
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -142,7 +142,6 @@ static const struct link_encoder_funcs d
 			dce110_link_encoder_set_dmcu_backlight_level,
 	.init_dmcu_backlight_settings =
 			dce110_link_encoder_init_dmcu_backlight_settings,
-	.set_dmcu_abm_level = dce110_link_encoder_set_dmcu_abm_level,
 	.set_dmcu_psr_enable = dce110_link_encoder_set_dmcu_psr_enable,
 	.setup_dmcu_psr = dce110_link_encoder_setup_dmcu_psr,
 	.backlight_control = dce110_link_encoder_edp_backlight_control,
@@ -1769,8 +1768,7 @@ void dce110_link_encoder_init_dmcu_backl
 	 * Bios bug w/a - period resets to zero,
 	 * restoring to cache values which is always correct
 	 */
-	REG_GET(BL_PWM_CNTL,
-				BL_ACTIVE_INT_FRAC_CNT, &value);
+	REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
 	if (value == 0 || bl_pwm_cntl == 1) {
 		if (stored_backlight_registers.vBL_PWM_CNTL != 0) {
 			pwmCntl = stored_backlight_registers.vBL_PWM_CNTL;
@@ -1810,36 +1808,6 @@ void dce110_link_encoder_init_dmcu_backl
 
 	/* Enable the backlight output */
 	REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
-
-}
-
-void dce110_link_encoder_set_dmcu_abm_level(
-	struct link_encoder *enc, uint32_t level)
-{
-	struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-	struct dc_context *ctx = enc110->base.ctx;
-
-	unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
-	unsigned int dmcu_wait_reg_ready_interval = 100;
-	unsigned int regValue;
-
-	/* waitDMCUReadyForCmd */
-	do {
-		dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval);
-		regValue = REG_READ(MASTER_COMM_CNTL_REG);
-		dmcu_max_retry_on_wait_reg_ready--;
-	} while
-	/* expected value is 0, loop while not 0*/
-	((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) &&
-		dmcu_max_retry_on_wait_reg_ready > 0);
-
-	/* setDMCUParam_ABMLevel */
-	REG_UPDATE_2(MASTER_COMM_CMD_REG,
-			MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET,
-			MASTER_COMM_CMD_REG_BYTE2, level);
-
-	/* notifyDMCUMsg */
-	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
 }
 
 static void get_dmcu_psr_state(struct link_encoder *enc, uint32_t *psr_state)
@@ -1856,10 +1824,8 @@ static void get_dmcu_psr_state(struct li
 
 	do {
 		dm_delay_in_microseconds(ctx, 2);
-		REG_GET(DCI_MEM_PWR_STATUS,
-					DMCU_IRAM_MEM_PWR_STATE, &value);
-	} while
-		(value != 0 && count++ < 10);
+		REG_GET(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, &value);
+	} while (value != 0 && count++ < 10);
 
 	/* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */
 	REG_WRITE(DMCU_IRAM_RD_CTRL, psrStateOffset);
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -42,6 +42,7 @@
 #include "stream_encoder.h"
 #include "link_encoder.h"
 #include "clock_source.h"
+#include "abm.h"
 #include "audio.h"
 #include "dce/dce_hwseq.h"
 
@@ -2166,6 +2167,7 @@ static void init_hw(struct core_dc *dc)
 	int i;
 	struct dc_bios *bp;
 	struct transform *xfm;
+	struct abm *abm;
 
 	bp = dc->ctx->dc_bios;
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -2210,6 +2212,10 @@ static void init_hw(struct core_dc *dc)
 		struct audio *audio = dc->res_pool->audios[i];
 		audio->funcs->hw_init(audio);
 	}
+
+	abm = dc->res_pool->abm;
+	if (abm != NULL)
+		abm->funcs->abm_init(abm);
 }
 
 /* TODO: move this to apply_ctx_tohw some how?*/
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -49,6 +49,8 @@
 #include "dce/dce_clock_source.h"
 #include "dce/dce_hwseq.h"
 #include "dce110/dce110_hw_sequencer.h"
+#include "dce/dce_abm.h"
+#include "dce/dce_dmcu.h"
 
 #include "reg_helper.h"
 
@@ -200,6 +202,30 @@ static const struct dce_disp_clk_mask di
 		CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 };
 
+static const struct dce_dmcu_registers dmcu_regs = {
+		DMCU_DCE110_COMMON_REG_LIST()
+};
+
+static const struct dce_dmcu_shift dmcu_shift = {
+		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
+};
+
+static const struct dce_dmcu_mask dmcu_mask = {
+		DMCU_MASK_SH_LIST_DCE110(_MASK)
+};
+
+static const struct dce_abm_registers abm_regs = {
+		ABM_DCE110_COMMON_REG_LIST()
+};
+
+static const struct dce_abm_shift abm_shift = {
+		ABM_MASK_SH_LIST_DCE110(__SHIFT)
+};
+
+static const struct dce_abm_mask abm_mask = {
+		ABM_MASK_SH_LIST_DCE110(_MASK)
+};
+
 #define transform_regs(id)\
 [id] = {\
 		XFM_COMMON_REG_LIST_DCE110(id)\
@@ -712,6 +738,12 @@ static void destruct(struct dce110_resou
 		}
 	}
 
+	if (pool->base.abm != NULL)
+		dce_abm_destroy(&pool->base.abm);
+
+	if (pool->base.dmcu != NULL)
+		dce_dmcu_destroy(&pool->base.dmcu);
+
 	if (pool->base.display_clock != NULL)
 		dce_disp_clk_destroy(&pool->base.display_clock);
 
@@ -1285,6 +1317,26 @@ static bool construct(
 		BREAK_TO_DEBUGGER();
 		goto res_create_fail;
 	}
+
+	pool->base.dmcu = dce_dmcu_create(ctx,
+			&dmcu_regs,
+			&dmcu_shift,
+			&dmcu_mask);
+	if (pool->base.dmcu == NULL) {
+		dm_error("DC: failed to create dmcu!\n");
+		BREAK_TO_DEBUGGER();
+		goto res_create_fail;
+	}
+
+	pool->base.abm = dce_abm_create(ctx,
+			&abm_regs,
+			&abm_shift,
+			&abm_mask);
+	if (pool->base.abm == NULL) {
+		dm_error("DC: failed to create abm!\n");
+		BREAK_TO_DEBUGGER();
+		goto res_create_fail;
+	}
 
 	/* get static clock information for PPLIB or firmware, save
 	 * max_clock_state
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -46,6 +46,8 @@
 
 #include "dce/dce_hwseq.h"
 #include "dce112/dce112_hw_sequencer.h"
+#include "dce/dce_abm.h"
+#include "dce/dce_dmcu.h"
 
 #include "reg_helper.h"
 
@@ -218,6 +220,30 @@ static const struct dce_disp_clk_mask di
 		CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 };
 
+static const struct dce_dmcu_registers dmcu_regs = {
+		DMCU_DCE110_COMMON_REG_LIST()
+};
+
+static const struct dce_dmcu_shift dmcu_shift = {
+		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
+};
+
+static const struct dce_dmcu_mask dmcu_mask = {
+		DMCU_MASK_SH_LIST_DCE110(_MASK)
+};
+
+static const struct dce_abm_registers abm_regs = {
+		ABM_DCE110_COMMON_REG_LIST()
+};
+
+static const struct dce_abm_shift abm_shift = {
+		ABM_MASK_SH_LIST_DCE110(__SHIFT)
+};
+
+static const struct dce_abm_mask abm_mask = {
+		ABM_MASK_SH_LIST_DCE110(_MASK)
+};
+
 #define transform_regs(id)\
 [id] = {\
 		XFM_COMMON_REG_LIST_DCE110(id)\
@@ -719,6 +745,12 @@ static void destruct(struct dce110_resou
 		}
 	}
 
+	if (pool->base.abm != NULL)
+		dce_abm_destroy(&pool->base.abm);
+
+	if (pool->base.dmcu != NULL)
+		dce_dmcu_destroy(&pool->base.dmcu);
+
 	if (pool->base.display_clock != NULL)
 		dce_disp_clk_destroy(&pool->base.display_clock);
 
@@ -1283,6 +1315,25 @@ static bool construct(
 		goto res_create_fail;
 	}
 
+	pool->base.dmcu = dce_dmcu_create(ctx,
+			&dmcu_regs,
+			&dmcu_shift,
+			&dmcu_mask);
+	if (pool->base.dmcu == NULL) {
+		dm_error("DC: failed to create dmcu!\n");
+		BREAK_TO_DEBUGGER();
+		goto res_create_fail;
+	}
+
+	pool->base.abm = dce_abm_create(ctx,
+			&abm_regs,
+			&abm_shift,
+			&abm_mask);
+	if (pool->base.abm == NULL) {
+		dm_error("DC: failed to create abm!\n");
+		BREAK_TO_DEBUGGER();
+		goto res_create_fail;
+	}
 
 	/* get static clock information for PPLIB or firmware, save
 	 * max_clock_state
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -259,6 +259,9 @@ struct resource_pool {
 	struct display_clock *display_clock;
 	struct irq_service *irqs;
 
+	struct abm *abm;
+	struct dmcu *dmcu;
+
 	const struct resource_funcs *funcs;
 	const struct resource_caps *res_cap;
 };
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
@@ -0,0 +1,40 @@
+/* Copyright 2012-15 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 __DC_ABM_H__
+#define __DC_ABM_H__
+
+#include "dm_services_types.h"
+
+struct abm {
+	struct dc_context *ctx;
+	const struct abm_funcs *funcs;
+};
+
+struct abm_funcs {
+	void (*abm_init)(struct abm *abm);
+	bool (*set_abm_level)(struct abm *abm, unsigned int abm_level);
+};
+
+#endif
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -0,0 +1,42 @@
+/* Copyright 2012-15 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 __DC_DMCU_H__
+#define __DC_DMCU_H__
+
+#include "dm_services_types.h"
+
+struct dmcu {
+	struct dc_context *ctx;
+	const struct dmcu_funcs *funcs;
+};
+
+struct dmcu_funcs {
+	bool (*load_iram)(struct dmcu *dmcu,
+			unsigned int start_offset,
+			const char *src,
+			unsigned int bytes);
+};
+
+#endif
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -225,7 +225,6 @@ struct link_encoder_funcs {
 	void (*set_dmcu_backlight_level)(struct link_encoder *enc,
 		uint32_t level, uint32_t frame_ramp, uint32_t controller_id);
 	void (*init_dmcu_backlight_settings)(struct link_encoder *enc);
-	void (*set_dmcu_abm_level)(struct link_encoder *enc, uint32_t level);
 	void (*set_dmcu_psr_enable)(struct link_encoder *enc, bool enable);
 	void (*setup_dmcu_psr)(struct link_encoder *enc,
 			struct psr_dmcu_context *psr_context);