drm/amd/display: Refactor HWSS into component folder
authorMounika Adhuri <moadhuri@amd.com>
Fri, 22 Sep 2023 12:53:28 +0000 (18:23 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 9 Oct 2023 21:00:09 +0000 (17:00 -0400)
[why]
Rename hw_sequencer to hwseq.
Move all hwseq files to unique
folder hwss.

[how]
creating hwss repo in dc, and moved the dcnxx_hwseq.c
and .h files into corresponding new folders inside the hwss
and cleared the linkage errors by adding relative paths
in the Makefile.template.

Reviewed-by: Martin Leung <martin.leung@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Mounika Adhuri <moadhuri@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
132 files changed:
drivers/gpu/drm/amd/display/Makefile
drivers/gpu/drm/amd/display/dc/Makefile
drivers/gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce/Makefile
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dce100/Makefile
drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c [deleted file]
drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
drivers/gpu/drm/amd/display/dc/dce110/Makefile
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c [deleted file]
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/dce112/Makefile
drivers/gpu/drm/amd/display/dc/dce112/dce112_hw_sequencer.c [deleted file]
drivers/gpu/drm/amd/display/dc/dce112/dce112_hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
drivers/gpu/drm/amd/display/dc/dce120/Makefile
drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c [deleted file]
drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce80/Makefile
drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c [deleted file]
drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
drivers/gpu/drm/amd/display/dc/dcn10/Makefile
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
drivers/gpu/drm/amd/display/dc/dcn20/Makefile
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn201/Makefile
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
drivers/gpu/drm/amd/display/dc/dcn21/Makefile
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/display/dc/dcn30/Makefile
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/dcn301/Makefile
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
drivers/gpu/drm/amd/display/dc/dcn302/Makefile
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.c
drivers/gpu/drm/amd/display/dc/dcn303/Makefile
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c
drivers/gpu/drm/amd/display/dc/dcn31/Makefile
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/dc/dcn314/Makefile
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
drivers/gpu/drm/amd/display/dc/dcn32/Makefile
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
drivers/gpu/drm/amd/display/dc/dcn35/Makefile
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c [deleted file]
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.h [deleted file]
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
drivers/gpu/drm/amd/display/dc/hwss/Makefile [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce112/dce112_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce112/dce112_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn302/dcn302_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn302/dcn302_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h [deleted file]
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h [deleted file]
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h

index 0d610cb..af17ab8 100644 (file)
@@ -29,6 +29,7 @@ AMDDALPATH = $(RELATIVE_AMD_DISPLAY_PATH)
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/hw
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/clk_mgr
+subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/hwss
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/freesync
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/color
index 53ec782..3a169b7 100644 (file)
@@ -22,7 +22,7 @@
 #
 # Makefile for Display Core (dc) component.
 
-DC_LIBS = basics bios clk_mgr dce gpio irq link virtual dsc
+DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link virtual dsc
 
 ifdef CONFIG_DRM_AMD_DC_FP
 
index 5399b8c..c9ba7b3 100644 (file)
@@ -30,7 +30,7 @@
 #include "dce110/dce110_clk_mgr.h"
 #include "dce120_clk_mgr.h"
 #include "dce100/dce_clk_mgr.h"
-#include "dce120/dce120_hw_sequencer.h"
+#include "dce120/dce120_hwseq.h"
 
 static const struct state_dependent_clocks dce120_max_clks_by_state[] = {
 /*ClocksStateInvalid - should not be used*/
index 2bd30a7..38e5f02 100644 (file)
@@ -35,7 +35,7 @@
 #include "grph_object_ctrl_defs.h"
 #include <inc/hw/opp.h>
 
-#include "inc/hw_sequencer.h"
+#include "hwss/hw_sequencer.h"
 #include "inc/compressor.h"
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
index 15b64c2..986e0e7 100644 (file)
@@ -26,7 +26,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_hwseq.o \
+DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o \
 dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
 dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \
 dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o dmub_abm_lcd.o dce_panel_cntl.o \
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
deleted file mode 100644 (file)
index 4202fad..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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"
-#include "hw_sequencer_private.h"
-#include "core_types.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);
-}
-
-void dce_pipe_control_lock(struct dc *dc,
-               struct pipe_ctx *pipe,
-               bool lock)
-{
-       uint32_t lock_val = lock ? 1 : 0;
-       uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* Not lock pipe when blank */
-       if (lock && pipe->stream_res.tg->funcs->is_blanked &&
-           pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
-               return;
-
-       val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
-                       BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
-                       BLND_SCL_V_UPDATE_LOCK, &scl,
-                       BLND_BLND_V_UPDATE_LOCK, &blnd,
-                       BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
-
-       dcp_grph = lock_val;
-       scl = lock_val;
-       blnd = lock_val;
-       update_lock_mode = lock_val;
-
-       REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
-                       BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
-                       BLND_SCL_V_UPDATE_LOCK, scl);
-
-       if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
-               REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
-                               BLND_BLND_V_UPDATE_LOCK, blnd,
-                               BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
-
-       if (hws->wa.blnd_crtc_trigger) {
-               if (!lock) {
-                       uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
-                       REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
-               }
-       }
-}
-
-#if defined(CONFIG_DRM_AMD_DC_SI)
-void dce60_pipe_control_lock(struct dc *dc,
-               struct pipe_ctx *pipe,
-               bool lock)
-{
-       /* DCE6 has no BLND_V_UPDATE_LOCK register */
-}
-#endif
-
-void dce_set_blender_mode(struct dce_hwseq *hws,
-       unsigned int blnd_inst,
-       enum blnd_mode mode)
-{
-       uint32_t feedthrough = 1;
-       uint32_t blnd_mode = 0;
-       uint32_t multiplied_mode = 0;
-       uint32_t alpha_mode = 2;
-
-       switch (mode) {
-       case BLND_MODE_OTHER_PIPE:
-               feedthrough = 0;
-               blnd_mode = 1;
-               alpha_mode = 0;
-               break;
-       case BLND_MODE_BLENDING:
-               feedthrough = 0;
-               blnd_mode = 2;
-               alpha_mode = 0;
-               multiplied_mode = 1;
-               break;
-       case BLND_MODE_CURRENT_PIPE:
-       default:
-               if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
-                               blnd_inst == 0)
-                       feedthrough = 0;
-               break;
-       }
-
-       REG_UPDATE(BLND_CONTROL[blnd_inst],
-               BLND_MODE, blnd_mode);
-
-       if (hws->masks->BLND_ALPHA_MODE != 0) {
-               REG_UPDATE_3(BLND_CONTROL[blnd_inst],
-                       BLND_FEEDTHROUGH_EN, feedthrough,
-                       BLND_ALPHA_MODE, alpha_mode,
-                       BLND_MULTIPLIED_MODE, multiplied_mode);
-       }
-}
-
-
-static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
-{
-       if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
-               REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
-                               DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
-}
-
-static void dce_underlay_clock_enable(struct dce_hwseq *hws)
-{
-       /* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
-       if (REG(DCFEV_CLOCK_CONTROL))
-               REG_UPDATE(DCFEV_CLOCK_CONTROL,
-                               DCFEV_CLOCK_ENABLE, 1);
-}
-
-static void enable_hw_base_light_sleep(void)
-{
-       /* TODO: implement */
-}
-
-static void disable_sw_manual_control_light_sleep(void)
-{
-       /* TODO: implement */
-}
-
-void dce_clock_gating_power_up(struct dce_hwseq *hws,
-               bool enable)
-{
-       if (enable) {
-               enable_hw_base_light_sleep();
-               disable_sw_manual_control_light_sleep();
-       } else {
-               dce_disable_sram_shut_down(hws);
-               dce_underlay_clock_enable(hws);
-       }
-}
-
-void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
-               struct clock_source *clk_src,
-               unsigned int tg_inst)
-{
-       if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO || clk_src->dp_clk_src) {
-               REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
-                               DP_DTO0_ENABLE, 1);
-
-       } else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
-               uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
-
-               REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
-                               PHYPLL_PIXEL_RATE_SOURCE, rate_source,
-                               PIXEL_RATE_PLL_SOURCE, 0);
-
-               REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
-                               DP_DTO0_ENABLE, 0);
-
-       } else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
-               uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
-
-               REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
-                               PIXEL_RATE_SOURCE, rate_source,
-                               DP_DTO0_ENABLE, 0);
-
-               if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
-                       REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
-                                       PIXEL_RATE_PLL_SOURCE, 1);
-       } else {
-               DC_ERR("Unknown clock source. clk_src id: %d, TG_inst: %d",
-                      clk_src->id, tg_inst);
-       }
-}
-
-/* Only use LUT for 8 bit formats */
-bool dce_use_lut(enum surface_pixel_format format)
-{
-       switch (format) {
-       case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
-       case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
-               return true;
-       default:
-               return false;
-       }
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
deleted file mode 100644 (file)
index 2fefdf4..0000000
+++ /dev/null
@@ -1,1241 +0,0 @@
-/*
- * 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 "dc_types.h"
-
-#define HWSEQ_DCEF_REG_LIST_DCE8() \
-       .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_DCEF_REG_LIST() \
-       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), \
-       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL)
-
-#define HWSEQ_BLND_REG_LIST() \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 0), \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 1), \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 2), \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 3), \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 4), \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 5), \
-       SRII(BLND_CONTROL, BLND, 0), \
-       SRII(BLND_CONTROL, BLND, 1), \
-       SRII(BLND_CONTROL, BLND, 2), \
-       SRII(BLND_CONTROL, BLND, 3), \
-       SRII(BLND_CONTROL, BLND, 4), \
-       SRII(BLND_CONTROL, BLND, 5)
-
-#define HSWEQ_DCN_PIXEL_RATE_REG_LIST(blk, inst) \
-       SRII(PIXEL_RATE_CNTL, blk, inst), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, inst)
-
-#define HWSEQ_PIXEL_RATE_REG_LIST(blk) \
-       SRII(PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PIXEL_RATE_CNTL, blk, 1), \
-       SRII(PIXEL_RATE_CNTL, blk, 2), \
-       SRII(PIXEL_RATE_CNTL, blk, 3), \
-       SRII(PIXEL_RATE_CNTL, blk, 4), \
-       SRII(PIXEL_RATE_CNTL, blk, 5)
-
-#define HWSEQ_PIXEL_RATE_REG_LIST_201(blk) \
-       SRII(PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PIXEL_RATE_CNTL, blk, 1)
-
-#define HWSEQ_PHYPLL_REG_LIST(blk) \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5)
-
-#define HWSEQ_PIXEL_RATE_REG_LIST_3(blk) \
-       SRII(PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PIXEL_RATE_CNTL, blk, 1),\
-       SRII(PIXEL_RATE_CNTL, blk, 2),\
-       SRII(PIXEL_RATE_CNTL, blk, 3), \
-       SRII(PIXEL_RATE_CNTL, blk, 4), \
-       SRII(PIXEL_RATE_CNTL, blk, 5)
-
-#define HWSEQ_PHYPLL_REG_LIST_3(blk) \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5)
-
-#define HWSEQ_PIXEL_RATE_REG_LIST_302(blk) \
-       SRII(PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PIXEL_RATE_CNTL, blk, 1),\
-       SRII(PIXEL_RATE_CNTL, blk, 2),\
-       SRII(PIXEL_RATE_CNTL, blk, 3), \
-       SRII(PIXEL_RATE_CNTL, blk, 4)
-
-#define HWSEQ_PHYPLL_REG_LIST_302(blk) \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4)
-
-#define HWSEQ_PIXEL_RATE_REG_LIST_303(blk) \
-       SRII(PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PIXEL_RATE_CNTL, blk, 1)
-
-#define HWSEQ_PHYPLL_REG_LIST_303(blk) \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1)
-
-
-#define HWSEQ_PHYPLL_REG_LIST_201(blk) \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
-       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1)
-
-#define HWSEQ_DCE11_REG_LIST_BASE() \
-       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
-       SR(DCFEV_CLOCK_CONTROL), \
-       SRII(DCFE_CLOCK_CONTROL, DCFE, 0), \
-       SRII(DCFE_CLOCK_CONTROL, DCFE, 1), \
-       SRII(CRTC_H_BLANK_START_END, CRTC, 0),\
-       SRII(CRTC_H_BLANK_START_END, CRTC, 1),\
-       SRII(BLND_V_UPDATE_LOCK, BLND, 0),\
-       SRII(BLND_V_UPDATE_LOCK, BLND, 1),\
-       SRII(BLND_CONTROL, BLND, 0),\
-       SRII(BLND_CONTROL, BLND, 1),\
-       SR(BLNDV_CONTROL),\
-       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
-
-#if defined(CONFIG_DRM_AMD_DC_SI)
-#define HWSEQ_DCE6_REG_LIST() \
-       HWSEQ_DCEF_REG_LIST_DCE8(), \
-       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
-#endif
-
-#define HWSEQ_DCE8_REG_LIST() \
-       HWSEQ_DCEF_REG_LIST_DCE8(), \
-       HWSEQ_BLND_REG_LIST(), \
-       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
-
-#define HWSEQ_DCE10_REG_LIST() \
-       HWSEQ_DCEF_REG_LIST(), \
-       HWSEQ_BLND_REG_LIST(), \
-       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
-
-#define HWSEQ_ST_REG_LIST() \
-       HWSEQ_DCE11_REG_LIST_BASE(), \
-       .DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
-       .CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
-       .BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
-       .BLND_CONTROL[2] = mmBLNDV_CONTROL
-
-#define HWSEQ_CZ_REG_LIST() \
-       HWSEQ_DCE11_REG_LIST_BASE(), \
-       SRII(DCFE_CLOCK_CONTROL, DCFE, 2), \
-       SRII(CRTC_H_BLANK_START_END, CRTC, 2), \
-       SRII(BLND_V_UPDATE_LOCK, BLND, 2), \
-       SRII(BLND_CONTROL, BLND, 2), \
-       .DCFE_CLOCK_CONTROL[3] = mmDCFEV_CLOCK_CONTROL, \
-       .CRTC_H_BLANK_START_END[3] = mmCRTCV_H_BLANK_START_END, \
-       .BLND_V_UPDATE_LOCK[3] = mmBLNDV_V_UPDATE_LOCK, \
-       .BLND_CONTROL[3] = mmBLNDV_CONTROL
-
-#define HWSEQ_DCE120_REG_LIST() \
-       HWSEQ_DCE10_REG_LIST(), \
-       HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
-       HWSEQ_PHYPLL_REG_LIST(CRTC), \
-       SR(DCHUB_FB_LOCATION),\
-       SR(DCHUB_AGP_BASE),\
-       SR(DCHUB_AGP_BOT),\
-       SR(DCHUB_AGP_TOP)
-
-#define HWSEQ_VG20_REG_LIST() \
-       HWSEQ_DCE120_REG_LIST(),\
-       MMHUB_SR(MC_VM_XGMI_LFB_CNTL)
-
-#define HWSEQ_DCE112_REG_LIST() \
-       HWSEQ_DCE10_REG_LIST(), \
-       HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
-       HWSEQ_PHYPLL_REG_LIST(CRTC)
-
-#define HWSEQ_DCN_REG_LIST()\
-       SR(REFCLK_CNTL), \
-       SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
-       SR(DIO_MEM_PWR_CTRL), \
-       SR(DCCG_GATE_DISABLE_CNTL), \
-       SR(DCCG_GATE_DISABLE_CNTL2), \
-       SR(DCFCLK_CNTL),\
-       SR(DCFCLK_CNTL), \
-       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL)
-
-
-#define MMHUB_DCN_REG_LIST()\
-       /* todo:  get these from GVM instead of reading registers ourselves */\
-       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
-       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
-       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32),\
-       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32),\
-       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32),\
-       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32),\
-       MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32),\
-       MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32),\
-       MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB),\
-       MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB),\
-       MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
-       MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
-
-
-#define HWSEQ_DCN1_REG_LIST()\
-       HWSEQ_DCN_REG_LIST(), \
-       MMHUB_DCN_REG_LIST(), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
-       SR(DCHUBBUB_SDPIF_FB_BASE),\
-       SR(DCHUBBUB_SDPIF_FB_OFFSET),\
-       SR(DCHUBBUB_SDPIF_AGP_BASE),\
-       SR(DCHUBBUB_SDPIF_AGP_BOT),\
-       SR(DCHUBBUB_SDPIF_AGP_TOP),\
-       SR(DOMAIN0_PG_CONFIG), \
-       SR(DOMAIN1_PG_CONFIG), \
-       SR(DOMAIN2_PG_CONFIG), \
-       SR(DOMAIN3_PG_CONFIG), \
-       SR(DOMAIN4_PG_CONFIG), \
-       SR(DOMAIN5_PG_CONFIG), \
-       SR(DOMAIN6_PG_CONFIG), \
-       SR(DOMAIN7_PG_CONFIG), \
-       SR(DOMAIN0_PG_STATUS), \
-       SR(DOMAIN1_PG_STATUS), \
-       SR(DOMAIN2_PG_STATUS), \
-       SR(DOMAIN3_PG_STATUS), \
-       SR(DOMAIN4_PG_STATUS), \
-       SR(DOMAIN5_PG_STATUS), \
-       SR(DOMAIN6_PG_STATUS), \
-       SR(DOMAIN7_PG_STATUS), \
-       SR(D1VGA_CONTROL), \
-       SR(D2VGA_CONTROL), \
-       SR(D3VGA_CONTROL), \
-       SR(D4VGA_CONTROL), \
-       SR(VGA_TEST_CONTROL), \
-       SR(DC_IP_REQUEST_CNTL)
-
-#define HWSEQ_DCN2_REG_LIST()\
-       HWSEQ_DCN_REG_LIST(), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 4), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 5), \
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(DOMAIN0_PG_CONFIG), \
-       SR(DOMAIN1_PG_CONFIG), \
-       SR(DOMAIN2_PG_CONFIG), \
-       SR(DOMAIN3_PG_CONFIG), \
-       SR(DOMAIN4_PG_CONFIG), \
-       SR(DOMAIN5_PG_CONFIG), \
-       SR(DOMAIN6_PG_CONFIG), \
-       SR(DOMAIN7_PG_CONFIG), \
-       SR(DOMAIN8_PG_CONFIG), \
-       SR(DOMAIN9_PG_CONFIG), \
-/*     SR(DOMAIN10_PG_CONFIG), Navi1x HUBP5 not powergate-able*/\
-/*     SR(DOMAIN11_PG_CONFIG), Navi1x DPP5 is not powergate-able */\
-       SR(DOMAIN16_PG_CONFIG), \
-       SR(DOMAIN17_PG_CONFIG), \
-       SR(DOMAIN18_PG_CONFIG), \
-       SR(DOMAIN19_PG_CONFIG), \
-       SR(DOMAIN20_PG_CONFIG), \
-       SR(DOMAIN21_PG_CONFIG), \
-       SR(DOMAIN0_PG_STATUS), \
-       SR(DOMAIN1_PG_STATUS), \
-       SR(DOMAIN2_PG_STATUS), \
-       SR(DOMAIN3_PG_STATUS), \
-       SR(DOMAIN4_PG_STATUS), \
-       SR(DOMAIN5_PG_STATUS), \
-       SR(DOMAIN6_PG_STATUS), \
-       SR(DOMAIN7_PG_STATUS), \
-       SR(DOMAIN8_PG_STATUS), \
-       SR(DOMAIN9_PG_STATUS), \
-       SR(DOMAIN10_PG_STATUS), \
-       SR(DOMAIN11_PG_STATUS), \
-       SR(DOMAIN16_PG_STATUS), \
-       SR(DOMAIN17_PG_STATUS), \
-       SR(DOMAIN18_PG_STATUS), \
-       SR(DOMAIN19_PG_STATUS), \
-       SR(DOMAIN20_PG_STATUS), \
-       SR(DOMAIN21_PG_STATUS), \
-       SR(D1VGA_CONTROL), \
-       SR(D2VGA_CONTROL), \
-       SR(D3VGA_CONTROL), \
-       SR(D4VGA_CONTROL), \
-       SR(D5VGA_CONTROL), \
-       SR(D6VGA_CONTROL), \
-       SR(DC_IP_REQUEST_CNTL)
-
-#define HWSEQ_DCN21_REG_LIST()\
-       HWSEQ_DCN_REG_LIST(), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
-       MMHUB_DCN_REG_LIST(), \
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(DOMAIN0_PG_CONFIG), \
-       SR(DOMAIN1_PG_CONFIG), \
-       SR(DOMAIN2_PG_CONFIG), \
-       SR(DOMAIN3_PG_CONFIG), \
-       SR(DOMAIN4_PG_CONFIG), \
-       SR(DOMAIN5_PG_CONFIG), \
-       SR(DOMAIN6_PG_CONFIG), \
-       SR(DOMAIN7_PG_CONFIG), \
-       SR(DOMAIN16_PG_CONFIG), \
-       SR(DOMAIN17_PG_CONFIG), \
-       SR(DOMAIN18_PG_CONFIG), \
-       SR(DOMAIN0_PG_STATUS), \
-       SR(DOMAIN1_PG_STATUS), \
-       SR(DOMAIN2_PG_STATUS), \
-       SR(DOMAIN3_PG_STATUS), \
-       SR(DOMAIN4_PG_STATUS), \
-       SR(DOMAIN5_PG_STATUS), \
-       SR(DOMAIN6_PG_STATUS), \
-       SR(DOMAIN7_PG_STATUS), \
-       SR(DOMAIN16_PG_STATUS), \
-       SR(DOMAIN17_PG_STATUS), \
-       SR(DOMAIN18_PG_STATUS), \
-       SR(D1VGA_CONTROL), \
-       SR(D2VGA_CONTROL), \
-       SR(D3VGA_CONTROL), \
-       SR(D4VGA_CONTROL), \
-       SR(D5VGA_CONTROL), \
-       SR(D6VGA_CONTROL), \
-       SR(DC_IP_REQUEST_CNTL)
-
-#define HWSEQ_DCN201_REG_LIST()\
-       HWSEQ_DCN_REG_LIST(), \
-       HWSEQ_PIXEL_RATE_REG_LIST_201(OTG), \
-       HWSEQ_PHYPLL_REG_LIST_201(OTG), \
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(AZALIA_AUDIO_DTO), \
-       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
-       MMHUB_SR(MC_VM_FB_LOCATION_BASE), \
-       MMHUB_SR(MC_VM_FB_LOCATION_TOP), \
-       MMHUB_SR(MC_VM_FB_OFFSET)
-
-#define HWSEQ_DCN30_REG_LIST()\
-       HWSEQ_DCN2_REG_LIST(),\
-       HWSEQ_DCN_REG_LIST(), \
-       HWSEQ_PIXEL_RATE_REG_LIST_3(OTG), \
-       HWSEQ_PHYPLL_REG_LIST_3(OTG), \
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(AZALIA_AUDIO_DTO), \
-       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
-       SR(HPO_TOP_CLOCK_CONTROL), \
-       SR(ODM_MEM_PWR_CTRL3), \
-       SR(DMU_MEM_PWR_CNTL), \
-       SR(MMHUBBUB_MEM_PWR_CNTL)
-
-#define HWSEQ_DCN301_REG_LIST()\
-       SR(REFCLK_CNTL), \
-       SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
-       SR(DIO_MEM_PWR_CTRL), \
-       SR(DCCG_GATE_DISABLE_CNTL), \
-       SR(DCCG_GATE_DISABLE_CNTL2), \
-       SR(DCFCLK_CNTL),\
-       SR(DCFCLK_CNTL), \
-       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
-       SRII(PIXEL_RATE_CNTL, OTG, 0), \
-       SRII(PIXEL_RATE_CNTL, OTG, 1),\
-       SRII(PIXEL_RATE_CNTL, OTG, 2),\
-       SRII(PIXEL_RATE_CNTL, OTG, 3),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
-       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(DOMAIN0_PG_CONFIG), \
-       SR(DOMAIN1_PG_CONFIG), \
-       SR(DOMAIN2_PG_CONFIG), \
-       SR(DOMAIN3_PG_CONFIG), \
-       SR(DOMAIN4_PG_CONFIG), \
-       SR(DOMAIN5_PG_CONFIG), \
-       SR(DOMAIN6_PG_CONFIG), \
-       SR(DOMAIN7_PG_CONFIG), \
-       SR(DOMAIN16_PG_CONFIG), \
-       SR(DOMAIN17_PG_CONFIG), \
-       SR(DOMAIN18_PG_CONFIG), \
-       SR(DOMAIN0_PG_STATUS), \
-       SR(DOMAIN1_PG_STATUS), \
-       SR(DOMAIN2_PG_STATUS), \
-       SR(DOMAIN3_PG_STATUS), \
-       SR(DOMAIN4_PG_STATUS), \
-       SR(DOMAIN5_PG_STATUS), \
-       SR(DOMAIN6_PG_STATUS), \
-       SR(DOMAIN7_PG_STATUS), \
-       SR(DOMAIN16_PG_STATUS), \
-       SR(DOMAIN17_PG_STATUS), \
-       SR(DOMAIN18_PG_STATUS), \
-       SR(D1VGA_CONTROL), \
-       SR(D2VGA_CONTROL), \
-       SR(D3VGA_CONTROL), \
-       SR(D4VGA_CONTROL), \
-       SR(D5VGA_CONTROL), \
-       SR(D6VGA_CONTROL), \
-       SR(DC_IP_REQUEST_CNTL), \
-       SR(AZALIA_AUDIO_DTO), \
-       SR(AZALIA_CONTROLLER_CLOCK_GATING)
-
-#define HWSEQ_DCN302_REG_LIST()\
-       HWSEQ_DCN_REG_LIST(), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 4), \
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(DOMAIN0_PG_CONFIG), \
-       SR(DOMAIN1_PG_CONFIG), \
-       SR(DOMAIN2_PG_CONFIG), \
-       SR(DOMAIN3_PG_CONFIG), \
-       SR(DOMAIN4_PG_CONFIG), \
-       SR(DOMAIN5_PG_CONFIG), \
-       SR(DOMAIN6_PG_CONFIG), \
-       SR(DOMAIN7_PG_CONFIG), \
-       SR(DOMAIN8_PG_CONFIG), \
-       SR(DOMAIN9_PG_CONFIG), \
-       SR(DOMAIN16_PG_CONFIG), \
-       SR(DOMAIN17_PG_CONFIG), \
-       SR(DOMAIN18_PG_CONFIG), \
-       SR(DOMAIN19_PG_CONFIG), \
-       SR(DOMAIN20_PG_CONFIG), \
-       SR(DOMAIN0_PG_STATUS), \
-       SR(DOMAIN1_PG_STATUS), \
-       SR(DOMAIN2_PG_STATUS), \
-       SR(DOMAIN3_PG_STATUS), \
-       SR(DOMAIN4_PG_STATUS), \
-       SR(DOMAIN5_PG_STATUS), \
-       SR(DOMAIN6_PG_STATUS), \
-       SR(DOMAIN7_PG_STATUS), \
-       SR(DOMAIN8_PG_STATUS), \
-       SR(DOMAIN9_PG_STATUS), \
-       SR(DOMAIN16_PG_STATUS), \
-       SR(DOMAIN17_PG_STATUS), \
-       SR(DOMAIN18_PG_STATUS), \
-       SR(DOMAIN19_PG_STATUS), \
-       SR(DOMAIN20_PG_STATUS), \
-       SR(D1VGA_CONTROL), \
-       SR(D2VGA_CONTROL), \
-       SR(D3VGA_CONTROL), \
-       SR(D4VGA_CONTROL), \
-       SR(D5VGA_CONTROL), \
-       SR(D6VGA_CONTROL), \
-       SR(DC_IP_REQUEST_CNTL), \
-       HWSEQ_PIXEL_RATE_REG_LIST_302(OTG), \
-       HWSEQ_PHYPLL_REG_LIST_302(OTG), \
-       SR(AZALIA_AUDIO_DTO), \
-       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
-       SR(HPO_TOP_CLOCK_CONTROL)
-
-#define HWSEQ_DCN303_REG_LIST() \
-       HWSEQ_DCN_REG_LIST(), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
-       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
-       SR(MICROSECOND_TIME_BASE_DIV), \
-       SR(MILLISECOND_TIME_BASE_DIV), \
-       SR(DISPCLK_FREQ_CHANGE_CNTL), \
-       SR(RBBMIF_TIMEOUT_DIS), \
-       SR(RBBMIF_TIMEOUT_DIS_2), \
-       SR(DCHUBBUB_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_CTRL), \
-       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
-       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
-       SR(MPC_CRC_CTRL), \
-       SR(MPC_CRC_RESULT_GB), \
-       SR(MPC_CRC_RESULT_C), \
-       SR(MPC_CRC_RESULT_AR), \
-       SR(D1VGA_CONTROL), \
-       SR(D2VGA_CONTROL), \
-       SR(D3VGA_CONTROL), \
-       SR(D4VGA_CONTROL), \
-       SR(D5VGA_CONTROL), \
-       SR(D6VGA_CONTROL), \
-       HWSEQ_PIXEL_RATE_REG_LIST_303(OTG), \
-       HWSEQ_PHYPLL_REG_LIST_303(OTG), \
-       SR(AZALIA_AUDIO_DTO), \
-       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
-       SR(HPO_TOP_CLOCK_CONTROL)
-
-struct dce_hwseq_registers {
-       uint32_t DCFE_CLOCK_CONTROL[6];
-       uint32_t DCFEV_CLOCK_CONTROL;
-       uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
-       uint32_t BLND_V_UPDATE_LOCK[6];
-       uint32_t BLND_CONTROL[6];
-       uint32_t BLNDV_CONTROL;
-       uint32_t CRTC_H_BLANK_START_END[6];
-       uint32_t PIXEL_RATE_CNTL[6];
-       uint32_t PHYPLL_PIXEL_RATE_CNTL[6];
-       /*DCHUB*/
-       uint32_t DCHUB_FB_LOCATION;
-       uint32_t DCHUB_AGP_BASE;
-       uint32_t DCHUB_AGP_BOT;
-       uint32_t DCHUB_AGP_TOP;
-
-       uint32_t REFCLK_CNTL;
-
-       uint32_t DCHUBBUB_GLOBAL_TIMER_CNTL;
-       uint32_t DCHUBBUB_SDPIF_FB_BASE;
-       uint32_t DCHUBBUB_SDPIF_FB_OFFSET;
-       uint32_t DCHUBBUB_SDPIF_AGP_BASE;
-       uint32_t DCHUBBUB_SDPIF_AGP_BOT;
-       uint32_t DCHUBBUB_SDPIF_AGP_TOP;
-       uint32_t DC_IP_REQUEST_CNTL;
-       uint32_t DOMAIN0_PG_CONFIG;
-       uint32_t DOMAIN1_PG_CONFIG;
-       uint32_t DOMAIN2_PG_CONFIG;
-       uint32_t DOMAIN3_PG_CONFIG;
-       uint32_t DOMAIN4_PG_CONFIG;
-       uint32_t DOMAIN5_PG_CONFIG;
-       uint32_t DOMAIN6_PG_CONFIG;
-       uint32_t DOMAIN7_PG_CONFIG;
-       uint32_t DOMAIN8_PG_CONFIG;
-       uint32_t DOMAIN9_PG_CONFIG;
-       uint32_t DOMAIN10_PG_CONFIG;
-       uint32_t DOMAIN11_PG_CONFIG;
-       uint32_t DOMAIN16_PG_CONFIG;
-       uint32_t DOMAIN17_PG_CONFIG;
-       uint32_t DOMAIN18_PG_CONFIG;
-       uint32_t DOMAIN19_PG_CONFIG;
-       uint32_t DOMAIN20_PG_CONFIG;
-       uint32_t DOMAIN21_PG_CONFIG;
-       uint32_t DOMAIN0_PG_STATUS;
-       uint32_t DOMAIN1_PG_STATUS;
-       uint32_t DOMAIN2_PG_STATUS;
-       uint32_t DOMAIN3_PG_STATUS;
-       uint32_t DOMAIN4_PG_STATUS;
-       uint32_t DOMAIN5_PG_STATUS;
-       uint32_t DOMAIN6_PG_STATUS;
-       uint32_t DOMAIN7_PG_STATUS;
-       uint32_t DOMAIN8_PG_STATUS;
-       uint32_t DOMAIN9_PG_STATUS;
-       uint32_t DOMAIN10_PG_STATUS;
-       uint32_t DOMAIN11_PG_STATUS;
-       uint32_t DOMAIN16_PG_STATUS;
-       uint32_t DOMAIN17_PG_STATUS;
-       uint32_t DOMAIN18_PG_STATUS;
-       uint32_t DOMAIN19_PG_STATUS;
-       uint32_t DOMAIN20_PG_STATUS;
-       uint32_t DOMAIN21_PG_STATUS;
-       uint32_t DIO_MEM_PWR_CTRL;
-       uint32_t DCCG_GATE_DISABLE_CNTL;
-       uint32_t DCCG_GATE_DISABLE_CNTL2;
-       uint32_t DCFCLK_CNTL;
-       uint32_t MICROSECOND_TIME_BASE_DIV;
-       uint32_t MILLISECOND_TIME_BASE_DIV;
-       uint32_t DISPCLK_FREQ_CHANGE_CNTL;
-       uint32_t RBBMIF_TIMEOUT_DIS;
-       uint32_t RBBMIF_TIMEOUT_DIS_2;
-       uint32_t DCHUBBUB_CRC_CTRL;
-       uint32_t DPP_TOP0_DPP_CRC_CTRL;
-       uint32_t DPP_TOP0_DPP_CRC_VAL_R_G;
-       uint32_t DPP_TOP0_DPP_CRC_VAL_B_A;
-       uint32_t MPC_CRC_CTRL;
-       uint32_t MPC_CRC_RESULT_GB;
-       uint32_t MPC_CRC_RESULT_C;
-       uint32_t MPC_CRC_RESULT_AR;
-       uint32_t D1VGA_CONTROL;
-       uint32_t D2VGA_CONTROL;
-       uint32_t D3VGA_CONTROL;
-       uint32_t D4VGA_CONTROL;
-       uint32_t D5VGA_CONTROL;
-       uint32_t D6VGA_CONTROL;
-       uint32_t VGA_TEST_CONTROL;
-       /* MMHUB registers. read only. temporary hack */
-       uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32;
-       uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
-       uint32_t VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32;
-       uint32_t VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32;
-       uint32_t VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32;
-       uint32_t VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32;
-       uint32_t VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32;
-       uint32_t VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32;
-       uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;
-       uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;
-       uint32_t MC_VM_SYSTEM_APERTURE_LOW_ADDR;
-       uint32_t MC_VM_SYSTEM_APERTURE_HIGH_ADDR;
-       uint32_t MC_VM_XGMI_LFB_CNTL;
-       uint32_t AZALIA_AUDIO_DTO;
-       uint32_t AZALIA_CONTROLLER_CLOCK_GATING;
-       /* MMHUB VM */
-       uint32_t MC_VM_FB_LOCATION_BASE;
-       uint32_t MC_VM_FB_LOCATION_TOP;
-       uint32_t MC_VM_FB_OFFSET;
-       uint32_t MMHUBBUB_MEM_PWR_CNTL;
-       uint32_t HPO_TOP_CLOCK_CONTROL;
-       uint32_t ODM_MEM_PWR_CTRL3;
-       uint32_t DMU_MEM_PWR_CNTL;
-       uint32_t DCHUBBUB_ARB_HOSTVM_CNTL;
-       uint32_t HPO_TOP_HW_CONTROL;
-       uint32_t DMU_CLK_CNTL;
-       uint32_t DCCG_GATE_DISABLE_CNTL5;
-};
- /* set field name */
-#define HWS_SF(blk_name, reg_name, field_name, post_fix)\
-       .field_name = blk_name ## reg_name ## __ ## field_name ## post_fix
-
-#define HWS_SF1(blk_name, reg_name, field_name, post_fix)\
-       .field_name = blk_name ## reg_name ## __ ## blk_name ## field_name ## post_fix
-
-
-#define HWSEQ_DCEF_MASK_SH_LIST(mask_sh, blk)\
-       HWS_SF(blk, CLOCK_CONTROL, DCFE_CLOCK_ENABLE, mask_sh),\
-       SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
-
-#define HWSEQ_BLND_MASK_SH_LIST(mask_sh, blk)\
-       HWS_SF(blk, V_UPDATE_LOCK, BLND_DCP_GRPH_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(blk, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(blk, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(blk, V_UPDATE_LOCK, BLND_BLND_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(blk, V_UPDATE_LOCK, BLND_V_UPDATE_LOCK_MODE, mask_sh),\
-       HWS_SF(blk, CONTROL, BLND_FEEDTHROUGH_EN, mask_sh),\
-       HWS_SF(blk, CONTROL, BLND_ALPHA_MODE, mask_sh),\
-       HWS_SF(blk, CONTROL, BLND_MODE, mask_sh),\
-       HWS_SF(blk, CONTROL, BLND_MULTIPLIED_MODE, mask_sh)
-
-#define HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, blk)\
-       HWS_SF1(blk, PIXEL_RATE_CNTL, PIXEL_RATE_SOURCE, mask_sh),\
-       HWS_SF(blk, PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh)
-
-#define HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, blk)\
-       HWS_SF1(blk, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh),\
-       HWS_SF1(blk, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh)
-
-#if defined(CONFIG_DRM_AMD_DC_SI)
-#define HWSEQ_DCE6_MASK_SH_LIST(mask_sh)\
-       .DCFE_CLOCK_ENABLE = CRTC_DCFE_CLOCK_CONTROL__CRTC_DCFE_CLOCK_ENABLE ## mask_sh, \
-       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
-#endif
-
-#define HWSEQ_DCE8_MASK_SH_LIST(mask_sh)\
-       .DCFE_CLOCK_ENABLE = CRTC_DCFE_CLOCK_CONTROL__CRTC_DCFE_CLOCK_ENABLE ## mask_sh, \
-       HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
-       HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
-       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
-
-#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
-       HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
-       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
-
-#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
-       SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
-       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
-
-#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
-       HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
-
-#define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\
-       SF(DCHUB_FB_LOCATION, FB_TOP, mask_sh),\
-       SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\
-       SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\
-       SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\
-       SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh)
-
-#define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\
-       HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\
-       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\
-       HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\
-       HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)
-
-#define HWSEQ_VG20_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCE12_MASK_SH_LIST(mask_sh),\
-       HWS_SF(, MC_VM_XGMI_LFB_CNTL, PF_LFB_REGION, mask_sh),\
-       HWS_SF(, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION, mask_sh)
-
-#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
-       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
-       HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
-       HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh), \
-       HWS_SF(, DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
-
-#define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh), \
-       HWS_SF(, DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh), \
-       HWS_SF(, DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh), \
-       HWS_SF(, DCHUBBUB_SDPIF_AGP_BASE, SDPIF_AGP_BASE, mask_sh), \
-       HWS_SF(, DCHUBBUB_SDPIF_AGP_BOT, SDPIF_AGP_BOT, mask_sh), \
-       HWS_SF(, DCHUBBUB_SDPIF_AGP_TOP, SDPIF_AGP_TOP, mask_sh), \
-       /* todo:  get these from GVM instead of reading registers ourselves */\
-       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
-       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
-       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, LOGICAL_PAGE_NUMBER_HI4, mask_sh),\
-       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, LOGICAL_PAGE_NUMBER_LO32, mask_sh),\
-       HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, PHYSICAL_PAGE_ADDR_HI4, mask_sh),\
-       HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
-       HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
-       HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
-       HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
-       HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\
-       HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\
-       HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\
-       HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\
-       HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\
-       HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh)
-
-#define HWSEQ_DCN2_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN10_PG_CONFIG, DOMAIN10_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN10_PG_CONFIG, DOMAIN10_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN11_PG_CONFIG, DOMAIN11_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN11_PG_CONFIG, DOMAIN11_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN21_PG_CONFIG, DOMAIN21_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN8_PG_STATUS, DOMAIN8_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN9_PG_STATUS, DOMAIN9_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN10_PG_STATUS, DOMAIN10_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN11_PG_STATUS, DOMAIN11_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN21_PG_STATUS, DOMAIN21_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh)
-
-#define HWSEQ_DCN21_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
-       HWS_SF(, MMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
-       HWS_SF(, MMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh)
-
-#define HWSEQ_DCN201_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
-       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh)
-
-#define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
-       HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh), \
-       HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
-       HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
-       HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \
-       HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh)
-
-#define HWSEQ_DCN301_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
-       HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_BLON, mask_sh),\
-       HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON, mask_sh),\
-       HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON_OVRD, mask_sh),\
-       HWS_SF(, PANEL_PWRSEQ0_STATE, PANEL_PWRSEQ_TARGET_STATE_R, mask_sh),\
-       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh)
-
-#define HWSEQ_DCN302_MASK_SH_LIST(mask_sh)\
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, mask_sh), \
-       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_GATE, mask_sh), \
-       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN8_PG_STATUS, DOMAIN8_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN9_PG_STATUS, DOMAIN9_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \
-       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
-       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
-       HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh)
-
-#define HWSEQ_DCN303_MASK_SH_LIST(mask_sh) \
-       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
-       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
-       HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh)
-
-#define HWSEQ_REG_FIELD_LIST(type) \
-       type DCFE_CLOCK_ENABLE; \
-       type DCFEV_CLOCK_ENABLE; \
-       type DC_MEM_GLOBAL_PWR_REQ_DIS; \
-       type BLND_DCP_GRPH_V_UPDATE_LOCK; \
-       type BLND_SCL_V_UPDATE_LOCK; \
-       type BLND_DCP_GRPH_SURF_V_UPDATE_LOCK; \
-       type BLND_BLND_V_UPDATE_LOCK; \
-       type BLND_V_UPDATE_LOCK_MODE; \
-       type BLND_FEEDTHROUGH_EN; \
-       type BLND_ALPHA_MODE; \
-       type BLND_MODE; \
-       type BLND_MULTIPLIED_MODE; \
-       type DP_DTO0_ENABLE; \
-       type PIXEL_RATE_SOURCE; \
-       type PHYPLL_PIXEL_RATE_SOURCE; \
-       type PIXEL_RATE_PLL_SOURCE; \
-       /* todo:  get these from GVM instead of reading registers ourselves */\
-       type PAGE_DIRECTORY_ENTRY_HI32;\
-       type PAGE_DIRECTORY_ENTRY_LO32;\
-       type LOGICAL_PAGE_NUMBER_HI4;\
-       type LOGICAL_PAGE_NUMBER_LO32;\
-       type PHYSICAL_PAGE_ADDR_HI4;\
-       type PHYSICAL_PAGE_ADDR_LO32;\
-       type PHYSICAL_PAGE_NUMBER_MSB;\
-       type PHYSICAL_PAGE_NUMBER_LSB;\
-       type LOGICAL_ADDR; \
-       type PF_LFB_REGION;\
-       type PF_MAX_REGION;\
-       type ENABLE_L1_TLB;\
-       type SYSTEM_ACCESS_MODE;
-
-#define HWSEQ_DCN_REG_FIELD_LIST(type) \
-       type HUBP_VTG_SEL; \
-       type HUBP_CLOCK_ENABLE; \
-       type DPP_CLOCK_ENABLE; \
-       type SDPIF_FB_BASE;\
-       type SDPIF_FB_OFFSET;\
-       type SDPIF_AGP_BASE;\
-       type SDPIF_AGP_BOT;\
-       type SDPIF_AGP_TOP;\
-       type FB_TOP;\
-       type FB_BASE;\
-       type FB_OFFSET;\
-       type AGP_BASE;\
-       type AGP_BOT;\
-       type AGP_TOP;\
-       type DCHUBBUB_GLOBAL_TIMER_ENABLE; \
-       type OPP_PIPE_CLOCK_EN;\
-       type IP_REQUEST_EN; \
-       type DOMAIN0_POWER_FORCEON; \
-       type DOMAIN0_POWER_GATE; \
-       type DOMAIN1_POWER_FORCEON; \
-       type DOMAIN1_POWER_GATE; \
-       type DOMAIN2_POWER_FORCEON; \
-       type DOMAIN2_POWER_GATE; \
-       type DOMAIN3_POWER_FORCEON; \
-       type DOMAIN3_POWER_GATE; \
-       type DOMAIN4_POWER_FORCEON; \
-       type DOMAIN4_POWER_GATE; \
-       type DOMAIN5_POWER_FORCEON; \
-       type DOMAIN5_POWER_GATE; \
-       type DOMAIN6_POWER_FORCEON; \
-       type DOMAIN6_POWER_GATE; \
-       type DOMAIN7_POWER_FORCEON; \
-       type DOMAIN7_POWER_GATE; \
-       type DOMAIN8_POWER_FORCEON; \
-       type DOMAIN8_POWER_GATE; \
-       type DOMAIN9_POWER_FORCEON; \
-       type DOMAIN9_POWER_GATE; \
-       type DOMAIN10_POWER_FORCEON; \
-       type DOMAIN10_POWER_GATE; \
-       type DOMAIN11_POWER_FORCEON; \
-       type DOMAIN11_POWER_GATE; \
-       type DOMAIN16_POWER_FORCEON; \
-       type DOMAIN16_POWER_GATE; \
-       type DOMAIN17_POWER_FORCEON; \
-       type DOMAIN17_POWER_GATE; \
-       type DOMAIN18_POWER_FORCEON; \
-       type DOMAIN18_POWER_GATE; \
-       type DOMAIN19_POWER_FORCEON; \
-       type DOMAIN19_POWER_GATE; \
-       type DOMAIN20_POWER_FORCEON; \
-       type DOMAIN20_POWER_GATE; \
-       type DOMAIN21_POWER_FORCEON; \
-       type DOMAIN21_POWER_GATE; \
-       type DOMAIN0_PGFSM_PWR_STATUS; \
-       type DOMAIN1_PGFSM_PWR_STATUS; \
-       type DOMAIN2_PGFSM_PWR_STATUS; \
-       type DOMAIN3_PGFSM_PWR_STATUS; \
-       type DOMAIN4_PGFSM_PWR_STATUS; \
-       type DOMAIN5_PGFSM_PWR_STATUS; \
-       type DOMAIN6_PGFSM_PWR_STATUS; \
-       type DOMAIN7_PGFSM_PWR_STATUS; \
-       type DOMAIN8_PGFSM_PWR_STATUS; \
-       type DOMAIN9_PGFSM_PWR_STATUS; \
-       type DOMAIN10_PGFSM_PWR_STATUS; \
-       type DOMAIN11_PGFSM_PWR_STATUS; \
-       type DOMAIN16_PGFSM_PWR_STATUS; \
-       type DOMAIN17_PGFSM_PWR_STATUS; \
-       type DOMAIN18_PGFSM_PWR_STATUS; \
-       type DOMAIN19_PGFSM_PWR_STATUS; \
-       type DOMAIN20_PGFSM_PWR_STATUS; \
-       type DOMAIN21_PGFSM_PWR_STATUS; \
-       type DCFCLK_GATE_DIS; \
-       type DCHUBBUB_GLOBAL_TIMER_REFDIV; \
-       type VGA_TEST_ENABLE; \
-       type VGA_TEST_RENDER_START; \
-       type D1VGA_MODE_ENABLE; \
-       type D2VGA_MODE_ENABLE; \
-       type D3VGA_MODE_ENABLE; \
-       type D4VGA_MODE_ENABLE; \
-       type AZALIA_AUDIO_DTO_MODULE; \
-       type ODM_MEM_UNASSIGNED_PWR_MODE; \
-       type ODM_MEM_VBLANK_PWR_MODE; \
-       type DMCU_ERAM_MEM_PWR_FORCE; \
-       type VGA_MEM_PWR_FORCE;
-
-#define HWSEQ_DCN3_REG_FIELD_LIST(type) \
-       type HPO_HDMISTREAMCLK_GATE_DIS;
-
-#define HWSEQ_DCN301_REG_FIELD_LIST(type) \
-       type PANEL_BLON;\
-       type PANEL_DIGON;\
-       type PANEL_DIGON_OVRD;\
-       type PANEL_PWRSEQ_TARGET_STATE_R;
-
-#define HWSEQ_DCN31_REG_FIELD_LIST(type) \
-       type DOMAIN_POWER_FORCEON;\
-       type DOMAIN_POWER_GATE;\
-       type DOMAIN_PGFSM_PWR_STATUS;\
-       type HPO_HDMISTREAMCLK_G_GATE_DIS;\
-       type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;\
-       type I2C_LIGHT_SLEEP_FORCE;\
-       type HPO_IO_EN;
-
-#define HWSEQ_DCN35_REG_FIELD_LIST(type) \
-       type DISPCLK_R_DMU_GATE_DIS;\
-       type DISPCLK_G_RBBMIF_GATE_DIS;\
-       type RBBMIF_FGCG_REP_DIS;\
-       type IHC_FGCG_REP_DIS;\
-       type DPREFCLK_ALLOW_DS_CLKSTOP;\
-       type DISPCLK_ALLOW_DS_CLKSTOP;\
-       type DPPCLK_ALLOW_DS_CLKSTOP;\
-       type DTBCLK_ALLOW_DS_CLKSTOP;\
-       type DCFCLK_ALLOW_DS_CLKSTOP;\
-       type DPIACLK_ALLOW_DS_CLKSTOP;\
-       type LONO_FGCG_REP_DIS;\
-       type LONO_DISPCLK_GATE_DISABLE;\
-       type LONO_SOCCLK_GATE_DISABLE;\
-       type LONO_DMCUBCLK_GATE_DISABLE;
-
-struct dce_hwseq_shift {
-       HWSEQ_REG_FIELD_LIST(uint8_t)
-       HWSEQ_DCN_REG_FIELD_LIST(uint8_t)
-       HWSEQ_DCN3_REG_FIELD_LIST(uint8_t)
-       HWSEQ_DCN301_REG_FIELD_LIST(uint8_t)
-       HWSEQ_DCN31_REG_FIELD_LIST(uint8_t)
-       HWSEQ_DCN35_REG_FIELD_LIST(uint8_t)
-};
-
-struct dce_hwseq_mask {
-       HWSEQ_REG_FIELD_LIST(uint32_t)
-       HWSEQ_DCN_REG_FIELD_LIST(uint32_t)
-       HWSEQ_DCN3_REG_FIELD_LIST(uint32_t)
-       HWSEQ_DCN301_REG_FIELD_LIST(uint32_t)
-       HWSEQ_DCN31_REG_FIELD_LIST(uint32_t)
-       HWSEQ_DCN35_REG_FIELD_LIST(uint32_t)
-};
-
-
-enum blnd_mode {
-       BLND_MODE_CURRENT_PIPE = 0,/* Data from current pipe only */
-       BLND_MODE_OTHER_PIPE, /* Data from other pipe only */
-       BLND_MODE_BLENDING,/* Alpha blending - blend 'current' and 'other' */
-};
-
-struct dce_hwseq;
-struct pipe_ctx;
-struct clock_source;
-
-void dce_enable_fe_clock(struct dce_hwseq *hwss,
-               unsigned int inst, bool enable);
-
-void dce_pipe_control_lock(struct dc *dc,
-               struct pipe_ctx *pipe,
-               bool lock);
-
-void dce_set_blender_mode(struct dce_hwseq *hws,
-       unsigned int blnd_inst, enum blnd_mode mode);
-
-#if defined(CONFIG_DRM_AMD_DC_SI)
-void dce60_pipe_control_lock(struct dc *dc,
-               struct pipe_ctx *pipe,
-               bool lock);
-#endif
-
-void dce_clock_gating_power_up(struct dce_hwseq *hws,
-               bool enable);
-
-void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
-               struct clock_source *clk_src,
-               unsigned int tg_inst);
-
-bool dce_use_lut(enum surface_pixel_format format);
-#endif   /*__DCE_HWSEQ_H__*/
index ff20c47..0d2f6bb 100644 (file)
@@ -25,7 +25,7 @@
 
 CFLAGS_$(AMDDALPATH)/dc/dce100/dce100_resource.o = $(call cc-disable-warning, override-init)
 
-DCE100 = dce100_resource.o dce100_hw_sequencer.o
+DCE100 = dce100_resource.o
 
 AMD_DAL_DCE100 = $(addprefix $(AMDDALPATH)/dc/dce100/,$(DCE100))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c
deleted file mode 100644 (file)
index 753cb8e..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2015 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 "dm_services.h"
-#include "dc.h"
-#include "core_types.h"
-#include "clk_mgr.h"
-#include "dce100_hw_sequencer.h"
-#include "resource.h"
-
-#include "dce110/dce110_hw_sequencer.h"
-
-/* include DCE10 register header files */
-#include "dce/dce_10_0_d.h"
-#include "dce/dce_10_0_sh_mask.h"
-
-struct dce100_hw_seq_reg_offsets {
-       uint32_t blnd;
-       uint32_t crtc;
-};
-
-static const struct dce100_hw_seq_reg_offsets reg_offsets[] = {
-{
-       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-}
-};
-
-#define HW_REG_CRTC(reg, id)\
-       (reg + reg_offsets[id].crtc)
-
-/*******************************************************************************
- * Private definitions
- ******************************************************************************/
-/***************************PIPE_CONTROL***********************************/
-
-bool dce100_enable_display_power_gating(
-       struct dc *dc,
-       uint8_t controller_id,
-       struct dc_bios *dcb,
-       enum pipe_gating_control power_gating)
-{
-       enum bp_result bp_result = BP_RESULT_OK;
-       enum bp_pipe_control_action cntl;
-       struct dc_context *ctx = dc->ctx;
-
-       if (power_gating == PIPE_GATING_CONTROL_INIT)
-               cntl = ASIC_PIPE_INIT;
-       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
-               cntl = ASIC_PIPE_ENABLE;
-       else
-               cntl = ASIC_PIPE_DISABLE;
-
-       if (!(power_gating == PIPE_GATING_CONTROL_INIT && controller_id != 0)){
-
-               bp_result = dcb->funcs->enable_disp_power_gating(
-                                               dcb, controller_id + 1, cntl);
-
-               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
-                * by default when command table is called
-                */
-               dm_write_reg(ctx,
-                       HW_REG_CRTC(mmMASTER_UPDATE_MODE, controller_id),
-                       0);
-       }
-
-       if (bp_result == BP_RESULT_OK)
-               return true;
-       else
-               return false;
-}
-
-void dce100_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       false);
-}
-
-void dce100_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       true);
-}
-
-/**************************************************************************/
-
-void dce100_hw_sequencer_construct(struct dc *dc)
-{
-       dce110_hw_sequencer_construct(dc);
-
-       dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
-       dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
-       dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h
deleted file mode 100644 (file)
index 34518da..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-* 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_HWSS_DCE100_H__
-#define __DC_HWSS_DCE100_H__
-
-#include "core_types.h"
-#include "hw_sequencer_private.h"
-
-struct dc;
-struct dc_state;
-
-void dce100_hw_sequencer_construct(struct dc *dc);
-
-void dce100_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-
-void dce100_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-
-bool dce100_enable_display_power_gating(struct dc *dc, uint8_t controller_id,
-                                       struct dc_bios *dcb,
-                                       enum pipe_gating_control power_gating);
-
-#endif /* __DC_HWSS_DCE100_H__ */
-
index 899b25b..53a5f4c 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "resource.h"
 #include "include/irq_service_interface.h"
-#include "../virtual/virtual_stream_encoder.h"
+#include "virtual/virtual_stream_encoder.h"
 #include "dce110/dce110_resource.h"
 #include "dce110/dce110_timing_generator.h"
 #include "irq/dce110/irq_service_dce110.h"
@@ -43,7 +43,7 @@
 #include "dce/dce_clock_source.h"
 #include "dce/dce_audio.h"
 #include "dce/dce_hwseq.h"
-#include "dce100/dce100_hw_sequencer.h"
+#include "dce100/dce100_hwseq.h"
 #include "dce/dce_panel_cntl.h"
 
 #include "reg_helper.h"
index 84ab48d..695a50e 100644 (file)
@@ -26,7 +26,7 @@
 CFLAGS_$(AMDDALPATH)/dc/dce110/dce110_resource.o = $(call cc-disable-warning, override-init)
 
 DCE110 = dce110_timing_generator.o \
-dce110_compressor.o dce110_hw_sequencer.o dce110_resource.o \
+dce110_compressor.o dce110_resource.o \
 dce110_opp_regamma_v.o dce110_opp_csc_v.o dce110_timing_generator_v.o \
 dce110_mem_input_v.o dce110_opp_v.o dce110_transform_v.o
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
deleted file mode 100644 (file)
index 5e4e9c1..0000000
+++ /dev/null
@@ -1,3200 +0,0 @@
-/*
- * Copyright 2015 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 "dm_services.h"
-#include "dc.h"
-#include "dc_bios_types.h"
-#include "core_types.h"
-#include "core_status.h"
-#include "resource.h"
-#include "dm_helpers.h"
-#include "dce110_timing_generator.h"
-#include "dce/dce_hwseq.h"
-#include "gpio_service_interface.h"
-
-#include "dce110_compressor.h"
-
-#include "bios/bios_parser_helper.h"
-#include "timing_generator.h"
-#include "mem_input.h"
-#include "opp.h"
-#include "ipp.h"
-#include "transform.h"
-#include "stream_encoder.h"
-#include "link_encoder.h"
-#include "link_enc_cfg.h"
-#include "link_hwss.h"
-#include "link.h"
-#include "dccg.h"
-#include "clock_source.h"
-#include "clk_mgr.h"
-#include "abm.h"
-#include "audio.h"
-#include "reg_helper.h"
-#include "panel_cntl.h"
-#include "dpcd_defs.h"
-/* include DCE11 register header files */
-#include "dce/dce_11_0_d.h"
-#include "dce/dce_11_0_sh_mask.h"
-#include "custom_float.h"
-
-#include "atomfirmware.h"
-
-#include "dcn10/dcn10_hw_sequencer.h"
-
-#include "dce110_hw_sequencer.h"
-
-#define GAMMA_HW_POINTS_NUM 256
-
-/*
- * All values are in milliseconds;
- * For eDP, after power-up/power/down,
- * 300/500 msec max. delay from LCDVCC to black video generation
- */
-#define PANEL_POWER_UP_TIMEOUT 300
-#define PANEL_POWER_DOWN_TIMEOUT 500
-#define HPD_CHECK_INTERVAL 10
-#define OLED_POST_T7_DELAY 100
-#define OLED_PRE_T11_DELAY 150
-
-#define CTX \
-       hws->ctx
-
-#define DC_LOGGER \
-       ctx->logger
-#define DC_LOGGER_INIT() \
-       struct dc_context *ctx = dc->ctx
-
-#define REG(reg)\
-       hws->regs->reg
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-
-struct dce110_hw_seq_reg_offsets {
-       uint32_t crtc;
-};
-
-static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
-{
-       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-}
-};
-
-#define HW_REG_BLND(reg, id)\
-       (reg + reg_offsets[id].blnd)
-
-#define HW_REG_CRTC(reg, id)\
-       (reg + reg_offsets[id].crtc)
-
-#define MAX_WATERMARK 0xFFFF
-#define SAFE_NBP_MARK 0x7FFF
-
-/*******************************************************************************
- * Private definitions
- ******************************************************************************/
-/***************************PIPE_CONTROL***********************************/
-static void dce110_init_pte(struct dc_context *ctx)
-{
-       uint32_t addr;
-       uint32_t value = 0;
-       uint32_t chunk_int = 0;
-       uint32_t chunk_mul = 0;
-
-       addr = mmUNP_DVMM_PTE_CONTROL;
-       value = dm_read_reg(ctx, addr);
-
-       set_reg_field_value(
-               value,
-               0,
-               DVMM_PTE_CONTROL,
-               DVMM_USE_SINGLE_PTE);
-
-       set_reg_field_value(
-               value,
-               1,
-               DVMM_PTE_CONTROL,
-               DVMM_PTE_BUFFER_MODE0);
-
-       set_reg_field_value(
-               value,
-               1,
-               DVMM_PTE_CONTROL,
-               DVMM_PTE_BUFFER_MODE1);
-
-       dm_write_reg(ctx, addr, value);
-
-       addr = mmDVMM_PTE_REQ;
-       value = dm_read_reg(ctx, addr);
-
-       chunk_int = get_reg_field_value(
-               value,
-               DVMM_PTE_REQ,
-               HFLIP_PTEREQ_PER_CHUNK_INT);
-
-       chunk_mul = get_reg_field_value(
-               value,
-               DVMM_PTE_REQ,
-               HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-
-       if (chunk_int != 0x4 || chunk_mul != 0x4) {
-
-               set_reg_field_value(
-                       value,
-                       255,
-                       DVMM_PTE_REQ,
-                       MAX_PTEREQ_TO_ISSUE);
-
-               set_reg_field_value(
-                       value,
-                       4,
-                       DVMM_PTE_REQ,
-                       HFLIP_PTEREQ_PER_CHUNK_INT);
-
-               set_reg_field_value(
-                       value,
-                       4,
-                       DVMM_PTE_REQ,
-                       HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-
-               dm_write_reg(ctx, addr, value);
-       }
-}
-/**************************************************************************/
-
-static void enable_display_pipe_clock_gating(
-       struct dc_context *ctx,
-       bool clock_gating)
-{
-       /*TODO*/
-}
-
-static bool dce110_enable_display_power_gating(
-       struct dc *dc,
-       uint8_t controller_id,
-       struct dc_bios *dcb,
-       enum pipe_gating_control power_gating)
-{
-       enum bp_result bp_result = BP_RESULT_OK;
-       enum bp_pipe_control_action cntl;
-       struct dc_context *ctx = dc->ctx;
-       unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
-
-       if (power_gating == PIPE_GATING_CONTROL_INIT)
-               cntl = ASIC_PIPE_INIT;
-       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
-               cntl = ASIC_PIPE_ENABLE;
-       else
-               cntl = ASIC_PIPE_DISABLE;
-
-       if (controller_id == underlay_idx)
-               controller_id = CONTROLLER_ID_UNDERLAY0 - 1;
-
-       if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
-
-               bp_result = dcb->funcs->enable_disp_power_gating(
-                                               dcb, controller_id + 1, cntl);
-
-               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
-                * by default when command table is called
-                *
-                * Bios parser accepts controller_id = 6 as indicative of
-                * underlay pipe in dce110. But we do not support more
-                * than 3.
-                */
-               if (controller_id < CONTROLLER_ID_MAX - 1)
-                       dm_write_reg(ctx,
-                               HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
-                               0);
-       }
-
-       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
-               dce110_init_pte(ctx);
-
-       if (bp_result == BP_RESULT_OK)
-               return true;
-       else
-               return false;
-}
-
-static void build_prescale_params(struct ipp_prescale_params *prescale_params,
-               const struct dc_plane_state *plane_state)
-{
-       prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
-
-       switch (plane_state->format) {
-       case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
-               prescale_params->scale = 0x2082;
-               break;
-       case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
-       case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
-               prescale_params->scale = 0x2020;
-               break;
-       case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
-       case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
-               prescale_params->scale = 0x2008;
-               break;
-       case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
-       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
-               prescale_params->scale = 0x2000;
-               break;
-       default:
-               ASSERT(false);
-               break;
-       }
-}
-
-static bool
-dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                              const struct dc_plane_state *plane_state)
-{
-       struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
-       const struct dc_transfer_func *tf = NULL;
-       struct ipp_prescale_params prescale_params = { 0 };
-       bool result = true;
-
-       if (ipp == NULL)
-               return false;
-
-       if (plane_state->in_transfer_func)
-               tf = plane_state->in_transfer_func;
-
-       build_prescale_params(&prescale_params, plane_state);
-       ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
-
-       if (plane_state->gamma_correction &&
-                       !plane_state->gamma_correction->is_identity &&
-                       dce_use_lut(plane_state->format))
-               ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
-
-       if (tf == NULL) {
-               /* Default case if no input transfer function specified */
-               ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
-       } else if (tf->type == TF_TYPE_PREDEFINED) {
-               switch (tf->tf) {
-               case TRANSFER_FUNCTION_SRGB:
-                       ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
-                       break;
-               case TRANSFER_FUNCTION_BT709:
-                       ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC);
-                       break;
-               case TRANSFER_FUNCTION_LINEAR:
-                       ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
-                       break;
-               case TRANSFER_FUNCTION_PQ:
-               default:
-                       result = false;
-                       break;
-               }
-       } else if (tf->type == TF_TYPE_BYPASS) {
-               ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
-       } else {
-               /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
-               result = false;
-       }
-
-       return result;
-}
-
-static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted,
-                                   struct curve_points *arr_points,
-                                   uint32_t hw_points_num)
-{
-       struct custom_float_format fmt;
-
-       struct pwl_result_data *rgb = rgb_resulted;
-
-       uint32_t i = 0;
-
-       fmt.exponenta_bits = 6;
-       fmt.mantissa_bits = 12;
-       fmt.sign = true;
-
-       if (!convert_to_custom_float_format(arr_points[0].x, &fmt,
-                                           &arr_points[0].custom_float_x)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(arr_points[0].offset, &fmt,
-                                           &arr_points[0].custom_float_offset)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(arr_points[0].slope, &fmt,
-                                           &arr_points[0].custom_float_slope)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       fmt.mantissa_bits = 10;
-       fmt.sign = false;
-
-       if (!convert_to_custom_float_format(arr_points[1].x, &fmt,
-                                           &arr_points[1].custom_float_x)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
-                                           &arr_points[1].custom_float_y)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
-                                           &arr_points[1].custom_float_slope)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       fmt.mantissa_bits = 12;
-       fmt.sign = true;
-
-       while (i != hw_points_num) {
-               if (!convert_to_custom_float_format(rgb->red, &fmt,
-                                                   &rgb->red_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(rgb->green, &fmt,
-                                                   &rgb->green_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(rgb->blue, &fmt,
-                                                   &rgb->blue_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
-                                                   &rgb->delta_red_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
-                                                   &rgb->delta_green_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
-                                                   &rgb->delta_blue_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               ++rgb;
-               ++i;
-       }
-
-       return true;
-}
-
-#define MAX_LOW_POINT      25
-#define NUMBER_REGIONS     16
-#define NUMBER_SW_SEGMENTS 16
-
-static bool
-dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
-                                     struct pwl_params *regamma_params)
-{
-       struct curve_points *arr_points;
-       struct pwl_result_data *rgb_resulted;
-       struct pwl_result_data *rgb;
-       struct pwl_result_data *rgb_plus_1;
-       struct fixed31_32 y_r;
-       struct fixed31_32 y_g;
-       struct fixed31_32 y_b;
-       struct fixed31_32 y1_min;
-       struct fixed31_32 y3_max;
-
-       int32_t region_start, region_end;
-       uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points;
-
-       if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS)
-               return false;
-
-       arr_points = regamma_params->arr_points;
-       rgb_resulted = regamma_params->rgb_resulted;
-       hw_points = 0;
-
-       memset(regamma_params, 0, sizeof(struct pwl_params));
-
-       if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
-               /* 16 segments
-                * segments are from 2^-11 to 2^5
-                */
-               region_start = -11;
-               region_end = region_start + NUMBER_REGIONS;
-
-               for (i = 0; i < NUMBER_REGIONS; i++)
-                       seg_distr[i] = 4;
-
-       } else {
-               /* 10 segments
-                * segment is from 2^-10 to 2^1
-                * We include an extra segment for range [2^0, 2^1). This is to
-                * ensure that colors with normalized values of 1 don't miss the
-                * LUT.
-                */
-               region_start = -10;
-               region_end = 1;
-
-               seg_distr[0] = 4;
-               seg_distr[1] = 4;
-               seg_distr[2] = 4;
-               seg_distr[3] = 4;
-               seg_distr[4] = 4;
-               seg_distr[5] = 4;
-               seg_distr[6] = 4;
-               seg_distr[7] = 4;
-               seg_distr[8] = 4;
-               seg_distr[9] = 4;
-               seg_distr[10] = 0;
-               seg_distr[11] = -1;
-               seg_distr[12] = -1;
-               seg_distr[13] = -1;
-               seg_distr[14] = -1;
-               seg_distr[15] = -1;
-       }
-
-       for (k = 0; k < 16; k++) {
-               if (seg_distr[k] != -1)
-                       hw_points += (1 << seg_distr[k]);
-       }
-
-       j = 0;
-       for (k = 0; k < (region_end - region_start); k++) {
-               increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
-               start_index = (region_start + k + MAX_LOW_POINT) *
-                               NUMBER_SW_SEGMENTS;
-               for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
-                               i += increment) {
-                       if (j == hw_points - 1)
-                               break;
-                       rgb_resulted[j].red = output_tf->tf_pts.red[i];
-                       rgb_resulted[j].green = output_tf->tf_pts.green[i];
-                       rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
-                       j++;
-               }
-       }
-
-       /* last point */
-       start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
-       rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
-       rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
-       rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
-
-       arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
-                                            dc_fixpt_from_int(region_start));
-       arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
-                                            dc_fixpt_from_int(region_end));
-
-       y_r = rgb_resulted[0].red;
-       y_g = rgb_resulted[0].green;
-       y_b = rgb_resulted[0].blue;
-
-       y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
-
-       arr_points[0].y = y1_min;
-       arr_points[0].slope = dc_fixpt_div(arr_points[0].y,
-                                                arr_points[0].x);
-
-       y_r = rgb_resulted[hw_points - 1].red;
-       y_g = rgb_resulted[hw_points - 1].green;
-       y_b = rgb_resulted[hw_points - 1].blue;
-
-       /* see comment above, m_arrPoints[1].y should be the Y value for the
-        * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
-        */
-       y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
-
-       arr_points[1].y = y3_max;
-
-       arr_points[1].slope = dc_fixpt_zero;
-
-       if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
-               /* for PQ, we want to have a straight line from last HW X point,
-                * and the slope to be such that we hit 1.0 at 10000 nits.
-                */
-               const struct fixed31_32 end_value = dc_fixpt_from_int(125);
-
-               arr_points[1].slope = dc_fixpt_div(
-                               dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
-                               dc_fixpt_sub(end_value, arr_points[1].x));
-       }
-
-       regamma_params->hw_points_num = hw_points;
-
-       k = 0;
-       for (i = 1; i < 16; i++) {
-               if (seg_distr[k] != -1) {
-                       regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
-                       regamma_params->arr_curve_points[i].offset =
-                                       regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
-               }
-               k++;
-       }
-
-       if (seg_distr[k] != -1)
-               regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
-
-       rgb = rgb_resulted;
-       rgb_plus_1 = rgb_resulted + 1;
-
-       i = 1;
-
-       while (i != hw_points + 1) {
-               if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
-                       rgb_plus_1->red = rgb->red;
-               if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
-                       rgb_plus_1->green = rgb->green;
-               if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
-                       rgb_plus_1->blue = rgb->blue;
-
-               rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
-               rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
-               rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
-
-               ++rgb_plus_1;
-               ++rgb;
-               ++i;
-       }
-
-       convert_to_custom_float(rgb_resulted, arr_points, hw_points);
-
-       return true;
-}
-
-static bool
-dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream)
-{
-       struct transform *xfm = pipe_ctx->plane_res.xfm;
-
-       xfm->funcs->opp_power_on_regamma_lut(xfm, true);
-       xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
-
-       if (stream->out_transfer_func &&
-           stream->out_transfer_func->type == TF_TYPE_PREDEFINED &&
-           stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) {
-               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
-       } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func,
-                                                        &xfm->regamma_params)) {
-               xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
-               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
-       } else {
-               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
-       }
-
-       xfm->funcs->opp_power_on_regamma_lut(xfm, false);
-
-       return true;
-}
-
-void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
-{
-       bool is_hdmi_tmds;
-       bool is_dp;
-
-       ASSERT(pipe_ctx->stream);
-
-       if (pipe_ctx->stream_res.stream_enc == NULL)
-               return;  /* this is not root pipe */
-
-       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
-       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
-
-       if (!is_hdmi_tmds && !is_dp)
-               return;
-
-       if (is_hdmi_tmds)
-               pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
-                       pipe_ctx->stream_res.stream_enc,
-                       &pipe_ctx->stream_res.encoder_info_frame);
-       else {
-               if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)
-                       pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(
-                               pipe_ctx->stream_res.stream_enc,
-                               &pipe_ctx->stream_res.encoder_info_frame);
-
-               pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
-                       pipe_ctx->stream_res.stream_enc,
-                       &pipe_ctx->stream_res.encoder_info_frame);
-       }
-}
-
-void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
-{
-       enum dc_lane_count lane_count =
-               pipe_ctx->stream->link->cur_link_settings.lane_count;
-       struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
-       struct dc_link *link = pipe_ctx->stream->link;
-       const struct dc *dc = link->dc;
-       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
-       uint32_t active_total_with_borders;
-       uint32_t early_control = 0;
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-
-       link_hwss->setup_stream_encoder(pipe_ctx);
-
-       dc->hwss.update_info_frame(pipe_ctx);
-
-       /* enable early control to avoid corruption on DP monitor*/
-       active_total_with_borders =
-                       timing->h_addressable
-                               + timing->h_border_left
-                               + timing->h_border_right;
-
-       if (lane_count != 0)
-               early_control = active_total_with_borders % lane_count;
-
-       if (early_control == 0)
-               early_control = lane_count;
-
-       tg->funcs->set_early_control(tg, early_control);
-}
-
-static enum bp_result link_transmitter_control(
-               struct dc_bios *bios,
-       struct bp_transmitter_control *cntl)
-{
-       enum bp_result result;
-
-       result = bios->funcs->transmitter_control(bios, cntl);
-
-       return result;
-}
-
-/*
- * @brief
- * eDP only.
- */
-void dce110_edp_wait_for_hpd_ready(
-               struct dc_link *link,
-               bool power_up)
-{
-       struct dc_context *ctx = link->ctx;
-       struct graphics_object_id connector = link->link_enc->connector;
-       struct gpio *hpd;
-       bool edp_hpd_high = false;
-       uint32_t time_elapsed = 0;
-       uint32_t timeout = power_up ?
-               PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
-
-       if (dal_graphics_object_id_get_connector_id(connector)
-                       != CONNECTOR_ID_EDP) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-
-       if (!power_up)
-               /*
-                * From KV, we will not HPD low after turning off VCC -
-                * instead, we will check the SW timer in power_up().
-                */
-               return;
-
-       /*
-        * When we power on/off the eDP panel,
-        * we need to wait until SENSE bit is high/low.
-        */
-
-       /* obtain HPD */
-       /* TODO what to do with this? */
-       hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
-
-       if (!hpd) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-
-       if (link != NULL) {
-               if (link->panel_config.pps.extra_t3_ms > 0) {
-                       int extra_t3_in_ms = link->panel_config.pps.extra_t3_ms;
-
-                       msleep(extra_t3_in_ms);
-               }
-       }
-
-       dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
-
-       /* wait until timeout or panel detected */
-
-       do {
-               uint32_t detected = 0;
-
-               dal_gpio_get_value(hpd, &detected);
-
-               if (!(detected ^ power_up)) {
-                       edp_hpd_high = true;
-                       break;
-               }
-
-               msleep(HPD_CHECK_INTERVAL);
-
-               time_elapsed += HPD_CHECK_INTERVAL;
-       } while (time_elapsed < timeout);
-
-       dal_gpio_close(hpd);
-
-       dal_gpio_destroy_irq(&hpd);
-
-       /* ensure that the panel is detected */
-       if (!edp_hpd_high)
-               DC_LOG_DC("%s: wait timed out!\n", __func__);
-}
-
-void dce110_edp_power_control(
-               struct dc_link *link,
-               bool power_up)
-{
-       struct dc_context *ctx = link->ctx;
-       struct bp_transmitter_control cntl = { 0 };
-       enum bp_result bp_result;
-       uint8_t panel_instance;
-
-
-       if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
-                       != CONNECTOR_ID_EDP) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-
-       if (!link->panel_cntl)
-               return;
-       if (power_up !=
-               link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) {
-
-               unsigned long long current_ts = dm_get_timestamp(ctx);
-               unsigned long long time_since_edp_poweroff_ms =
-                               div64_u64(dm_get_elapse_time_in_ns(
-                                               ctx,
-                                               current_ts,
-                                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
-               unsigned long long time_since_edp_poweron_ms =
-                               div64_u64(dm_get_elapse_time_in_ns(
-                                               ctx,
-                                               current_ts,
-                                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)), 1000000);
-               DC_LOG_HW_RESUME_S3(
-                               "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu",
-                               __func__,
-                               power_up,
-                               current_ts,
-                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link),
-                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link),
-                               time_since_edp_poweroff_ms,
-                               time_since_edp_poweron_ms);
-
-               /* Send VBIOS command to prompt eDP panel power */
-               if (power_up) {
-                       /* edp requires a min of 500ms from LCDVDD off to on */
-                       unsigned long long remaining_min_edp_poweroff_time_ms = 500;
-
-                       /* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */
-                       if (link->local_sink != NULL)
-                               remaining_min_edp_poweroff_time_ms +=
-                                       link->panel_config.pps.extra_t12_ms;
-
-                       /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */
-                       if (ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) {
-                               if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms)
-                                       remaining_min_edp_poweroff_time_ms =
-                                               remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms;
-                               else
-                                       remaining_min_edp_poweroff_time_ms = 0;
-                       }
-
-                       if (remaining_min_edp_poweroff_time_ms) {
-                               DC_LOG_HW_RESUME_S3(
-                                               "%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n",
-                                               __func__, remaining_min_edp_poweroff_time_ms);
-                               msleep(remaining_min_edp_poweroff_time_ms);
-                               DC_LOG_HW_RESUME_S3(
-                                               "%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n",
-                                               __func__, remaining_min_edp_poweroff_time_ms);
-                               dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
-                                               __func__, remaining_min_edp_poweroff_time_ms);
-                       } else {
-                               DC_LOG_HW_RESUME_S3(
-                                               "%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n",
-                                               __func__, remaining_min_edp_poweroff_time_ms);
-                       }
-               }
-
-               DC_LOG_HW_RESUME_S3(
-                               "%s: BEGIN: Panel Power action: %s\n",
-                               __func__, (power_up ? "On":"Off"));
-
-               cntl.action = power_up ?
-                       TRANSMITTER_CONTROL_POWER_ON :
-                       TRANSMITTER_CONTROL_POWER_OFF;
-               cntl.transmitter = link->link_enc->transmitter;
-               cntl.connector_obj_id = link->link_enc->connector;
-               cntl.coherent = false;
-               cntl.lanes_number = LANE_COUNT_FOUR;
-               cntl.hpd_sel = link->link_enc->hpd_source;
-               panel_instance = link->panel_cntl->inst;
-
-               if (ctx->dc->ctx->dmub_srv &&
-                               ctx->dc->debug.dmub_command_table) {
-
-                       if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) {
-                               bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
-                                               LVTMA_CONTROL_POWER_ON,
-                                               panel_instance, link->link_powered_externally);
-                       } else {
-                               bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
-                                               LVTMA_CONTROL_POWER_OFF,
-                                               panel_instance, link->link_powered_externally);
-                       }
-               }
-
-               bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
-
-               DC_LOG_HW_RESUME_S3(
-                               "%s: END: Panel Power action: %s bp_result=%u\n",
-                               __func__, (power_up ? "On":"Off"),
-                               bp_result);
-
-               ctx->dc->link_srv->dp_trace_set_edp_power_timestamp(link, power_up);
-
-               DC_LOG_HW_RESUME_S3(
-                               "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n",
-                               __func__,
-                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link),
-                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link));
-
-               if (bp_result != BP_RESULT_OK)
-                       DC_LOG_ERROR(
-                                       "%s: Panel Power bp_result: %d\n",
-                                       __func__, bp_result);
-       } else {
-               DC_LOG_HW_RESUME_S3(
-                               "%s: Skipping Panel Power action: %s\n",
-                               __func__, (power_up ? "On":"Off"));
-       }
-}
-
-void dce110_edp_wait_for_T12(
-               struct dc_link *link)
-{
-       struct dc_context *ctx = link->ctx;
-
-       if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
-                       != CONNECTOR_ID_EDP) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-
-       if (!link->panel_cntl)
-               return;
-
-       if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) &&
-                       ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) {
-               unsigned int t12_duration = 500; // Default T12 as per spec
-               unsigned long long current_ts = dm_get_timestamp(ctx);
-               unsigned long long time_since_edp_poweroff_ms =
-                               div64_u64(dm_get_elapse_time_in_ns(
-                                               ctx,
-                                               current_ts,
-                                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
-
-               t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12
-
-               if (time_since_edp_poweroff_ms < t12_duration)
-                       msleep(t12_duration - time_since_edp_poweroff_ms);
-       }
-}
-/*todo: cloned in stream enc, fix*/
-/*
- * @brief
- * eDP only. Control the backlight of the eDP panel
- */
-void dce110_edp_backlight_control(
-               struct dc_link *link,
-               bool enable)
-{
-       struct dc_context *ctx = link->ctx;
-       struct bp_transmitter_control cntl = { 0 };
-       uint8_t panel_instance;
-       unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
-       unsigned int post_T7_delay = OLED_POST_T7_DELAY;
-
-       if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
-               != CONNECTOR_ID_EDP) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-
-       if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled ||
-               link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
-               link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) {
-               bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl);
-
-               if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) {
-                       DC_LOG_HW_RESUME_S3(
-                               "%s: panel already powered up/off. Do nothing.\n",
-                               __func__);
-                       return;
-               }
-       }
-
-       /* Send VBIOS command to control eDP panel backlight */
-
-       DC_LOG_HW_RESUME_S3(
-                       "%s: backlight action: %s\n",
-                       __func__, (enable ? "On":"Off"));
-
-       cntl.action = enable ?
-               TRANSMITTER_CONTROL_BACKLIGHT_ON :
-               TRANSMITTER_CONTROL_BACKLIGHT_OFF;
-
-       /*cntl.engine_id = ctx->engine;*/
-       cntl.transmitter = link->link_enc->transmitter;
-       cntl.connector_obj_id = link->link_enc->connector;
-       /*todo: unhardcode*/
-       cntl.lanes_number = LANE_COUNT_FOUR;
-       cntl.hpd_sel = link->link_enc->hpd_source;
-       cntl.signal = SIGNAL_TYPE_EDP;
-
-       /* For eDP, the following delays might need to be considered
-        * after link training completed:
-        * idle period - min. accounts for required BS-Idle pattern,
-        * max. allows for source frame synchronization);
-        * 50 msec max. delay from valid video data from source
-        * to video on dislpay or backlight enable.
-        *
-        * Disable the delay for now.
-        * Enable it in the future if necessary.
-        */
-       /* dc_service_sleep_in_milliseconds(50); */
-               /*edp 1.2*/
-       panel_instance = link->panel_cntl->inst;
-
-       if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
-               if (!link->dc->config.edp_no_power_sequencing)
-               /*
-                * Sometimes, DP receiver chip power-controlled externally by an
-                * Embedded Controller could be treated and used as eDP,
-                * if it drives mobile display. In this case,
-                * we shouldn't be doing power-sequencing, hence we can skip
-                * waiting for T7-ready.
-                */
-                       ctx->dc->link_srv->edp_receiver_ready_T7(link);
-               else
-                       DC_LOG_DC("edp_receiver_ready_T7 skipped\n");
-       }
-
-       /* Setting link_powered_externally will bypass delays in the backlight
-        * as they are not required if the link is being powered by a different
-        * source.
-        */
-       if (ctx->dc->ctx->dmub_srv &&
-                       ctx->dc->debug.dmub_command_table) {
-               if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
-                       ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
-                                       LVTMA_CONTROL_LCD_BLON,
-                                       panel_instance, link->link_powered_externally);
-               else
-                       ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
-                                       LVTMA_CONTROL_LCD_BLOFF,
-                                       panel_instance, link->link_powered_externally);
-       }
-
-       link_transmitter_control(ctx->dc_bios, &cntl);
-
-       if (enable && link->dpcd_sink_ext_caps.bits.oled &&
-           !link->dc->config.edp_no_power_sequencing) {
-               post_T7_delay += link->panel_config.pps.extra_post_t7_ms;
-               msleep(post_T7_delay);
-       }
-
-       if (link->dpcd_sink_ext_caps.bits.oled ||
-               link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
-               link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)
-               ctx->dc->link_srv->edp_backlight_enable_aux(link, enable);
-
-       /*edp 1.2*/
-       if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) {
-               if (!link->dc->config.edp_no_power_sequencing)
-               /*
-                * Sometimes, DP receiver chip power-controlled externally by an
-                * Embedded Controller could be treated and used as eDP,
-                * if it drives mobile display. In this case,
-                * we shouldn't be doing power-sequencing, hence we can skip
-                * waiting for T9-ready.
-                */
-                       ctx->dc->link_srv->edp_add_delay_for_T9(link);
-               else
-                       DC_LOG_DC("edp_receiver_ready_T9 skipped\n");
-       }
-
-       if (!enable && link->dpcd_sink_ext_caps.bits.oled) {
-               pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms;
-               msleep(pre_T11_delay);
-       }
-}
-
-void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
-{
-       /* notify audio driver for audio modes of monitor */
-       struct dc *dc;
-       struct clk_mgr *clk_mgr;
-       unsigned int i, num_audio = 1;
-       const struct link_hwss *link_hwss;
-
-       if (!pipe_ctx->stream)
-               return;
-
-       dc = pipe_ctx->stream->ctx->dc;
-       clk_mgr = dc->clk_mgr;
-       link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
-
-       if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
-               return;
-
-       if (pipe_ctx->stream_res.audio) {
-               for (i = 0; i < MAX_PIPES; i++) {
-                       /*current_state not updated yet*/
-                       if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
-                               num_audio++;
-               }
-
-               pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
-
-               if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa)
-                       /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
-                       clk_mgr->funcs->enable_pme_wa(clk_mgr);
-
-               link_hwss->enable_audio_packet(pipe_ctx);
-
-               if (pipe_ctx->stream_res.audio)
-                       pipe_ctx->stream_res.audio->enabled = true;
-       }
-}
-
-void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
-{
-       struct dc *dc;
-       struct clk_mgr *clk_mgr;
-       const struct link_hwss *link_hwss;
-
-       if (!pipe_ctx || !pipe_ctx->stream)
-               return;
-
-       dc = pipe_ctx->stream->ctx->dc;
-       clk_mgr = dc->clk_mgr;
-       link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
-
-       if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
-               return;
-
-       link_hwss->disable_audio_packet(pipe_ctx);
-
-       if (pipe_ctx->stream_res.audio) {
-               pipe_ctx->stream_res.audio->enabled = false;
-
-               if (clk_mgr->funcs->enable_pme_wa)
-                       /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
-                       clk_mgr->funcs->enable_pme_wa(clk_mgr);
-
-               /* TODO: notify audio driver for if audio modes list changed
-                * add audio mode list change flag */
-               /* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
-                * stream->stream_engine_id);
-                */
-       }
-}
-
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dc *dc = pipe_ctx->stream->ctx->dc;
-       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
-       struct dccg *dccg = dc->res_pool->dccg;
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       struct dtbclk_dto_params dto_params = {0};
-       int dp_hpo_inst;
-       struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
-       struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
-
-       if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
-               pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
-                       pipe_ctx->stream_res.stream_enc);
-               pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute(
-                       pipe_ctx->stream_res.stream_enc);
-       }
-
-       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
-                                       pipe_ctx->stream_res.hpo_dp_stream_enc);
-       } else if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
-                       pipe_ctx->stream_res.stream_enc);
-
-       dc->hwss.disable_audio_stream(pipe_ctx);
-
-       link_hwss->reset_stream_encoder(pipe_ctx);
-
-       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && dccg) {
-               dto_params.otg_inst = tg->inst;
-               dto_params.timing = &pipe_ctx->stream->timing;
-               dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
-
-               dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
-               dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
-               dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
-       } else if (dccg && dccg->funcs->disable_symclk_se) {
-               dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
-                                              link_enc->transmitter - TRANSMITTER_UNIPHY_A);
-       }
-
-       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               /* TODO: This looks like a bug to me as we are disabling HPO IO when
-                * we are just disabling a single HPO stream. Shouldn't we disable HPO
-                * HW control only when HPOs for all streams are disabled?
-                */
-               if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
-                       pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
-                                       pipe_ctx->stream->ctx->dc->hwseq, false);
-       }
-}
-
-void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings)
-{
-       struct encoder_unblank_param params = { { 0 } };
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dce_hwseq *hws = link->dc->hwseq;
-
-       /* only 3 items below are used by unblank */
-       params.timing = pipe_ctx->stream->timing;
-       params.link_settings.link_rate = link_settings->link_rate;
-
-       if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
-
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-               hws->funcs.edp_backlight_control(link, true);
-       }
-}
-
-void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dce_hwseq *hws = link->dc->hwseq;
-
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-               if (!link->skip_implict_edp_power_control)
-                       hws->funcs.edp_backlight_control(link, false);
-               link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
-       }
-
-       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
-               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
-                               pipe_ctx->stream_res.hpo_dp_stream_enc);
-       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
-
-               if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) {
-                       /*
-                        * After output is idle pattern some sinks need time to recognize the stream
-                        * has changed or they enter protection state and hang.
-                        */
-                       msleep(60);
-               } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
-                       if (!link->dc->config.edp_no_power_sequencing) {
-                               /*
-                                * Sometimes, DP receiver chip power-controlled externally by an
-                                * Embedded Controller could be treated and used as eDP,
-                                * if it drives mobile display. In this case,
-                                * we shouldn't be doing power-sequencing, hence we can skip
-                                * waiting for T9-ready.
-                                */
-                               link->dc->link_srv->edp_receiver_ready_T9(link);
-                       }
-               }
-       }
-
-}
-
-
-void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
-{
-       if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
-               pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
-}
-
-static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
-{
-       switch (crtc_id) {
-       case CONTROLLER_ID_D0:
-               return DTO_SOURCE_ID0;
-       case CONTROLLER_ID_D1:
-               return DTO_SOURCE_ID1;
-       case CONTROLLER_ID_D2:
-               return DTO_SOURCE_ID2;
-       case CONTROLLER_ID_D3:
-               return DTO_SOURCE_ID3;
-       case CONTROLLER_ID_D4:
-               return DTO_SOURCE_ID4;
-       case CONTROLLER_ID_D5:
-               return DTO_SOURCE_ID5;
-       default:
-               return DTO_SOURCE_UNKNOWN;
-       }
-}
-
-static void build_audio_output(
-       struct dc_state *state,
-       const struct pipe_ctx *pipe_ctx,
-       struct audio_output *audio_output)
-{
-       const struct dc_stream_state *stream = pipe_ctx->stream;
-       audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id;
-
-       audio_output->signal = pipe_ctx->stream->signal;
-
-       /* audio_crtc_info  */
-
-       audio_output->crtc_info.h_total =
-               stream->timing.h_total;
-
-       /*
-        * Audio packets are sent during actual CRTC blank physical signal, we
-        * need to specify actual active signal portion
-        */
-       audio_output->crtc_info.h_active =
-                       stream->timing.h_addressable
-                       + stream->timing.h_border_left
-                       + stream->timing.h_border_right;
-
-       audio_output->crtc_info.v_active =
-                       stream->timing.v_addressable
-                       + stream->timing.v_border_top
-                       + stream->timing.v_border_bottom;
-
-       audio_output->crtc_info.pixel_repetition = 1;
-
-       audio_output->crtc_info.interlaced =
-                       stream->timing.flags.INTERLACE;
-
-       audio_output->crtc_info.refresh_rate =
-               (stream->timing.pix_clk_100hz*100)/
-               (stream->timing.h_total*stream->timing.v_total);
-
-       audio_output->crtc_info.color_depth =
-               stream->timing.display_color_depth;
-
-       audio_output->crtc_info.requested_pixel_clock_100Hz =
-                       pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
-
-       audio_output->crtc_info.calculated_pixel_clock_100Hz =
-                       pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
-
-/*for HDMI, audio ACR is with deep color ratio factor*/
-       if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) &&
-               audio_output->crtc_info.requested_pixel_clock_100Hz ==
-                               (stream->timing.pix_clk_100hz)) {
-               if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
-                       audio_output->crtc_info.requested_pixel_clock_100Hz =
-                                       audio_output->crtc_info.requested_pixel_clock_100Hz/2;
-                       audio_output->crtc_info.calculated_pixel_clock_100Hz =
-                                       pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2;
-
-               }
-       }
-
-       if (state->clk_mgr &&
-               (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
-                       pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
-               audio_output->pll_info.dp_dto_source_clock_in_khz =
-                               state->clk_mgr->funcs->get_dp_ref_clk_frequency(
-                                               state->clk_mgr);
-       }
-
-       audio_output->pll_info.feed_back_divider =
-                       pipe_ctx->pll_settings.feedback_divider;
-
-       audio_output->pll_info.dto_source =
-               translate_to_dto_source(
-                       pipe_ctx->stream_res.tg->inst + 1);
-
-       /* TODO hard code to enable for now. Need get from stream */
-       audio_output->pll_info.ss_enabled = true;
-
-       audio_output->pll_info.ss_percentage =
-                       pipe_ctx->pll_settings.ss_percentage;
-}
-
-static void program_scaler(const struct dc *dc,
-               const struct pipe_ctx *pipe_ctx)
-{
-       struct tg_color color = {0};
-
-       /* TOFPGA */
-       if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
-               return;
-
-       if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
-               get_surface_visual_confirm_color(pipe_ctx, &color);
-       else
-               color_space_to_black_color(dc,
-                               pipe_ctx->stream->output_color_space,
-                               &color);
-
-       pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
-               pipe_ctx->plane_res.xfm,
-               pipe_ctx->plane_res.scl_data.lb_params.depth,
-               &pipe_ctx->stream->bit_depth_params);
-
-       if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {
-               /*
-                * The way 420 is packed, 2 channels carry Y component, 1 channel
-                * alternate between Cb and Cr, so both channels need the pixel
-                * value for Y
-                */
-               if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-                       color.color_r_cr = color.color_g_y;
-
-               pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
-                               pipe_ctx->stream_res.tg,
-                               &color);
-       }
-
-       pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
-               &pipe_ctx->plane_res.scl_data);
-}
-
-static enum dc_status dce110_enable_stream_timing(
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context,
-               struct dc *dc)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
-                       pipe_ctx[pipe_ctx->pipe_idx];
-       struct tg_color black_color = {0};
-
-       if (!pipe_ctx_old->stream) {
-
-               /* program blank color */
-               color_space_to_black_color(dc,
-                               stream->output_color_space, &black_color);
-               pipe_ctx->stream_res.tg->funcs->set_blank_color(
-                               pipe_ctx->stream_res.tg,
-                               &black_color);
-
-               /*
-                * Must blank CRTC after disabling power gating and before any
-                * programming, otherwise CRTC will be hung in bad state
-                */
-               pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
-
-               if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
-                               pipe_ctx->clock_source,
-                               &pipe_ctx->stream_res.pix_clk_params,
-                               dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
-                               &pipe_ctx->pll_settings)) {
-                       BREAK_TO_DEBUGGER();
-                       return DC_ERROR_UNEXPECTED;
-               }
-
-               if (dc_is_hdmi_tmds_signal(stream->signal)) {
-                       stream->link->phy_state.symclk_ref_cnts.otg = 1;
-                       if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
-                               stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
-                       else
-                               stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-               }
-
-               pipe_ctx->stream_res.tg->funcs->program_timing(
-                               pipe_ctx->stream_res.tg,
-                               &stream->timing,
-                               0,
-                               0,
-                               0,
-                               0,
-                               pipe_ctx->stream->signal,
-                               true);
-       }
-
-       if (!pipe_ctx_old->stream) {
-               if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(
-                               pipe_ctx->stream_res.tg)) {
-                       BREAK_TO_DEBUGGER();
-                       return DC_ERROR_UNEXPECTED;
-               }
-       }
-
-       return DC_OK;
-}
-
-static enum dc_status apply_single_controller_ctx_to_hw(
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context,
-               struct dc *dc)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct drr_params params = {0};
-       unsigned int event_triggers = 0;
-       struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
-       struct dce_hwseq *hws = dc->hwseq;
-       const struct link_hwss *link_hwss = get_link_hwss(
-                       link, &pipe_ctx->link_res);
-
-
-       if (hws->funcs.disable_stream_gating) {
-               hws->funcs.disable_stream_gating(dc, pipe_ctx);
-       }
-
-       if (pipe_ctx->stream_res.audio != NULL) {
-               struct audio_output audio_output;
-
-               build_audio_output(context, pipe_ctx, &audio_output);
-
-               link_hwss->setup_audio_output(pipe_ctx, &audio_output,
-                               pipe_ctx->stream_res.audio->inst);
-
-               pipe_ctx->stream_res.audio->funcs->az_configure(
-                               pipe_ctx->stream_res.audio,
-                               pipe_ctx->stream->signal,
-                               &audio_output.crtc_info,
-                               &pipe_ctx->stream->audio_info);
-       }
-
-       /* make sure no pipes syncd to the pipe being enabled */
-       if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic)
-               check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx);
-
-       pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
-               pipe_ctx->stream_res.opp,
-               &stream->bit_depth_params,
-               &stream->clamping);
-
-       pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
-                       pipe_ctx->stream_res.opp,
-                       COLOR_SPACE_YCBCR601,
-                       stream->timing.display_color_depth,
-                       stream->signal);
-
-       while (odm_pipe) {
-               odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion(
-                               odm_pipe->stream_res.opp,
-                               COLOR_SPACE_YCBCR601,
-                               stream->timing.display_color_depth,
-                               stream->signal);
-
-               odm_pipe->stream_res.opp->funcs->opp_program_fmt(
-                               odm_pipe->stream_res.opp,
-                               &stream->bit_depth_params,
-                               &stream->clamping);
-               odm_pipe = odm_pipe->next_odm_pipe;
-       }
-
-       /* DCN3.1 FPGA Workaround
-        * Need to enable HPO DP Stream Encoder before setting OTG master enable.
-        * To do so, move calling function enable_stream_timing to only be done AFTER calling
-        * function core_link_enable_stream
-        */
-       if (!(hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)))
-               /*  */
-               /* Do not touch stream timing on seamless boot optimization. */
-               if (!pipe_ctx->stream->apply_seamless_boot_optimization)
-                       hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
-
-       if (hws->funcs.setup_vupdate_interrupt)
-               hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
-
-       params.vertical_total_min = stream->adjust.v_total_min;
-       params.vertical_total_max = stream->adjust.v_total_max;
-       if (pipe_ctx->stream_res.tg->funcs->set_drr)
-               pipe_ctx->stream_res.tg->funcs->set_drr(
-                       pipe_ctx->stream_res.tg, &params);
-
-       // DRR should set trigger event to monitor surface update event
-       if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
-               event_triggers = 0x80;
-       /* Event triggers and num frames initialized for DRR, but can be
-        * later updated for PSR use. Note DRR trigger events are generated
-        * regardless of whether num frames met.
-        */
-       if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
-               pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
-                               pipe_ctx->stream_res.tg, event_triggers, 2);
-
-       if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
-               pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
-                       pipe_ctx->stream_res.stream_enc,
-                       pipe_ctx->stream_res.tg->inst);
-
-       if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
-
-       if (!stream->dpms_off)
-               dc->link_srv->set_dpms_on(context, pipe_ctx);
-
-       /* DCN3.1 FPGA Workaround
-        * Need to enable HPO DP Stream Encoder before setting OTG master enable.
-        * To do so, move calling function enable_stream_timing to only be done AFTER calling
-        * function core_link_enable_stream
-        */
-       if (hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               if (!pipe_ctx->stream->apply_seamless_boot_optimization)
-                       hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
-       }
-
-       pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
-
-       /* Phantom and main stream share the same link (because the stream
-        * is constructed with the same sink). Make sure not to override
-        * and link programming on the main.
-        */
-       if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
-               pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
-               pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false;
-       }
-       return DC_OK;
-}
-
-/******************************************************************************/
-
-static void power_down_encoders(struct dc *dc)
-{
-       int i;
-
-       for (i = 0; i < dc->link_count; i++) {
-               enum signal_type signal = dc->links[i]->connector_signal;
-
-               dc->link_srv->blank_dp_stream(dc->links[i], false);
-
-               if (signal != SIGNAL_TYPE_EDP)
-                       signal = SIGNAL_TYPE_NONE;
-
-               if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY)
-                       dc->links[i]->link_enc->funcs->disable_output(
-                                       dc->links[i]->link_enc, signal);
-
-               dc->links[i]->link_status.link_active = false;
-               memset(&dc->links[i]->cur_link_settings, 0,
-                               sizeof(dc->links[i]->cur_link_settings));
-       }
-}
-
-static void power_down_controllers(struct dc *dc)
-{
-       int i;
-
-       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-               dc->res_pool->timing_generators[i]->funcs->disable_crtc(
-                               dc->res_pool->timing_generators[i]);
-       }
-}
-
-static void power_down_clock_sources(struct dc *dc)
-{
-       int i;
-
-       if (dc->res_pool->dp_clock_source->funcs->cs_power_down(
-               dc->res_pool->dp_clock_source) == false)
-               dm_error("Failed to power down pll! (dp clk src)\n");
-
-       for (i = 0; i < dc->res_pool->clk_src_count; i++) {
-               if (dc->res_pool->clock_sources[i]->funcs->cs_power_down(
-                               dc->res_pool->clock_sources[i]) == false)
-                       dm_error("Failed to power down pll! (clk src index=%d)\n", i);
-       }
-}
-
-static void power_down_all_hw_blocks(struct dc *dc)
-{
-       power_down_encoders(dc);
-
-       power_down_controllers(dc);
-
-       power_down_clock_sources(dc);
-
-       if (dc->fbc_compressor)
-               dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
-}
-
-static void disable_vga_and_power_gate_all_controllers(
-               struct dc *dc)
-{
-       int i;
-       struct timing_generator *tg;
-       struct dc_context *ctx = dc->ctx;
-
-       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-               tg = dc->res_pool->timing_generators[i];
-
-               if (tg->funcs->disable_vga)
-                       tg->funcs->disable_vga(tg);
-       }
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               /* Enable CLOCK gating for each pipe BEFORE controller
-                * powergating. */
-               enable_display_pipe_clock_gating(ctx,
-                               true);
-
-               dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i;
-               dc->hwss.disable_plane(dc,
-                       &dc->current_state->res_ctx.pipe_ctx[i]);
-       }
-}
-
-
-static void get_edp_streams(struct dc_state *context,
-               struct dc_stream_state **edp_streams,
-               int *edp_stream_num)
-{
-       int i;
-
-       *edp_stream_num = 0;
-       for (i = 0; i < context->stream_count; i++) {
-               if (context->streams[i]->signal == SIGNAL_TYPE_EDP) {
-                       edp_streams[*edp_stream_num] = context->streams[i];
-                       if (++(*edp_stream_num) == MAX_NUM_EDP)
-                               return;
-               }
-       }
-}
-
-static void get_edp_links_with_sink(
-               struct dc *dc,
-               struct dc_link **edp_links_with_sink,
-               int *edp_with_sink_num)
-{
-       int i;
-
-       /* check if there is an eDP panel not in use */
-       *edp_with_sink_num = 0;
-       for (i = 0; i < dc->link_count; i++) {
-               if (dc->links[i]->local_sink &&
-                       dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-                       edp_links_with_sink[*edp_with_sink_num] = dc->links[i];
-                       if (++(*edp_with_sink_num) == MAX_NUM_EDP)
-                               return;
-               }
-       }
-}
-
-/*
- * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
- *  1. Power down all DC HW blocks
- *  2. Disable VGA engine on all controllers
- *  3. Enable power gating for controller
- *  4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
- */
-void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
-{
-       struct dc_link *edp_links_with_sink[MAX_NUM_EDP];
-       struct dc_link *edp_links[MAX_NUM_EDP];
-       struct dc_stream_state *edp_streams[MAX_NUM_EDP];
-       struct dc_link *edp_link_with_sink = NULL;
-       struct dc_link *edp_link = NULL;
-       struct dce_hwseq *hws = dc->hwseq;
-       int edp_with_sink_num;
-       int edp_num;
-       int edp_stream_num;
-       int i;
-       bool can_apply_edp_fast_boot = false;
-       bool can_apply_seamless_boot = false;
-       bool keep_edp_vdd_on = false;
-       DC_LOGGER_INIT();
-
-
-       get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num);
-       dc_get_edp_links(dc, edp_links, &edp_num);
-
-       if (hws->funcs.init_pipes)
-               hws->funcs.init_pipes(dc, context);
-
-       get_edp_streams(context, edp_streams, &edp_stream_num);
-
-       // Check fastboot support, disable on DCE8 because of blank screens
-       if (edp_num && edp_stream_num && dc->ctx->dce_version != DCE_VERSION_8_0 &&
-                   dc->ctx->dce_version != DCE_VERSION_8_1 &&
-                   dc->ctx->dce_version != DCE_VERSION_8_3) {
-               for (i = 0; i < edp_num; i++) {
-                       edp_link = edp_links[i];
-                       if (edp_link != edp_streams[0]->link)
-                               continue;
-                       // enable fastboot if backend is enabled on eDP
-                       if (edp_link->link_enc->funcs->is_dig_enabled &&
-                           edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                           edp_link->link_status.link_active) {
-                               struct dc_stream_state *edp_stream = edp_streams[0];
-
-                               can_apply_edp_fast_boot = dc_validate_boot_timing(dc,
-                                       edp_stream->sink, &edp_stream->timing);
-                               edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot;
-                               if (can_apply_edp_fast_boot)
-                                       DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n");
-
-                               break;
-                       }
-               }
-               // We are trying to enable eDP, don't power down VDD
-               if (can_apply_edp_fast_boot)
-                       keep_edp_vdd_on = true;
-       }
-
-       // Check seamless boot support
-       for (i = 0; i < context->stream_count; i++) {
-               if (context->streams[i]->apply_seamless_boot_optimization) {
-                       can_apply_seamless_boot = true;
-                       break;
-               }
-       }
-
-       /* eDP should not have stream in resume from S4 and so even with VBios post
-        * it should get turned off
-        */
-       if (edp_with_sink_num)
-               edp_link_with_sink = edp_links_with_sink[0];
-
-       if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) {
-               if (edp_link_with_sink && !keep_edp_vdd_on) {
-                       /*turn off backlight before DP_blank and encoder powered down*/
-                       hws->funcs.edp_backlight_control(edp_link_with_sink, false);
-               }
-               /*resume from S3, no vbios posting, no need to power down again*/
-               clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
-
-               power_down_all_hw_blocks(dc);
-               disable_vga_and_power_gate_all_controllers(dc);
-               if (edp_link_with_sink && !keep_edp_vdd_on)
-                       dc->hwss.edp_power_control(edp_link_with_sink, false);
-               clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
-       }
-       bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1);
-}
-
-static uint32_t compute_pstate_blackout_duration(
-       struct bw_fixed blackout_duration,
-       const struct dc_stream_state *stream)
-{
-       uint32_t total_dest_line_time_ns;
-       uint32_t pstate_blackout_duration_ns;
-
-       pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
-
-       total_dest_line_time_ns = 1000000UL *
-               (stream->timing.h_total * 10) /
-               stream->timing.pix_clk_100hz +
-               pstate_blackout_duration_ns;
-
-       return total_dest_line_time_ns;
-}
-
-static void dce110_set_displaymarks(
-       const struct dc *dc,
-       struct dc_state *context)
-{
-       uint8_t i, num_pipes;
-       unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
-
-       for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               uint32_t total_dest_line_time_ns;
-
-               if (pipe_ctx->stream == NULL)
-                       continue;
-
-               total_dest_line_time_ns = compute_pstate_blackout_duration(
-                       dc->bw_vbios->blackout_duration, pipe_ctx->stream);
-               pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
-                       pipe_ctx->plane_res.mi,
-                       context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
-                       context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
-                       context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes],
-                       context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
-                       total_dest_line_time_ns);
-               if (i == underlay_idx) {
-                       num_pipes++;
-                       pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
-                               pipe_ctx->plane_res.mi,
-                               context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
-                               context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
-                               context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
-                               total_dest_line_time_ns);
-               }
-               num_pipes++;
-       }
-}
-
-void dce110_set_safe_displaymarks(
-               struct resource_context *res_ctx,
-               const struct resource_pool *pool)
-{
-       int i;
-       int underlay_idx = pool->underlay_pipe_index;
-       struct dce_watermarks max_marks = {
-               MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK };
-       struct dce_watermarks nbp_marks = {
-               SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
-       struct dce_watermarks min_marks = { 0, 0, 0, 0};
-
-       for (i = 0; i < MAX_PIPES; i++) {
-               if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
-                       continue;
-
-               res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
-                               res_ctx->pipe_ctx[i].plane_res.mi,
-                               nbp_marks,
-                               max_marks,
-                               min_marks,
-                               max_marks,
-                               MAX_WATERMARK);
-
-               if (i == underlay_idx)
-                       res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
-                               res_ctx->pipe_ctx[i].plane_res.mi,
-                               nbp_marks,
-                               max_marks,
-                               max_marks,
-                               MAX_WATERMARK);
-
-       }
-}
-
-/*******************************************************************************
- * Public functions
- ******************************************************************************/
-
-static void set_drr(struct pipe_ctx **pipe_ctx,
-               int num_pipes, struct dc_crtc_timing_adjust adjust)
-{
-       int i = 0;
-       struct drr_params params = {0};
-       // DRR should set trigger event to monitor surface update event
-       unsigned int event_triggers = 0x80;
-       // Note DRR trigger events are generated regardless of whether num frames met.
-       unsigned int num_frames = 2;
-
-       params.vertical_total_max = adjust.v_total_max;
-       params.vertical_total_min = adjust.v_total_min;
-
-       /* TODO: If multiple pipes are to be supported, you need
-        * some GSL stuff. Static screen triggers may be programmed differently
-        * as well.
-        */
-       for (i = 0; i < num_pipes; i++) {
-               pipe_ctx[i]->stream_res.tg->funcs->set_drr(
-                       pipe_ctx[i]->stream_res.tg, &params);
-
-               if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
-                       pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
-                                       pipe_ctx[i]->stream_res.tg,
-                                       event_triggers, num_frames);
-       }
-}
-
-static void get_position(struct pipe_ctx **pipe_ctx,
-               int num_pipes,
-               struct crtc_position *position)
-{
-       int i = 0;
-
-       /* TODO: handle pipes > 1
-        */
-       for (i = 0; i < num_pipes; i++)
-               pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
-}
-
-static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
-               int num_pipes, const struct dc_static_screen_params *params)
-{
-       unsigned int i;
-       unsigned int triggers = 0;
-
-       if (params->triggers.overlay_update)
-               triggers |= 0x100;
-       if (params->triggers.surface_update)
-               triggers |= 0x80;
-       if (params->triggers.cursor_update)
-               triggers |= 0x2;
-       if (params->triggers.force_trigger)
-               triggers |= 0x1;
-
-       if (num_pipes) {
-               struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
-
-               if (dc->fbc_compressor)
-                       triggers |= 0x84;
-       }
-
-       for (i = 0; i < num_pipes; i++)
-               pipe_ctx[i]->stream_res.tg->funcs->
-                       set_static_screen_control(pipe_ctx[i]->stream_res.tg,
-                                       triggers, params->num_frames);
-}
-
-/*
- *  Check if FBC can be enabled
- */
-static bool should_enable_fbc(struct dc *dc,
-               struct dc_state *context,
-               uint32_t *pipe_idx)
-{
-       uint32_t i;
-       struct pipe_ctx *pipe_ctx = NULL;
-       struct resource_context *res_ctx = &context->res_ctx;
-       unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
-
-
-       ASSERT(dc->fbc_compressor);
-
-       /* FBC memory should be allocated */
-       if (!dc->ctx->fbc_gpu_addr)
-               return false;
-
-       /* Only supports single display */
-       if (context->stream_count != 1)
-               return false;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (res_ctx->pipe_ctx[i].stream) {
-
-                       pipe_ctx = &res_ctx->pipe_ctx[i];
-
-                       /* fbc not applicable on underlay pipe */
-                       if (pipe_ctx->pipe_idx != underlay_idx) {
-                               *pipe_idx = i;
-                               break;
-                       }
-               }
-       }
-
-       if (i == dc->res_pool->pipe_count)
-               return false;
-
-       if (!pipe_ctx->stream->link)
-               return false;
-
-       /* Only supports eDP */
-       if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
-               return false;
-
-       /* PSR should not be enabled */
-       if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
-               return false;
-
-       /* Replay should not be enabled */
-       if (pipe_ctx->stream->link->replay_settings.replay_feature_enabled)
-               return false;
-
-       /* Nothing to compress */
-       if (!pipe_ctx->plane_state)
-               return false;
-
-       /* Only for non-linear tiling */
-       if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
-               return false;
-
-       return true;
-}
-
-/*
- *  Enable FBC
- */
-static void enable_fbc(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       uint32_t pipe_idx = 0;
-
-       if (should_enable_fbc(dc, context, &pipe_idx)) {
-               /* Program GRPH COMPRESSED ADDRESS and PITCH */
-               struct compr_addr_and_pitch_params params = {0, 0, 0};
-               struct compressor *compr = dc->fbc_compressor;
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
-
-               params.source_view_width = pipe_ctx->stream->timing.h_addressable;
-               params.source_view_height = pipe_ctx->stream->timing.v_addressable;
-               params.inst = pipe_ctx->stream_res.tg->inst;
-               compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
-
-               compr->funcs->surface_address_and_pitch(compr, &params);
-               compr->funcs->set_fbc_invalidation_triggers(compr, 1);
-
-               compr->funcs->enable_fbc(compr, &params);
-       }
-}
-
-static void dce110_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-
-       /* Reset old context */
-       /* look up the targets that have been removed since last commit */
-       for (i = 0; i < MAX_PIPES; i++) {
-               struct pipe_ctx *pipe_ctx_old =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* Note: We need to disable output if clock sources change,
-                * since bios does optimization and doesn't apply if changing
-                * PHY when not already disabled.
-                */
-
-               /* Skip underlay pipe since it will be handled in commit surface*/
-               if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe)
-                       continue;
-
-               if (!pipe_ctx->stream ||
-                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
-                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
-
-                       /* Disable if new stream is null. O/w, if stream is
-                        * disabled already, no need to disable again.
-                        */
-                       if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
-                               dc->link_srv->set_dpms_off(pipe_ctx_old);
-
-                               /* free acquired resources*/
-                               if (pipe_ctx_old->stream_res.audio) {
-                                       /*disable az_endpoint*/
-                                       pipe_ctx_old->stream_res.audio->funcs->
-                                                       az_disable(pipe_ctx_old->stream_res.audio);
-
-                                       /*free audio*/
-                                       if (dc->caps.dynamic_audio == true) {
-                                               /*we have to dynamic arbitrate the audio endpoints*/
-                                               /*we free the resource, need reset is_audio_acquired*/
-                                               update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
-                                                               pipe_ctx_old->stream_res.audio, false);
-                                               pipe_ctx_old->stream_res.audio = NULL;
-                                       }
-                               }
-                       }
-
-                       pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
-                       if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
-                               dm_error("DC: failed to blank crtc!\n");
-                               BREAK_TO_DEBUGGER();
-                       }
-                       pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg);
-                       pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0;
-                       pipe_ctx_old->plane_res.mi->funcs->free_mem_input(
-                                       pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
-
-                       if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx,
-                                                                               dc->res_pool,
-                                                                               old_clk))
-                               old_clk->funcs->cs_power_down(old_clk);
-
-                       dc->hwss.disable_plane(dc, pipe_ctx_old);
-
-                       pipe_ctx_old->stream = NULL;
-               }
-       }
-}
-
-static void dce110_setup_audio_dto(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-
-       /* program audio wall clock. use HDMI as clock source if HDMI
-        * audio active. Otherwise, use DP as clock source
-        * first, loop to find any HDMI audio, if not, loop find DP audio
-        */
-       /* Setup audio rate clock source */
-       /* Issue:
-       * Audio lag happened on DP monitor when unplug a HDMI monitor
-       *
-       * Cause:
-       * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL
-       * is set to either dto0 or dto1, audio should work fine.
-       * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1,
-       * set to dto0 will cause audio lag.
-       *
-       * Solution:
-       * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx,
-       * find first available pipe with audio, setup audio wall DTO per topology
-       * instead of per pipe.
-       */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->stream == NULL)
-                       continue;
-
-               if (pipe_ctx->top_pipe)
-                       continue;
-               if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
-                       continue;
-               if (pipe_ctx->stream_res.audio != NULL) {
-                       struct audio_output audio_output;
-
-                       build_audio_output(context, pipe_ctx, &audio_output);
-
-                       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {
-                               struct dtbclk_dto_params dto_params = {0};
-
-                               dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
-                                       dc->res_pool->dccg, &dto_params);
-
-                               pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
-                                               pipe_ctx->stream_res.audio,
-                                               pipe_ctx->stream->signal,
-                                               &audio_output.crtc_info,
-                                               &audio_output.pll_info);
-                       } else
-                               pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
-                                       pipe_ctx->stream_res.audio,
-                                       pipe_ctx->stream->signal,
-                                       &audio_output.crtc_info,
-                                       &audio_output.pll_info);
-                       break;
-               }
-       }
-
-       /* no HDMI audio is found, try DP audio */
-       if (i == dc->res_pool->pipe_count) {
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-                       if (pipe_ctx->stream == NULL)
-                               continue;
-
-                       if (pipe_ctx->top_pipe)
-                               continue;
-
-                       if (!dc_is_dp_signal(pipe_ctx->stream->signal))
-                               continue;
-
-                       if (pipe_ctx->stream_res.audio != NULL) {
-                               struct audio_output audio_output;
-
-                               build_audio_output(context, pipe_ctx, &audio_output);
-
-                               pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
-                                       pipe_ctx->stream_res.audio,
-                                       pipe_ctx->stream->signal,
-                                       &audio_output.crtc_info,
-                                       &audio_output.pll_info);
-                               break;
-                       }
-               }
-       }
-}
-
-enum dc_status dce110_apply_ctx_to_hw(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       enum dc_status status;
-       int i;
-
-       /* reset syncd pipes from disabled pipes */
-       if (dc->config.use_pipe_ctx_sync_logic)
-               reset_syncd_pipes_from_disabled_pipes(dc, context);
-
-       /* Reset old context */
-       /* look up the targets that have been removed since last commit */
-       hws->funcs.reset_hw_ctx_wrap(dc, context);
-
-       /* Skip applying if no targets */
-       if (context->stream_count <= 0)
-               return DC_OK;
-
-       /* Apply new context */
-       dcb->funcs->set_scratch_critical_state(dcb, true);
-
-       /* below is for real asic only */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx_old =
-                                       &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe)
-                       continue;
-
-               if (pipe_ctx->stream == pipe_ctx_old->stream) {
-                       if (pipe_ctx_old->clock_source != pipe_ctx->clock_source)
-                               dce_crtc_switch_to_clk_src(dc->hwseq,
-                                               pipe_ctx->clock_source, i);
-                       continue;
-               }
-
-               hws->funcs.enable_display_power_gating(
-                               dc, i, dc->ctx->dc_bios,
-                               PIPE_GATING_CONTROL_DISABLE);
-       }
-
-       if (dc->fbc_compressor)
-               dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
-
-       dce110_setup_audio_dto(dc, context);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx_old =
-                                       &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->stream == NULL)
-                       continue;
-
-               if (pipe_ctx->stream == pipe_ctx_old->stream &&
-                       pipe_ctx->stream->link->link_state_valid) {
-                       continue;
-               }
-
-               if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
-                       continue;
-
-               if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
-                       continue;
-
-               status = apply_single_controller_ctx_to_hw(
-                               pipe_ctx,
-                               context,
-                               dc);
-
-               if (DC_OK != status)
-                       return status;
-
-#ifdef CONFIG_DRM_AMD_DC_FP
-               if (hws->funcs.resync_fifo_dccg_dio)
-                       hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
-#endif
-       }
-
-       if (dc->fbc_compressor)
-               enable_fbc(dc, dc->current_state);
-
-       dcb->funcs->set_scratch_critical_state(dcb, false);
-
-       return DC_OK;
-}
-
-/*******************************************************************************
- * Front End programming
- ******************************************************************************/
-static void set_default_colors(struct pipe_ctx *pipe_ctx)
-{
-       struct default_adjustment default_adjust = { 0 };
-
-       default_adjust.force_hw_default = false;
-       default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
-       default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
-       default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
-       default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
-
-       /* display color depth */
-       default_adjust.color_depth =
-               pipe_ctx->stream->timing.display_color_depth;
-
-       /* Lb color depth */
-       default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
-
-       pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
-                                       pipe_ctx->plane_res.xfm, &default_adjust);
-}
-
-
-/*******************************************************************************
- * In order to turn on/off specific surface we will program
- * Blender + CRTC
- *
- * In case that we have two surfaces and they have a different visibility
- * we can't turn off the CRTC since it will turn off the entire display
- *
- * |----------------------------------------------- |
- * |bottom pipe|curr pipe  |              |         |
- * |Surface    |Surface    | Blender      |  CRCT   |
- * |visibility |visibility | Configuration|         |
- * |------------------------------------------------|
- * |   off     |    off    | CURRENT_PIPE | blank   |
- * |   off     |    on     | CURRENT_PIPE | unblank |
- * |   on      |    off    | OTHER_PIPE   | unblank |
- * |   on      |    on     | BLENDING     | unblank |
- * -------------------------------------------------|
- *
- ******************************************************************************/
-static void program_surface_visibility(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx)
-{
-       enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE;
-       bool blank_target = false;
-
-       if (pipe_ctx->bottom_pipe) {
-
-               /* For now we are supporting only two pipes */
-               ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL);
-
-               if (pipe_ctx->bottom_pipe->plane_state->visible) {
-                       if (pipe_ctx->plane_state->visible)
-                               blender_mode = BLND_MODE_BLENDING;
-                       else
-                               blender_mode = BLND_MODE_OTHER_PIPE;
-
-               } else if (!pipe_ctx->plane_state->visible)
-                       blank_target = true;
-
-       } else if (!pipe_ctx->plane_state->visible)
-               blank_target = true;
-
-       dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
-       pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
-
-}
-
-static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
-{
-       int i = 0;
-       struct xfm_grph_csc_adjustment adjust;
-       memset(&adjust, 0, sizeof(adjust));
-       adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-
-
-       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
-               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-
-               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
-                       adjust.temperature_matrix[i] =
-                               pipe_ctx->stream->gamut_remap_matrix.matrix[i];
-       }
-
-       pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
-}
-static void update_plane_addr(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx)
-{
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-
-       if (plane_state == NULL)
-               return;
-
-       pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
-                       pipe_ctx->plane_res.mi,
-                       &plane_state->address,
-                       plane_state->flip_immediate);
-
-       plane_state->status.requested_address = plane_state->address;
-}
-
-static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-
-       if (plane_state == NULL)
-               return;
-
-       plane_state->status.is_flip_pending =
-                       pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
-                                       pipe_ctx->plane_res.mi);
-
-       if (plane_state->status.is_flip_pending && !plane_state->visible)
-               pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address;
-
-       plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
-       if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
-                       pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) {
-               plane_state->status.is_right_eye =\
-                               !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
-       }
-}
-
-void dce110_power_down(struct dc *dc)
-{
-       power_down_all_hw_blocks(dc);
-       disable_vga_and_power_gate_all_controllers(dc);
-}
-
-static bool wait_for_reset_trigger_to_occur(
-       struct dc_context *dc_ctx,
-       struct timing_generator *tg)
-{
-       struct dc_context *ctx = dc_ctx;
-       bool rc = false;
-
-       /* To avoid endless loop we wait at most
-        * frames_to_wait_on_triggered_reset frames for the reset to occur. */
-       const uint32_t frames_to_wait_on_triggered_reset = 10;
-       uint32_t i;
-
-       for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
-
-               if (!tg->funcs->is_counter_moving(tg)) {
-                       DC_ERROR("TG counter is not moving!\n");
-                       break;
-               }
-
-               if (tg->funcs->did_triggered_reset_occur(tg)) {
-                       rc = true;
-                       /* usually occurs at i=1 */
-                       DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
-                                       i);
-                       break;
-               }
-
-               /* Wait for one frame. */
-               tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
-               tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
-       }
-
-       if (false == rc)
-               DC_ERROR("GSL: Timeout on reset trigger!\n");
-
-       return rc;
-}
-
-/* Enable timing synchronization for a group of Timing Generators. */
-static void dce110_enable_timing_synchronization(
-               struct dc *dc,
-               int group_index,
-               int group_size,
-               struct pipe_ctx *grouped_pipes[])
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct dcp_gsl_params gsl_params = { 0 };
-       int i;
-       DC_LOGGER_INIT();
-
-       DC_SYNC_INFO("GSL: Setting-up...\n");
-
-       /* Designate a single TG in the group as a master.
-        * Since HW doesn't care which one, we always assign
-        * the 1st one in the group. */
-       gsl_params.gsl_group = 0;
-       gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst;
-
-       for (i = 0; i < group_size; i++)
-               grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
-                                       grouped_pipes[i]->stream_res.tg, &gsl_params);
-
-       /* Reset slave controllers on master VSync */
-       DC_SYNC_INFO("GSL: enabling trigger-reset\n");
-
-       for (i = 1 /* skip the master */; i < group_size; i++)
-               grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
-                               grouped_pipes[i]->stream_res.tg,
-                               gsl_params.gsl_group);
-
-       for (i = 1 /* skip the master */; i < group_size; i++) {
-               DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
-               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
-               grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
-                               grouped_pipes[i]->stream_res.tg);
-       }
-
-       /* GSL Vblank synchronization is a one time sync mechanism, assumption
-        * is that the sync'ed displays will not drift out of sync over time*/
-       DC_SYNC_INFO("GSL: Restoring register states.\n");
-       for (i = 0; i < group_size; i++)
-               grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
-
-       DC_SYNC_INFO("GSL: Set-up complete.\n");
-}
-
-static void dce110_enable_per_frame_crtc_position_reset(
-               struct dc *dc,
-               int group_size,
-               struct pipe_ctx *grouped_pipes[])
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct dcp_gsl_params gsl_params = { 0 };
-       int i;
-       DC_LOGGER_INIT();
-
-       gsl_params.gsl_group = 0;
-       gsl_params.gsl_master = 0;
-
-       for (i = 0; i < group_size; i++)
-               grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
-                                       grouped_pipes[i]->stream_res.tg, &gsl_params);
-
-       DC_SYNC_INFO("GSL: enabling trigger-reset\n");
-
-       for (i = 1; i < group_size; i++)
-               grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
-                               grouped_pipes[i]->stream_res.tg,
-                               gsl_params.gsl_master,
-                               &grouped_pipes[i]->stream->triggered_crtc_reset);
-
-       DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
-       for (i = 1; i < group_size; i++)
-               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
-
-       for (i = 0; i < group_size; i++)
-               grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
-
-}
-
-static void init_pipes(struct dc *dc, struct dc_state *context)
-{
-       // Do nothing
-}
-
-static void init_hw(struct dc *dc)
-{
-       int i;
-       struct dc_bios *bp;
-       struct transform *xfm;
-       struct abm *abm;
-       struct dmcu *dmcu;
-       struct dce_hwseq *hws = dc->hwseq;
-       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-
-       bp = dc->ctx->dc_bios;
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               xfm = dc->res_pool->transforms[i];
-               xfm->funcs->transform_reset(xfm);
-
-               hws->funcs.enable_display_power_gating(
-                               dc, i, bp,
-                               PIPE_GATING_CONTROL_INIT);
-               hws->funcs.enable_display_power_gating(
-                               dc, i, bp,
-                               PIPE_GATING_CONTROL_DISABLE);
-               hws->funcs.enable_display_pipe_clock_gating(
-                       dc->ctx,
-                       true);
-       }
-
-       dce_clock_gating_power_up(dc->hwseq, false);
-       /***************************************/
-
-       for (i = 0; i < dc->link_count; i++) {
-               /****************************************/
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector). */
-               struct dc_link *link = dc->links[i];
-
-               link->link_enc->funcs->hw_init(link->link_enc);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-               tg->funcs->disable_vga(tg);
-
-               /* Blank controller using driver code instead of
-                * command table. */
-               tg->funcs->set_blank(tg, true);
-               hwss_wait_for_blank_complete(tg);
-       }
-
-       for (i = 0; i < dc->res_pool->audio_count; i++) {
-               struct audio *audio = dc->res_pool->audios[i];
-               audio->funcs->hw_init(audio);
-       }
-
-       for (i = 0; i < dc->link_count; i++) {
-               struct dc_link *link = dc->links[i];
-
-               if (link->panel_cntl)
-                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
-       }
-
-       abm = dc->res_pool->abm;
-       if (abm != NULL)
-               abm->funcs->abm_init(abm, backlight);
-
-       dmcu = dc->res_pool->dmcu;
-       if (dmcu != NULL && abm != NULL)
-               abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
-
-       if (dc->fbc_compressor)
-               dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
-
-}
-
-
-void dce110_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct clk_mgr *dccg = dc->clk_mgr;
-
-       dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
-       if (dccg)
-               dccg->funcs->update_clocks(
-                               dccg,
-                               context,
-                               false);
-}
-
-void dce110_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct clk_mgr *dccg = dc->clk_mgr;
-
-       dce110_set_displaymarks(dc, context);
-
-       if (dccg)
-               dccg->funcs->update_clocks(
-                               dccg,
-                               context,
-                               true);
-}
-
-static void dce110_program_front_end_for_pipe(
-               struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct mem_input *mi = pipe_ctx->plane_res.mi;
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       struct xfm_grph_csc_adjustment adjust;
-       struct out_csc_color_matrix tbl_entry;
-       unsigned int i;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       memset(&tbl_entry, 0, sizeof(tbl_entry));
-
-       memset(&adjust, 0, sizeof(adjust));
-       adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-
-       dce_enable_fe_clock(dc->hwseq, mi->inst, true);
-
-       set_default_colors(pipe_ctx);
-       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
-                       == true) {
-               tbl_entry.color_space =
-                       pipe_ctx->stream->output_color_space;
-
-               for (i = 0; i < 12; i++)
-                       tbl_entry.regval[i] =
-                       pipe_ctx->stream->csc_color_matrix.matrix[i];
-
-               pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
-                               (pipe_ctx->plane_res.xfm, &tbl_entry);
-       }
-
-       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
-               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-
-               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
-                       adjust.temperature_matrix[i] =
-                               pipe_ctx->stream->gamut_remap_matrix.matrix[i];
-       }
-
-       pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
-
-       pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
-
-       program_scaler(dc, pipe_ctx);
-
-       mi->funcs->mem_input_program_surface_config(
-                       mi,
-                       plane_state->format,
-                       &plane_state->tiling_info,
-                       &plane_state->plane_size,
-                       plane_state->rotation,
-                       NULL,
-                       false);
-       if (mi->funcs->set_blank)
-               mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
-
-       if (dc->config.gpu_vm_support)
-               mi->funcs->mem_input_program_pte_vm(
-                               pipe_ctx->plane_res.mi,
-                               plane_state->format,
-                               &plane_state->tiling_info,
-                               plane_state->rotation);
-
-       /* Moved programming gamma from dc to hwss */
-       if (pipe_ctx->plane_state->update_flags.bits.full_update ||
-                       pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-                       pipe_ctx->plane_state->update_flags.bits.gamma_change)
-               hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
-
-       if (pipe_ctx->plane_state->update_flags.bits.full_update)
-               hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
-
-       DC_LOG_SURFACE(
-                       "Pipe:%d %p: addr hi:0x%x, "
-                       "addr low:0x%x, "
-                       "src: %d, %d, %d,"
-                       " %d; dst: %d, %d, %d, %d;"
-                       "clip: %d, %d, %d, %d\n",
-                       pipe_ctx->pipe_idx,
-                       (void *) pipe_ctx->plane_state,
-                       pipe_ctx->plane_state->address.grph.addr.high_part,
-                       pipe_ctx->plane_state->address.grph.addr.low_part,
-                       pipe_ctx->plane_state->src_rect.x,
-                       pipe_ctx->plane_state->src_rect.y,
-                       pipe_ctx->plane_state->src_rect.width,
-                       pipe_ctx->plane_state->src_rect.height,
-                       pipe_ctx->plane_state->dst_rect.x,
-                       pipe_ctx->plane_state->dst_rect.y,
-                       pipe_ctx->plane_state->dst_rect.width,
-                       pipe_ctx->plane_state->dst_rect.height,
-                       pipe_ctx->plane_state->clip_rect.x,
-                       pipe_ctx->plane_state->clip_rect.y,
-                       pipe_ctx->plane_state->clip_rect.width,
-                       pipe_ctx->plane_state->clip_rect.height);
-
-       DC_LOG_SURFACE(
-                       "Pipe %d: width, height, x, y\n"
-                       "viewport:%d, %d, %d, %d\n"
-                       "recout:  %d, %d, %d, %d\n",
-                       pipe_ctx->pipe_idx,
-                       pipe_ctx->plane_res.scl_data.viewport.width,
-                       pipe_ctx->plane_res.scl_data.viewport.height,
-                       pipe_ctx->plane_res.scl_data.viewport.x,
-                       pipe_ctx->plane_res.scl_data.viewport.y,
-                       pipe_ctx->plane_res.scl_data.recout.width,
-                       pipe_ctx->plane_res.scl_data.recout.height,
-                       pipe_ctx->plane_res.scl_data.recout.x,
-                       pipe_ctx->plane_res.scl_data.recout.y);
-}
-
-static void dce110_apply_ctx_for_surface(
-               struct dc *dc,
-               const struct dc_stream_state *stream,
-               int num_planes,
-               struct dc_state *context)
-{
-       int i;
-
-       if (num_planes == 0)
-               return;
-
-       if (dc->fbc_compressor)
-               dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->stream != stream)
-                       continue;
-
-               /* Need to allocate mem before program front end for Fiji */
-               pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
-                               pipe_ctx->plane_res.mi,
-                               pipe_ctx->stream->timing.h_total,
-                               pipe_ctx->stream->timing.v_total,
-                               pipe_ctx->stream->timing.pix_clk_100hz / 10,
-                               context->stream_count);
-
-               dce110_program_front_end_for_pipe(dc, pipe_ctx);
-
-               dc->hwss.update_plane_addr(dc, pipe_ctx);
-
-               program_surface_visibility(dc, pipe_ctx);
-
-       }
-
-       if (dc->fbc_compressor)
-               enable_fbc(dc, context);
-}
-
-static void dce110_post_unlock_program_front_end(
-               struct dc *dc,
-               struct dc_state *context)
-{
-}
-
-static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       int fe_idx = pipe_ctx->plane_res.mi ?
-               pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
-
-       /* Do not power down fe when stream is active on dce*/
-       if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
-               return;
-
-       hws->funcs.enable_display_power_gating(
-               dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
-
-       dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
-                               dc->res_pool->transforms[fe_idx]);
-}
-
-static void dce110_wait_for_mpcc_disconnect(
-               struct dc *dc,
-               struct resource_pool *res_pool,
-               struct pipe_ctx *pipe_ctx)
-{
-       /* do nothing*/
-}
-
-static void program_output_csc(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum dc_color_space colorspace,
-               uint16_t *matrix,
-               int opp_id)
-{
-       int i;
-       struct out_csc_color_matrix tbl_entry;
-
-       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
-               enum dc_color_space color_space = pipe_ctx->stream->output_color_space;
-
-               for (i = 0; i < 12; i++)
-                       tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
-
-               tbl_entry.color_space = color_space;
-
-               pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
-                               pipe_ctx->plane_res.xfm, &tbl_entry);
-       }
-}
-
-static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
-       struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
-       struct mem_input *mi = pipe_ctx->plane_res.mi;
-       struct dc_cursor_mi_param param = {
-               .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
-               .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz,
-               .viewport = pipe_ctx->plane_res.scl_data.viewport,
-               .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
-               .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
-               .rotation = pipe_ctx->plane_state->rotation,
-               .mirror = pipe_ctx->plane_state->horizontal_mirror
-       };
-
-       /**
-        * If the cursor's source viewport is clipped then we need to
-        * translate the cursor to appear in the correct position on
-        * the screen.
-        *
-        * This translation isn't affected by scaling so it needs to be
-        * done *after* we adjust the position for the scale factor.
-        *
-        * This is only done by opt-in for now since there are still
-        * some usecases like tiled display that might enable the
-        * cursor on both streams while expecting dc to clip it.
-        */
-       if (pos_cpy.translate_by_source) {
-               pos_cpy.x += pipe_ctx->plane_state->src_rect.x;
-               pos_cpy.y += pipe_ctx->plane_state->src_rect.y;
-       }
-
-       if (pipe_ctx->plane_state->address.type
-                       == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
-               pos_cpy.enable = false;
-
-       if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
-               pos_cpy.enable = false;
-
-       if (ipp->funcs->ipp_cursor_set_position)
-               ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
-       if (mi->funcs->set_cursor_position)
-               mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
-}
-
-static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
-
-       if (pipe_ctx->plane_res.ipp &&
-           pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
-               pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
-                               pipe_ctx->plane_res.ipp, attributes);
-
-       if (pipe_ctx->plane_res.mi &&
-           pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
-               pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
-                               pipe_ctx->plane_res.mi, attributes);
-
-       if (pipe_ctx->plane_res.xfm &&
-           pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
-               pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
-                               pipe_ctx->plane_res.xfm, attributes);
-}
-
-bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
-               uint32_t backlight_pwm_u16_16,
-               uint32_t frame_ramp)
-{
-       struct dc_link *link = pipe_ctx->stream->link;
-       struct dc  *dc = link->ctx->dc;
-       struct abm *abm = pipe_ctx->stream_res.abm;
-       struct panel_cntl *panel_cntl = link->panel_cntl;
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-       bool fw_set_brightness = true;
-       /* DMCU -1 for all controller id values,
-        * therefore +1 here
-        */
-       uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
-
-       if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
-               return false;
-
-       if (dmcu)
-               fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
-
-       if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
-               panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
-       else
-               abm->funcs->set_backlight_level_pwm(
-                               abm,
-                               backlight_pwm_u16_16,
-                               frame_ramp,
-                               controller_id,
-                               link->panel_cntl->inst);
-
-       return true;
-}
-
-void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
-{
-       struct abm *abm = pipe_ctx->stream_res.abm;
-       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
-
-       if (abm)
-               abm->funcs->set_abm_immediate_disable(abm,
-                               pipe_ctx->stream->link->panel_cntl->inst);
-
-       if (panel_cntl)
-               panel_cntl->funcs->store_backlight_level(panel_cntl);
-}
-
-void dce110_set_pipe(struct pipe_ctx *pipe_ctx)
-{
-       struct abm *abm = pipe_ctx->stream_res.abm;
-       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
-       uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1;
-
-       if (abm && panel_cntl)
-               abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst);
-}
-
-void dce110_enable_lvds_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum clock_source_id clock_source,
-               uint32_t pixel_clock)
-{
-       link->link_enc->funcs->enable_lvds_output(
-                       link->link_enc,
-                       clock_source,
-                       pixel_clock);
-       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-}
-
-void dce110_enable_tmds_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal,
-               enum clock_source_id clock_source,
-               enum dc_color_depth color_depth,
-               uint32_t pixel_clock)
-{
-       link->link_enc->funcs->enable_tmds_output(
-                       link->link_enc,
-                       clock_source,
-                       color_depth,
-                       signal,
-                       pixel_clock);
-       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-}
-
-void dce110_enable_dp_link_output(
-               struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal,
-               enum clock_source_id clock_source,
-               const struct dc_link_settings *link_settings)
-{
-       struct dc  *dc = link->ctx->dc;
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-       struct pipe_ctx *pipes =
-                       link->dc->current_state->res_ctx.pipe_ctx;
-       struct clock_source *dp_cs =
-                       link->dc->res_pool->dp_clock_source;
-       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
-       unsigned int i;
-
-       /*
-        * Add the logic to extract BOTH power up and power down sequences
-        * from enable/disable link output and only call edp panel control
-        * in enable_link_dp and disable_link_dp once.
-        */
-       if (link->connector_signal == SIGNAL_TYPE_EDP) {
-               link->dc->hwss.edp_wait_for_hpd_ready(link, true);
-       }
-
-       /* If the current pixel clock source is not DTO(happens after
-        * switching from HDMI passive dongle to DP on the same connector),
-        * switch the pixel clock source to DTO.
-        */
-
-       for (i = 0; i < MAX_PIPES; i++) {
-               if (pipes[i].stream != NULL &&
-                               pipes[i].stream->link == link) {
-                       if (pipes[i].clock_source != NULL &&
-                                       pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
-                               pipes[i].clock_source = dp_cs;
-                               pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
-                                               pipes[i].stream->timing.pix_clk_100hz;
-                               pipes[i].clock_source->funcs->program_pix_clk(
-                                               pipes[i].clock_source,
-                                               &pipes[i].stream_res.pix_clk_params,
-                                               dc->link_srv->dp_get_encoding_format(link_settings),
-                                               &pipes[i].pll_settings);
-                       }
-               }
-       }
-
-       if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
-               if (dc->clk_mgr->funcs->notify_link_rate_change)
-                       dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
-       }
-
-       if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->lock_phy(dmcu);
-
-       if (link_hwss->ext.enable_dp_link_output)
-               link_hwss->ext.enable_dp_link_output(link, link_res, signal,
-                               clock_source, link_settings);
-
-       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-
-       if (dmcu != NULL && dmcu->funcs->unlock_phy)
-               dmcu->funcs->unlock_phy(dmcu);
-
-       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
-}
-
-void dce110_disable_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal)
-{
-       struct dc *dc = link->ctx->dc;
-       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-
-       if (signal == SIGNAL_TYPE_EDP &&
-                       link->dc->hwss.edp_backlight_control)
-               link->dc->hwss.edp_backlight_control(link, false);
-       else if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->lock_phy(dmcu);
-
-       link_hwss->disable_link_output(link, link_res, signal);
-       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
-       /*
-        * Add the logic to extract BOTH power up and power down sequences
-        * from enable/disable link output and only call edp panel control
-        * in enable_link_dp and disable_link_dp once.
-        */
-       if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->unlock_phy(dmcu);
-       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
-}
-
-static const struct hw_sequencer_funcs dce110_funcs = {
-       .program_gamut_remap = program_gamut_remap,
-       .program_output_csc = program_output_csc,
-       .init_hw = init_hw,
-       .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
-       .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
-       .post_unlock_program_front_end = dce110_post_unlock_program_front_end,
-       .update_plane_addr = update_plane_addr,
-       .update_pending_status = dce110_update_pending_status,
-       .enable_accelerated_mode = dce110_enable_accelerated_mode,
-       .enable_timing_synchronization = dce110_enable_timing_synchronization,
-       .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
-       .update_info_frame = dce110_update_info_frame,
-       .enable_stream = dce110_enable_stream,
-       .disable_stream = dce110_disable_stream,
-       .unblank_stream = dce110_unblank_stream,
-       .blank_stream = dce110_blank_stream,
-       .enable_audio_stream = dce110_enable_audio_stream,
-       .disable_audio_stream = dce110_disable_audio_stream,
-       .disable_plane = dce110_power_down_fe,
-       .pipe_control_lock = dce_pipe_control_lock,
-       .interdependent_update_lock = NULL,
-       .cursor_lock = dce_pipe_control_lock,
-       .prepare_bandwidth = dce110_prepare_bandwidth,
-       .optimize_bandwidth = dce110_optimize_bandwidth,
-       .set_drr = set_drr,
-       .get_position = get_position,
-       .set_static_screen_control = set_static_screen_control,
-       .setup_stereo = NULL,
-       .set_avmute = dce110_set_avmute,
-       .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
-       .edp_backlight_control = dce110_edp_backlight_control,
-       .edp_power_control = dce110_edp_power_control,
-       .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
-       .set_cursor_position = dce110_set_cursor_position,
-       .set_cursor_attribute = dce110_set_cursor_attribute,
-       .set_backlight_level = dce110_set_backlight_level,
-       .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
-       .set_pipe = dce110_set_pipe,
-       .enable_lvds_link_output = dce110_enable_lvds_link_output,
-       .enable_tmds_link_output = dce110_enable_tmds_link_output,
-       .enable_dp_link_output = dce110_enable_dp_link_output,
-       .disable_link_output = dce110_disable_link_output,
-};
-
-static const struct hwseq_private_funcs dce110_private_funcs = {
-       .init_pipes = init_pipes,
-       .update_plane_addr = update_plane_addr,
-       .set_input_transfer_func = dce110_set_input_transfer_func,
-       .set_output_transfer_func = dce110_set_output_transfer_func,
-       .power_down = dce110_power_down,
-       .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
-       .enable_display_power_gating = dce110_enable_display_power_gating,
-       .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
-       .enable_stream_timing = dce110_enable_stream_timing,
-       .disable_stream_gating = NULL,
-       .enable_stream_gating = NULL,
-       .edp_backlight_control = dce110_edp_backlight_control,
-};
-
-void dce110_hw_sequencer_construct(struct dc *dc)
-{
-       dc->hwss = dce110_funcs;
-       dc->hwseq->funcs = dce110_private_funcs;
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
deleted file mode 100644 (file)
index 08028a1..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-* 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_HWSS_DCE110_H__
-#define __DC_HWSS_DCE110_H__
-
-#include "core_types.h"
-#include "hw_sequencer_private.h"
-
-struct dc;
-struct dc_state;
-struct dm_pp_display_configuration;
-
-void dce110_hw_sequencer_construct(struct dc *dc);
-
-enum dc_status dce110_apply_ctx_to_hw(
-               struct dc *dc,
-               struct dc_state *context);
-
-
-void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
-
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx);
-
-void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings);
-
-void dce110_blank_stream(struct pipe_ctx *pipe_ctx);
-
-void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx);
-void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx);
-
-void dce110_update_info_frame(struct pipe_ctx *pipe_ctx);
-
-void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
-void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context);
-
-void dce110_power_down(struct dc *dc);
-
-void dce110_set_safe_displaymarks(
-               struct resource_context *res_ctx,
-               const struct resource_pool *pool);
-
-void dce110_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-
-void dce110_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-
-void dce110_edp_power_control(
-               struct dc_link *link,
-               bool power_up);
-
-void dce110_edp_backlight_control(
-       struct dc_link *link,
-       bool enable);
-
-void dce110_edp_wait_for_hpd_ready(
-               struct dc_link *link,
-               bool power_up);
-
-bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
-               uint32_t backlight_pwm_u16_16,
-               uint32_t frame_ramp);
-void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
-void dce110_set_pipe(struct pipe_ctx *pipe_ctx);
-void dce110_disable_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal);
-void dce110_enable_lvds_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum clock_source_id clock_source,
-               uint32_t pixel_clock);
-void dce110_enable_tmds_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal,
-               enum clock_source_id clock_source,
-               enum dc_color_depth color_depth,
-               uint32_t pixel_clock);
-void dce110_enable_dp_link_output(
-               struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal,
-               enum clock_source_id clock_source,
-               const struct dc_link_settings *link_settings);
-#endif /* __DC_HWSS_DCE110_H__ */
-
index 1289b94..fe518fd 100644 (file)
@@ -46,7 +46,7 @@
 #include "dce110/dce110_opp_v.h"
 #include "dce/dce_clock_source.h"
 #include "dce/dce_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dce/dce_aux.h"
 #include "dce/dce_abm.h"
 #include "dce/dce_dmcu.h"
index 9de6501..e846ef5 100644 (file)
@@ -25,7 +25,7 @@
 
 CFLAGS_$(AMDDALPATH)/dc/dce112/dce112_resource.o = $(call cc-disable-warning, override-init)
 
-DCE112 = dce112_compressor.o dce112_hw_sequencer.o \
+DCE112 = dce112_compressor.o \
 dce112_resource.o
 
 AMD_DAL_DCE112 = $(addprefix $(AMDDALPATH)/dc/dce112/,$(DCE112))
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_hw_sequencer.c
deleted file mode 100644 (file)
index 0ef9ebb..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2015 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 "dm_services.h"
-#include "dc.h"
-#include "core_types.h"
-#include "dce112_hw_sequencer.h"
-
-#include "dce110/dce110_hw_sequencer.h"
-
-/* include DCE11.2 register header files */
-#include "dce/dce_11_2_d.h"
-#include "dce/dce_11_2_sh_mask.h"
-
-struct dce112_hw_seq_reg_offsets {
-       uint32_t crtc;
-};
-
-
-static const struct dce112_hw_seq_reg_offsets reg_offsets[] = {
-{
-       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-}
-};
-#define HW_REG_CRTC(reg, id)\
-       (reg + reg_offsets[id].crtc)
-
-/*******************************************************************************
- * Private definitions
- ******************************************************************************/
-
-static void dce112_init_pte(struct dc_context *ctx)
-{
-       uint32_t addr;
-       uint32_t value = 0;
-       uint32_t chunk_int = 0;
-       uint32_t chunk_mul = 0;
-
-       addr = mmDVMM_PTE_REQ;
-       value = dm_read_reg(ctx, addr);
-
-       chunk_int = get_reg_field_value(
-               value,
-               DVMM_PTE_REQ,
-               HFLIP_PTEREQ_PER_CHUNK_INT);
-
-       chunk_mul = get_reg_field_value(
-               value,
-               DVMM_PTE_REQ,
-               HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-
-       if (chunk_int != 0x4 || chunk_mul != 0x4) {
-
-               set_reg_field_value(
-                       value,
-                       255,
-                       DVMM_PTE_REQ,
-                       MAX_PTEREQ_TO_ISSUE);
-
-               set_reg_field_value(
-                       value,
-                       4,
-                       DVMM_PTE_REQ,
-                       HFLIP_PTEREQ_PER_CHUNK_INT);
-
-               set_reg_field_value(
-                       value,
-                       4,
-                       DVMM_PTE_REQ,
-                       HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-
-               dm_write_reg(ctx, addr, value);
-       }
-}
-
-static bool dce112_enable_display_power_gating(
-       struct dc *dc,
-       uint8_t controller_id,
-       struct dc_bios *dcb,
-       enum pipe_gating_control power_gating)
-{
-       enum bp_result bp_result = BP_RESULT_OK;
-       enum bp_pipe_control_action cntl;
-       struct dc_context *ctx = dc->ctx;
-
-       if (power_gating == PIPE_GATING_CONTROL_INIT)
-               cntl = ASIC_PIPE_INIT;
-       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
-               cntl = ASIC_PIPE_ENABLE;
-       else
-               cntl = ASIC_PIPE_DISABLE;
-
-       if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
-
-               bp_result = dcb->funcs->enable_disp_power_gating(
-                                               dcb, controller_id + 1, cntl);
-
-               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
-                * by default when command table is called
-                */
-               dm_write_reg(ctx,
-                       HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
-                       0);
-       }
-
-       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
-               dce112_init_pte(ctx);
-
-       if (bp_result == BP_RESULT_OK)
-               return true;
-       else
-               return false;
-}
-
-void dce112_hw_sequencer_construct(struct dc *dc)
-{
-       /* All registers used by dce11.2 match those in dce11 in offset and
-        * structure
-        */
-       dce110_hw_sequencer_construct(dc);
-       dc->hwseq->funcs.enable_display_power_gating = dce112_enable_display_power_gating;
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce112/dce112_hw_sequencer.h
deleted file mode 100644 (file)
index 943f1b2..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* 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_HWSS_DCE112_H__
-#define __DC_HWSS_DCE112_H__
-
-#include "core_types.h"
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dce112_hw_sequencer_construct(struct dc *dc);
-
-#endif /* __DC_HWSS_DCE112_H__ */
-
index 2b20180..d1edac4 100644 (file)
@@ -44,7 +44,7 @@
 #include "dce/dce_clock_source.h"
 
 #include "dce/dce_hwseq.h"
-#include "dce112/dce112_hw_sequencer.h"
+#include "dce112/dce112_hwseq.h"
 #include "dce/dce_abm.h"
 #include "dce/dce_dmcu.h"
 #include "dce/dce_aux.h"
index a9cc4b7..097cf40 100644 (file)
@@ -27,7 +27,6 @@
 CFLAGS_$(AMDDALPATH)/dc/dce120/dce120_resource.o = $(call cc-disable-warning, override-init)
 
 DCE120 = dce120_resource.o dce120_timing_generator.o \
-dce120_hw_sequencer.o
 
 AMD_DAL_DCE120 = $(addprefix $(AMDDALPATH)/dc/dce120/,$(DCE120))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
deleted file mode 100644 (file)
index 45e08c4..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2015 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 "dm_services.h"
-#include "dc.h"
-#include "core_types.h"
-#include "dce120_hw_sequencer.h"
-#include "dce/dce_hwseq.h"
-
-#include "dce110/dce110_hw_sequencer.h"
-
-#include "dce/dce_12_0_offset.h"
-#include "dce/dce_12_0_sh_mask.h"
-#include "soc15_hw_ip.h"
-#include "vega10_ip_offset.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
-
-struct dce120_hw_seq_reg_offsets {
-       uint32_t crtc;
-};
-
-#if 0
-static const struct dce120_hw_seq_reg_offsets reg_offsets[] = {
-{
-       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-},
-{
-       .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-}
-};
-
-#define HW_REG_CRTC(reg, id)\
-       (reg + reg_offsets[id].crtc)
-
-#define CNTL_ID(controller_id)\
-       controller_id
-/*******************************************************************************
- * Private definitions
- ******************************************************************************/
-static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id)
-{
-       uint32_t addr;
-       uint32_t value = 0;
-       uint32_t chunk_int = 0;
-       uint32_t chunk_mul = 0;
-/*
-       addr = mmDCP0_DVMM_PTE_CONTROL + controller_id *
-                       (mmDCP1_DVMM_PTE_CONTROL- mmDCP0_DVMM_PTE_CONTROL);
-
-       value = dm_read_reg(ctx, addr);
-
-       set_reg_field_value(
-                       value, 0, DCP, controller_id,
-                       DVMM_PTE_CONTROL,
-                       DVMM_USE_SINGLE_PTE);
-
-       set_reg_field_value_soc15(
-                       value, 1, DCP, controller_id,
-                       DVMM_PTE_CONTROL,
-                       DVMM_PTE_BUFFER_MODE0);
-
-       set_reg_field_value_soc15(
-                       value, 1, DCP, controller_id,
-                       DVMM_PTE_CONTROL,
-                       DVMM_PTE_BUFFER_MODE1);
-
-       dm_write_reg(ctx, addr, value);*/
-
-       addr = mmDVMM_PTE_REQ;
-       value = dm_read_reg(ctx, addr);
-
-       chunk_int = get_reg_field_value(
-               value,
-               DVMM_PTE_REQ,
-               HFLIP_PTEREQ_PER_CHUNK_INT);
-
-       chunk_mul = get_reg_field_value(
-               value,
-               DVMM_PTE_REQ,
-               HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-
-       if (chunk_int != 0x4 || chunk_mul != 0x4) {
-
-               set_reg_field_value(
-                       value,
-                       255,
-                       DVMM_PTE_REQ,
-                       MAX_PTEREQ_TO_ISSUE);
-
-               set_reg_field_value(
-                       value,
-                       4,
-                       DVMM_PTE_REQ,
-                       HFLIP_PTEREQ_PER_CHUNK_INT);
-
-               set_reg_field_value(
-                       value,
-                       4,
-                       DVMM_PTE_REQ,
-                       HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-
-               dm_write_reg(ctx, addr, value);
-       }
-}
-#endif
-
-static bool dce120_enable_display_power_gating(
-       struct dc *dc,
-       uint8_t controller_id,
-       struct dc_bios *dcb,
-       enum pipe_gating_control power_gating)
-{
-       /* disable for bringup */
-#if 0
-       enum bp_result bp_result = BP_RESULT_OK;
-       enum bp_pipe_control_action cntl;
-       struct dc_context *ctx = dc->ctx;
-
-       if (power_gating == PIPE_GATING_CONTROL_INIT)
-               cntl = ASIC_PIPE_INIT;
-       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
-               cntl = ASIC_PIPE_ENABLE;
-       else
-               cntl = ASIC_PIPE_DISABLE;
-
-       if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
-
-               bp_result = dcb->funcs->enable_disp_power_gating(
-                                               dcb, controller_id + 1, cntl);
-
-               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
-                * by default when command table is called
-                */
-               dm_write_reg(ctx,
-                       HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id),
-                       0);
-       }
-
-       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
-               dce120_init_pte(ctx, controller_id);
-
-       if (bp_result == BP_RESULT_OK)
-               return true;
-       else
-               return false;
-#endif
-       return false;
-}
-
-static void dce120_update_dchub(
-       struct dce_hwseq *hws,
-       struct dchub_init_data *dh_data)
-{
-       /* TODO: port code from dal2 */
-       switch (dh_data->fb_mode) {
-       case FRAME_BUFFER_MODE_ZFB_ONLY:
-               /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
-               REG_UPDATE_2(DCHUB_FB_LOCATION,
-                               FB_TOP, 0,
-                               FB_BASE, 0x0FFFF);
-
-               REG_UPDATE(DCHUB_AGP_BASE,
-                               AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
-
-               REG_UPDATE(DCHUB_AGP_BOT,
-                               AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
-
-               REG_UPDATE(DCHUB_AGP_TOP,
-                               AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
-               break;
-       case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
-               /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
-               REG_UPDATE(DCHUB_AGP_BASE,
-                               AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
-
-               REG_UPDATE(DCHUB_AGP_BOT,
-                               AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
-
-               REG_UPDATE(DCHUB_AGP_TOP,
-                               AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
-               break;
-       case FRAME_BUFFER_MODE_LOCAL_ONLY:
-               /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
-               REG_UPDATE(DCHUB_AGP_BASE,
-                               AGP_BASE, 0);
-
-               REG_UPDATE(DCHUB_AGP_BOT,
-                               AGP_BOT, 0x03FFFF);
-
-               REG_UPDATE(DCHUB_AGP_TOP,
-                               AGP_TOP, 0);
-               break;
-       default:
-               break;
-       }
-
-       dh_data->dchub_initialzied = true;
-       dh_data->dchub_info_valid = false;
-}
-
-/**
- * dce121_xgmi_enabled() - Check if xGMI is enabled
- * @hws: DCE hardware sequencer object
- *
- * Return true if xGMI is enabled. False otherwise.
- */
-bool dce121_xgmi_enabled(struct dce_hwseq *hws)
-{
-       uint32_t pf_max_region;
-
-       REG_GET(MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION, &pf_max_region);
-       /* PF_MAX_REGION == 0 means xgmi is disabled */
-       return !!pf_max_region;
-}
-
-void dce120_hw_sequencer_construct(struct dc *dc)
-{
-       /* All registers used by dce11.2 match those in dce11 in offset and
-        * structure
-        */
-       dce110_hw_sequencer_construct(dc);
-       dc->hwseq->funcs.enable_display_power_gating = dce120_enable_display_power_gating;
-       dc->hwss.update_dchub = dce120_update_dchub;
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.h
deleted file mode 100644 (file)
index bc02453..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-* 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_HWSS_DCE120_H__
-#define __DC_HWSS_DCE120_H__
-
-#include "core_types.h"
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-bool dce121_xgmi_enabled(struct dce_hwseq *hws);
-void dce120_hw_sequencer_construct(struct dc *dc);
-
-#endif /* __DC_HWSS_DCE112_H__ */
-
index 18c5a86..962de79 100644 (file)
@@ -35,7 +35,7 @@
 #include "dce112/dce112_resource.h"
 
 #include "dce110/dce110_resource.h"
-#include "../virtual/virtual_stream_encoder.h"
+#include "virtual/virtual_stream_encoder.h"
 #include "dce120_timing_generator.h"
 #include "irq/dce120/irq_service_dce120.h"
 #include "dce/dce_opp.h"
@@ -44,8 +44,8 @@
 #include "dce/dce_mem_input.h"
 #include "dce/dce_panel_cntl.h"
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dce120/dce120_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dce120/dce120_hwseq.h"
 #include "dce/dce_transform.h"
 #include "clk_mgr.h"
 #include "dce/dce_audio.h"
index 920c7ae..1fdeef4 100644 (file)
@@ -29,8 +29,8 @@
 #include "dce60_hw_sequencer.h"
 
 #include "dce/dce_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
-#include "dce100/dce100_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dce100/dce100_hwseq.h"
 
 /* include DCE6 register header files */
 #include "dce/dce_6_0_d.h"
index 0a9d1a3..93dd68c 100644 (file)
@@ -25,7 +25,7 @@
 
 CFLAGS_$(AMDDALPATH)/dc/dce80/dce80_resource.o = $(call cc-disable-warning, override-init)
 
-DCE80 = dce80_timing_generator.o dce80_hw_sequencer.o \
+DCE80 = dce80_timing_generator.o \
        dce80_resource.o
 
 AMD_DAL_DCE80 = $(addprefix $(AMDDALPATH)/dc/dce80/,$(DCE80))
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
deleted file mode 100644 (file)
index d2ceebd..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 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 "dm_services.h"
-#include "dc.h"
-#include "core_types.h"
-#include "dce80_hw_sequencer.h"
-
-#include "dce/dce_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
-#include "dce100/dce100_hw_sequencer.h"
-
-/* include DCE8 register header files */
-#include "dce/dce_8_0_d.h"
-#include "dce/dce_8_0_sh_mask.h"
-
-/*******************************************************************************
- * Private definitions
- ******************************************************************************/
-
-/***************************PIPE_CONTROL***********************************/
-
-void dce80_hw_sequencer_construct(struct dc *dc)
-{
-       dce110_hw_sequencer_construct(dc);
-
-       dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
-       dc->hwss.pipe_control_lock = dce_pipe_control_lock;
-       dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
-       dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.h
deleted file mode 100644 (file)
index e43af83..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* 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_HWSS_DCE80_H__
-#define __DC_HWSS_DCE80_H__
-
-#include "core_types.h"
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dce80_hw_sequencer_construct(struct dc *dc);
-
-#endif /* __DC_HWSS_DCE80_H__ */
-
index 0612213..35a2cce 100644 (file)
@@ -46,7 +46,7 @@
 #include "dce/dce_clock_source.h"
 #include "dce/dce_audio.h"
 #include "dce/dce_hwseq.h"
-#include "dce80/dce80_hw_sequencer.h"
+#include "dce80/dce80_hwseq.h"
 #include "dce100/dce100_resource.h"
 #include "dce/dce_panel_cntl.h"
 
index 62ad1a1..2d2007c 100644 (file)
@@ -22,7 +22,7 @@
 #
 # Makefile for DCN.
 
-DCN10 = dcn10_init.o dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
+DCN10 = dcn10_init.o dcn10_resource.o dcn10_ipp.o \
                dcn10_hw_sequencer_debug.o \
                dcn10_dpp.o dcn10_opp.o dcn10_optc.o \
                dcn10_hubp.o dcn10_mpc.o \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
deleted file mode 100644 (file)
index 817827f..0000000
+++ /dev/null
@@ -1,3898 +0,0 @@
-/*
- * 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 <linux/delay.h>
-#include "dm_services.h"
-#include "basics/dc_common.h"
-#include "core_types.h"
-#include "resource.h"
-#include "custom_float.h"
-#include "dcn10_hw_sequencer.h"
-#include "dcn10_hw_sequencer_debug.h"
-#include "dce/dce_hwseq.h"
-#include "abm.h"
-#include "dmcu.h"
-#include "dcn10_optc.h"
-#include "dcn10_dpp.h"
-#include "dcn10_mpc.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "reg_helper.h"
-#include "dcn10_hubp.h"
-#include "dcn10_hubbub.h"
-#include "dcn10_cm_common.h"
-#include "dccg.h"
-#include "clk_mgr.h"
-#include "link_hwss.h"
-#include "dpcd_defs.h"
-#include "dsc.h"
-#include "dce/dmub_psr.h"
-#include "dc_dmub_srv.h"
-#include "dce/dmub_hw_lock_mgr.h"
-#include "dc_trace.h"
-#include "dce/dmub_outbox.h"
-#include "link.h"
-
-#define DC_LOGGER \
-       dc_logger
-#define DC_LOGGER_INIT(logger) \
-       struct dal_logger *dc_logger = logger
-
-#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
-
-/*print is 17 wide, first two characters are spaces*/
-#define DTN_INFO_MICRO_SEC(ref_cycle) \
-       print_microsec(dc_ctx, log_ctx, ref_cycle)
-
-#define GAMMA_HW_POINTS_NUM 256
-
-#define PGFSM_POWER_ON 0
-#define PGFSM_POWER_OFF 2
-
-static void print_microsec(struct dc_context *dc_ctx,
-                          struct dc_log_buffer_ctx *log_ctx,
-                          uint32_t ref_cycle)
-{
-       const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
-       static const unsigned int frac = 1000;
-       uint32_t us_x10 = (ref_cycle * frac) / ref_clk_mhz;
-
-       DTN_INFO("  %11d.%03d",
-                       us_x10 / frac,
-                       us_x10 % frac);
-}
-
-void dcn10_lock_all_pipes(struct dc *dc,
-       struct dc_state *context,
-       bool lock)
-{
-       struct pipe_ctx *pipe_ctx;
-       struct pipe_ctx *old_pipe_ctx;
-       struct timing_generator *tg;
-       int i;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-               pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               tg = pipe_ctx->stream_res.tg;
-
-               /*
-                * Only lock the top pipe's tg to prevent redundant
-                * (un)locking. Also skip if pipe is disabled.
-                */
-               if (pipe_ctx->top_pipe ||
-                   !pipe_ctx->stream ||
-                   (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state) ||
-                   !tg->funcs->is_tg_enabled(tg) ||
-                       pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM)
-                       continue;
-
-               if (lock)
-                       dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
-               else
-                       dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
-       }
-}
-
-static void log_mpc_crc(struct dc *dc,
-       struct dc_log_buffer_ctx *log_ctx)
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       if (REG(MPC_CRC_RESULT_GB))
-               DTN_INFO("MPC_CRC_RESULT_GB:%d MPC_CRC_RESULT_C:%d MPC_CRC_RESULT_AR:%d\n",
-               REG_READ(MPC_CRC_RESULT_GB), REG_READ(MPC_CRC_RESULT_C), REG_READ(MPC_CRC_RESULT_AR));
-       if (REG(DPP_TOP0_DPP_CRC_VAL_B_A))
-               DTN_INFO("DPP_TOP0_DPP_CRC_VAL_B_A:%d DPP_TOP0_DPP_CRC_VAL_R_G:%d\n",
-               REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G));
-}
-
-static void dcn10_log_hubbub_state(struct dc *dc,
-                                  struct dc_log_buffer_ctx *log_ctx)
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct dcn_hubbub_wm wm;
-       int i;
-
-       memset(&wm, 0, sizeof(struct dcn_hubbub_wm));
-       dc->res_pool->hubbub->funcs->wm_read_state(dc->res_pool->hubbub, &wm);
-
-       DTN_INFO("HUBBUB WM:      data_urgent  pte_meta_urgent"
-                       "         sr_enter          sr_exit  dram_clk_change\n");
-
-       for (i = 0; i < 4; i++) {
-               struct dcn_hubbub_wm_set *s;
-
-               s = &wm.sets[i];
-               DTN_INFO("WM_Set[%d]:", s->wm_set);
-               DTN_INFO_MICRO_SEC(s->data_urgent);
-               DTN_INFO_MICRO_SEC(s->pte_meta_urgent);
-               DTN_INFO_MICRO_SEC(s->sr_enter);
-               DTN_INFO_MICRO_SEC(s->sr_exit);
-               DTN_INFO_MICRO_SEC(s->dram_clk_change);
-               DTN_INFO("\n");
-       }
-
-       DTN_INFO("\n");
-}
-
-static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct resource_pool *pool = dc->res_pool;
-       int i;
-
-       DTN_INFO(
-               "HUBP:  format  addr_hi  width  height  rot  mir  sw_mode  dcc_en  blank_en  clock_en  ttu_dis  underflow   min_ttu_vblank       qos_low_wm      qos_high_wm\n");
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct hubp *hubp = pool->hubps[i];
-               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
-
-               hubp->funcs->hubp_read_state(hubp);
-
-               if (!s->blank_en) {
-                       DTN_INFO("[%2d]:  %5xh  %6xh  %5d  %6d  %2xh  %2xh  %6xh  %6d  %8d  %8d  %7d  %8xh",
-                                       hubp->inst,
-                                       s->pixel_format,
-                                       s->inuse_addr_hi,
-                                       s->viewport_width,
-                                       s->viewport_height,
-                                       s->rotation_angle,
-                                       s->h_mirror_en,
-                                       s->sw_mode,
-                                       s->dcc_en,
-                                       s->blank_en,
-                                       s->clock_en,
-                                       s->ttu_disable,
-                                       s->underflow_status);
-                       DTN_INFO_MICRO_SEC(s->min_ttu_vblank);
-                       DTN_INFO_MICRO_SEC(s->qos_level_low_wm);
-                       DTN_INFO_MICRO_SEC(s->qos_level_high_wm);
-                       DTN_INFO("\n");
-               }
-       }
-
-       DTN_INFO("\n=========RQ========\n");
-       DTN_INFO("HUBP:  drq_exp_m  prq_exp_m  mrq_exp_m  crq_exp_m  plane1_ba  L:chunk_s  min_chu_s  meta_ch_s"
-               "  min_m_c_s  dpte_gr_s  mpte_gr_s  swath_hei  pte_row_h  C:chunk_s  min_chu_s  meta_ch_s"
-               "  min_m_c_s  dpte_gr_s  mpte_gr_s  swath_hei  pte_row_h\n");
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
-               struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
-
-               if (!s->blank_en)
-                       DTN_INFO("[%2d]:  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh\n",
-                               pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode,
-                               rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size,
-                               rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size,
-                               rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size,
-                               rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height,
-                               rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size,
-                               rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size,
-                               rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size,
-                               rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear);
-       }
-
-       DTN_INFO("========DLG========\n");
-       DTN_INFO("HUBP:  rc_hbe     dlg_vbe    min_d_y_n  rc_per_ht  rc_x_a_s "
-                       "  dst_y_a_s  dst_y_pf   dst_y_vvb  dst_y_rvb  dst_y_vfl  dst_y_rfl  rf_pix_fq"
-                       "  vratio_pf  vrat_pf_c  rc_pg_vbl  rc_pg_vbc  rc_mc_vbl  rc_mc_vbc  rc_pg_fll"
-                       "  rc_pg_flc  rc_mc_fll  rc_mc_flc  pr_nom_l   pr_nom_c   rc_pg_nl   rc_pg_nc "
-                       "  mr_nom_l   mr_nom_c   rc_mc_nl   rc_mc_nc   rc_ld_pl   rc_ld_pc   rc_ld_l  "
-                       "  rc_ld_c    cha_cur0   ofst_cur1  cha_cur1   vr_af_vc0  ddrq_limt  x_rt_dlay"
-                       "  x_rp_dlay  x_rr_sfl\n");
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
-               struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
-
-               if (!s->blank_en)
-                       DTN_INFO("[%2d]:  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh"
-                               "  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh"
-                               "  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh\n",
-                               pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start,
-                               dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler,
-                               dlg_regs->dst_y_prefetch, dlg_regs->dst_y_per_vm_vblank, dlg_regs->dst_y_per_row_vblank,
-                               dlg_regs->dst_y_per_vm_flip, dlg_regs->dst_y_per_row_flip, dlg_regs->ref_freq_to_pix_freq,
-                               dlg_regs->vratio_prefetch, dlg_regs->vratio_prefetch_c, dlg_regs->refcyc_per_pte_group_vblank_l,
-                               dlg_regs->refcyc_per_pte_group_vblank_c, dlg_regs->refcyc_per_meta_chunk_vblank_l,
-                               dlg_regs->refcyc_per_meta_chunk_vblank_c, dlg_regs->refcyc_per_pte_group_flip_l,
-                               dlg_regs->refcyc_per_pte_group_flip_c, dlg_regs->refcyc_per_meta_chunk_flip_l,
-                               dlg_regs->refcyc_per_meta_chunk_flip_c, dlg_regs->dst_y_per_pte_row_nom_l,
-                               dlg_regs->dst_y_per_pte_row_nom_c, dlg_regs->refcyc_per_pte_group_nom_l,
-                               dlg_regs->refcyc_per_pte_group_nom_c, dlg_regs->dst_y_per_meta_row_nom_l,
-                               dlg_regs->dst_y_per_meta_row_nom_c, dlg_regs->refcyc_per_meta_chunk_nom_l,
-                               dlg_regs->refcyc_per_meta_chunk_nom_c, dlg_regs->refcyc_per_line_delivery_pre_l,
-                               dlg_regs->refcyc_per_line_delivery_pre_c, dlg_regs->refcyc_per_line_delivery_l,
-                               dlg_regs->refcyc_per_line_delivery_c, dlg_regs->chunk_hdl_adjust_cur0, dlg_regs->dst_y_offset_cur1,
-                               dlg_regs->chunk_hdl_adjust_cur1, dlg_regs->vready_after_vcount0, dlg_regs->dst_y_delta_drq_limit,
-                               dlg_regs->xfc_reg_transfer_delay, dlg_regs->xfc_reg_precharge_delay,
-                               dlg_regs->xfc_reg_remote_surface_flip_latency);
-       }
-
-       DTN_INFO("========TTU========\n");
-       DTN_INFO("HUBP:  qos_ll_wm  qos_lh_wm  mn_ttu_vb  qos_l_flp  rc_rd_p_l  rc_rd_l    rc_rd_p_c"
-                       "  rc_rd_c    rc_rd_c0   rc_rd_pc0  rc_rd_c1   rc_rd_pc1  qos_lf_l   qos_rds_l"
-                       "  qos_lf_c   qos_rds_c  qos_lf_c0  qos_rds_c0 qos_lf_c1  qos_rds_c1\n");
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
-               struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr;
-
-               if (!s->blank_en)
-                       DTN_INFO("[%2d]:  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh\n",
-                               pool->hubps[i]->inst, ttu_regs->qos_level_low_wm, ttu_regs->qos_level_high_wm, ttu_regs->min_ttu_vblank,
-                               ttu_regs->qos_level_flip, ttu_regs->refcyc_per_req_delivery_pre_l, ttu_regs->refcyc_per_req_delivery_l,
-                               ttu_regs->refcyc_per_req_delivery_pre_c, ttu_regs->refcyc_per_req_delivery_c, ttu_regs->refcyc_per_req_delivery_cur0,
-                               ttu_regs->refcyc_per_req_delivery_pre_cur0, ttu_regs->refcyc_per_req_delivery_cur1,
-                               ttu_regs->refcyc_per_req_delivery_pre_cur1, ttu_regs->qos_level_fixed_l, ttu_regs->qos_ramp_disable_l,
-                               ttu_regs->qos_level_fixed_c, ttu_regs->qos_ramp_disable_c, ttu_regs->qos_level_fixed_cur0,
-                               ttu_regs->qos_ramp_disable_cur0, ttu_regs->qos_level_fixed_cur1, ttu_regs->qos_ramp_disable_cur1);
-       }
-       DTN_INFO("\n");
-}
-
-void dcn10_log_hw_state(struct dc *dc,
-       struct dc_log_buffer_ctx *log_ctx)
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct resource_pool *pool = dc->res_pool;
-       int i;
-
-       DTN_INFO_BEGIN();
-
-       dcn10_log_hubbub_state(dc, log_ctx);
-
-       dcn10_log_hubp_states(dc, log_ctx);
-
-       DTN_INFO("DPP:    IGAM format  IGAM mode    DGAM mode    RGAM mode"
-                       "  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24   "
-                       "C31 C32   C33 C34\n");
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct dpp *dpp = pool->dpps[i];
-               struct dcn_dpp_state s = {0};
-
-               dpp->funcs->dpp_read_state(dpp, &s);
-
-               if (!s.is_enabled)
-                       continue;
-
-               DTN_INFO("[%2d]:  %11xh  %-11s  %-11s  %-11s"
-                               "%8x    %08xh %08xh %08xh %08xh %08xh %08xh",
-                               dpp->inst,
-                               s.igam_input_format,
-                               (s.igam_lut_mode == 0) ? "BypassFixed" :
-                                       ((s.igam_lut_mode == 1) ? "BypassFloat" :
-                                       ((s.igam_lut_mode == 2) ? "RAM" :
-                                       ((s.igam_lut_mode == 3) ? "RAM" :
-                                                                "Unknown"))),
-                               (s.dgam_lut_mode == 0) ? "Bypass" :
-                                       ((s.dgam_lut_mode == 1) ? "sRGB" :
-                                       ((s.dgam_lut_mode == 2) ? "Ycc" :
-                                       ((s.dgam_lut_mode == 3) ? "RAM" :
-                                       ((s.dgam_lut_mode == 4) ? "RAM" :
-                                                                "Unknown")))),
-                               (s.rgam_lut_mode == 0) ? "Bypass" :
-                                       ((s.rgam_lut_mode == 1) ? "sRGB" :
-                                       ((s.rgam_lut_mode == 2) ? "Ycc" :
-                                       ((s.rgam_lut_mode == 3) ? "RAM" :
-                                       ((s.rgam_lut_mode == 4) ? "RAM" :
-                                                                "Unknown")))),
-                               s.gamut_remap_mode,
-                               s.gamut_remap_c11_c12,
-                               s.gamut_remap_c13_c14,
-                               s.gamut_remap_c21_c22,
-                               s.gamut_remap_c23_c24,
-                               s.gamut_remap_c31_c32,
-                               s.gamut_remap_c33_c34);
-               DTN_INFO("\n");
-       }
-       DTN_INFO("\n");
-
-       DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE\n");
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct mpcc_state s = {0};
-
-               pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
-               if (s.opp_id != 0xf)
-                       DTN_INFO("[%2d]:  %2xh  %2xh  %6xh  %4d  %10d  %7d  %12d  %4d\n",
-                               i, s.opp_id, s.dpp_id, s.bot_mpcc_id,
-                               s.mode, s.alpha_mode, s.pre_multiplied_alpha, s.overlap_only,
-                               s.idle);
-       }
-       DTN_INFO("\n");
-
-       DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
-
-       for (i = 0; i < pool->timing_generator_count; i++) {
-               struct timing_generator *tg = pool->timing_generators[i];
-               struct dcn_otg_state s = {0};
-               /* Read shared OTG state registers for all DCNx */
-               optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
-
-               /*
-                * For DCN2 and greater, a register on the OPP is used to
-                * determine if the CRTC is blanked instead of the OTG. So use
-                * dpg_is_blanked() if exists, otherwise fallback on otg.
-                *
-                * TODO: Implement DCN-specific read_otg_state hooks.
-                */
-               if (pool->opps[i]->funcs->dpg_is_blanked)
-                       s.blank_enabled = pool->opps[i]->funcs->dpg_is_blanked(pool->opps[i]);
-               else
-                       s.blank_enabled = tg->funcs->is_blanked(tg);
-
-               //only print if OTG master is enabled
-               if ((s.otg_enabled & 1) == 0)
-                       continue;
-
-               DTN_INFO("[%d]: %5d %5d %5d %5d %5d %5d %5d %9d %9d %5d %5d %5d %5d %5d %5d %5d  %9d %8d\n",
-                               tg->inst,
-                               s.v_blank_start,
-                               s.v_blank_end,
-                               s.v_sync_a_start,
-                               s.v_sync_a_end,
-                               s.v_sync_a_pol,
-                               s.v_total_max,
-                               s.v_total_min,
-                               s.v_total_max_sel,
-                               s.v_total_min_sel,
-                               s.h_blank_start,
-                               s.h_blank_end,
-                               s.h_sync_a_start,
-                               s.h_sync_a_end,
-                               s.h_sync_a_pol,
-                               s.h_total,
-                               s.v_total,
-                               s.underflow_occurred_status,
-                               s.blank_enabled);
-
-               // Clear underflow for debug purposes
-               // We want to keep underflow sticky bit on for the longevity tests outside of test environment.
-               // This function is called only from Windows or Diags test environment, hence it's safe to clear
-               // it from here without affecting the original intent.
-               tg->funcs->clear_optc_underflow(tg);
-       }
-       DTN_INFO("\n");
-
-       // dcn_dsc_state struct field bytes_per_pixel was renamed to bits_per_pixel
-       // TODO: Update golden log header to reflect this name change
-       DTN_INFO("DSC: CLOCK_EN  SLICE_WIDTH  Bytes_pp\n");
-       for (i = 0; i < pool->res_cap->num_dsc; i++) {
-               struct display_stream_compressor *dsc = pool->dscs[i];
-               struct dcn_dsc_state s = {0};
-
-               dsc->funcs->dsc_read_state(dsc, &s);
-               DTN_INFO("[%d]: %-9d %-12d %-10d\n",
-               dsc->inst,
-                       s.dsc_clock_en,
-                       s.dsc_slice_width,
-                       s.dsc_bits_per_pixel);
-               DTN_INFO("\n");
-       }
-       DTN_INFO("\n");
-
-       DTN_INFO("S_ENC: DSC_MODE  SEC_GSP7_LINE_NUM"
-                       "  VBID6_LINE_REFERENCE  VBID6_LINE_NUM  SEC_GSP7_ENABLE  SEC_STREAM_ENABLE\n");
-       for (i = 0; i < pool->stream_enc_count; i++) {
-               struct stream_encoder *enc = pool->stream_enc[i];
-               struct enc_state s = {0};
-
-               if (enc->funcs->enc_read_state) {
-                       enc->funcs->enc_read_state(enc, &s);
-                       DTN_INFO("[%-3d]: %-9d %-18d %-21d %-15d %-16d %-17d\n",
-                               enc->id,
-                               s.dsc_mode,
-                               s.sec_gsp_pps_line_num,
-                               s.vbid6_line_reference,
-                               s.vbid6_line_num,
-                               s.sec_gsp_pps_enable,
-                               s.sec_stream_enable);
-                       DTN_INFO("\n");
-               }
-       }
-       DTN_INFO("\n");
-
-       DTN_INFO("L_ENC: DPHY_FEC_EN  DPHY_FEC_READY_SHADOW  DPHY_FEC_ACTIVE_STATUS  DP_LINK_TRAINING_COMPLETE\n");
-       for (i = 0; i < dc->link_count; i++) {
-               struct link_encoder *lenc = dc->links[i]->link_enc;
-
-               struct link_enc_state s = {0};
-
-               if (lenc && lenc->funcs->read_state) {
-                       lenc->funcs->read_state(lenc, &s);
-                       DTN_INFO("[%-3d]: %-12d %-22d %-22d %-25d\n",
-                               i,
-                               s.dphy_fec_en,
-                               s.dphy_fec_ready_shadow,
-                               s.dphy_fec_active_status,
-                               s.dp_link_training_complete);
-                       DTN_INFO("\n");
-               }
-       }
-       DTN_INFO("\n");
-
-       DTN_INFO("\nCALCULATED Clocks: dcfclk_khz:%d  dcfclk_deep_sleep_khz:%d  dispclk_khz:%d\n"
-               "dppclk_khz:%d  max_supported_dppclk_khz:%d  fclk_khz:%d  socclk_khz:%d\n\n",
-                       dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz,
-                       dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz,
-                       dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz,
-                       dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz,
-                       dc->current_state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz,
-                       dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz,
-                       dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz);
-
-       log_mpc_crc(dc, log_ctx);
-
-       {
-               if (pool->hpo_dp_stream_enc_count > 0) {
-                       DTN_INFO("DP HPO S_ENC:  Enabled  OTG   Format   Depth   Vid   SDP   Compressed  Link\n");
-                       for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) {
-                               struct hpo_dp_stream_encoder_state hpo_dp_se_state = {0};
-                               struct hpo_dp_stream_encoder *hpo_dp_stream_enc = pool->hpo_dp_stream_enc[i];
-
-                               if (hpo_dp_stream_enc && hpo_dp_stream_enc->funcs->read_state) {
-                                       hpo_dp_stream_enc->funcs->read_state(hpo_dp_stream_enc, &hpo_dp_se_state);
-
-                                       DTN_INFO("[%d]:                 %d    %d   %6s       %d     %d     %d            %d     %d\n",
-                                                       hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0,
-                                                       hpo_dp_se_state.stream_enc_enabled,
-                                                       hpo_dp_se_state.otg_inst,
-                                                       (hpo_dp_se_state.pixel_encoding == 0) ? "4:4:4" :
-                                                                       ((hpo_dp_se_state.pixel_encoding == 1) ? "4:2:2" :
-                                                                       (hpo_dp_se_state.pixel_encoding == 2) ? "4:2:0" : "Y-Only"),
-                                                       (hpo_dp_se_state.component_depth == 0) ? 6 :
-                                                                       ((hpo_dp_se_state.component_depth == 1) ? 8 :
-                                                                       (hpo_dp_se_state.component_depth == 2) ? 10 : 12),
-                                                       hpo_dp_se_state.vid_stream_enabled,
-                                                       hpo_dp_se_state.sdp_enabled,
-                                                       hpo_dp_se_state.compressed_format,
-                                                       hpo_dp_se_state.mapped_to_link_enc);
-                               }
-                       }
-
-                       DTN_INFO("\n");
-               }
-
-               /* log DP HPO L_ENC section if any hpo_dp_link_enc exists */
-               if (pool->hpo_dp_link_enc_count) {
-                       DTN_INFO("DP HPO L_ENC:  Enabled  Mode   Lanes   Stream  Slots   VC Rate X    VC Rate Y\n");
-
-                       for (i = 0; i < pool->hpo_dp_link_enc_count; i++) {
-                               struct hpo_dp_link_encoder *hpo_dp_link_enc = pool->hpo_dp_link_enc[i];
-                               struct hpo_dp_link_enc_state hpo_dp_le_state = {0};
-
-                               if (hpo_dp_link_enc->funcs->read_state) {
-                                       hpo_dp_link_enc->funcs->read_state(hpo_dp_link_enc, &hpo_dp_le_state);
-                                       DTN_INFO("[%d]:                 %d  %6s     %d        %d      %d     %d     %d\n",
-                                                       hpo_dp_link_enc->inst,
-                                                       hpo_dp_le_state.link_enc_enabled,
-                                                       (hpo_dp_le_state.link_mode == 0) ? "TPS1" :
-                                                                       (hpo_dp_le_state.link_mode == 1) ? "TPS2" :
-                                                                       (hpo_dp_le_state.link_mode == 2) ? "ACTIVE" : "TEST",
-                                                       hpo_dp_le_state.lane_count,
-                                                       hpo_dp_le_state.stream_src[0],
-                                                       hpo_dp_le_state.slot_count[0],
-                                                       hpo_dp_le_state.vc_rate_x[0],
-                                                       hpo_dp_le_state.vc_rate_y[0]);
-                                       DTN_INFO("\n");
-                               }
-                       }
-
-                       DTN_INFO("\n");
-               }
-       }
-
-       DTN_INFO_END();
-}
-
-bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-
-       if (tg->funcs->is_optc_underflow_occurred(tg)) {
-               tg->funcs->clear_optc_underflow(tg);
-               return true;
-       }
-
-       if (hubp->funcs->hubp_get_underflow_status(hubp)) {
-               hubp->funcs->hubp_clear_underflow(hubp);
-               return true;
-       }
-       return false;
-}
-
-void dcn10_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable)
-{
-       bool force_on = true; /* disable power gating */
-
-       if (enable)
-               force_on = false;
-
-       /* DCHUBP0/1/2/3 */
-       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
-
-       /* DPP0/1/2/3 */
-       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
-}
-
-void dcn10_disable_vga(
-       struct dce_hwseq *hws)
-{
-       unsigned int in_vga1_mode = 0;
-       unsigned int in_vga2_mode = 0;
-       unsigned int in_vga3_mode = 0;
-       unsigned int in_vga4_mode = 0;
-
-       REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode);
-       REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode);
-       REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode);
-       REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode);
-
-       if (in_vga1_mode == 0 && in_vga2_mode == 0 &&
-                       in_vga3_mode == 0 && in_vga4_mode == 0)
-               return;
-
-       REG_WRITE(D1VGA_CONTROL, 0);
-       REG_WRITE(D2VGA_CONTROL, 0);
-       REG_WRITE(D3VGA_CONTROL, 0);
-       REG_WRITE(D4VGA_CONTROL, 0);
-
-       /* HW Engineer's Notes:
-        *  During switch from vga->extended, if we set the VGA_TEST_ENABLE and
-        *  then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly.
-        *
-        *  Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset
-        *  VGA_TEST_ENABLE, to leave it in the same state as before.
-        */
-       REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1);
-       REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
-}
-
-/**
- * dcn10_dpp_pg_control - DPP power gate control.
- *
- * @hws: dce_hwseq reference.
- * @dpp_inst: DPP instance reference.
- * @power_on: true if we want to enable power gate, false otherwise.
- *
- * Enable or disable power gate in the specific DPP instance.
- */
-void dcn10_dpp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dpp_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? PGFSM_POWER_ON : PGFSM_POWER_OFF;
-
-       if (hws->ctx->dc->debug.disable_dpp_power_gate)
-               return;
-       if (REG(DOMAIN1_PG_CONFIG) == 0)
-               return;
-
-       switch (dpp_inst) {
-       case 0: /* DPP0 */
-               REG_UPDATE(DOMAIN1_PG_CONFIG,
-                               DOMAIN1_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN1_PG_STATUS,
-                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DPP1 */
-               REG_UPDATE(DOMAIN3_PG_CONFIG,
-                               DOMAIN3_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN3_PG_STATUS,
-                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DPP2 */
-               REG_UPDATE(DOMAIN5_PG_CONFIG,
-                               DOMAIN5_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN5_PG_STATUS,
-                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DPP3 */
-               REG_UPDATE(DOMAIN7_PG_CONFIG,
-                               DOMAIN7_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN7_PG_STATUS,
-                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-/**
- * dcn10_hubp_pg_control - HUBP power gate control.
- *
- * @hws: dce_hwseq reference.
- * @hubp_inst: DPP instance reference.
- * @power_on: true if we want to enable power gate, false otherwise.
- *
- * Enable or disable power gate in the specific HUBP instance.
- */
-void dcn10_hubp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int hubp_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? PGFSM_POWER_ON : PGFSM_POWER_OFF;
-
-       if (hws->ctx->dc->debug.disable_hubp_power_gate)
-               return;
-       if (REG(DOMAIN0_PG_CONFIG) == 0)
-               return;
-
-       switch (hubp_inst) {
-       case 0: /* DCHUBP0 */
-               REG_UPDATE(DOMAIN0_PG_CONFIG,
-                               DOMAIN0_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN0_PG_STATUS,
-                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DCHUBP1 */
-               REG_UPDATE(DOMAIN2_PG_CONFIG,
-                               DOMAIN2_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN2_PG_STATUS,
-                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DCHUBP2 */
-               REG_UPDATE(DOMAIN4_PG_CONFIG,
-                               DOMAIN4_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN4_PG_STATUS,
-                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DCHUBP3 */
-               REG_UPDATE(DOMAIN6_PG_CONFIG,
-                               DOMAIN6_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN6_PG_STATUS,
-                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-static void power_on_plane_resources(
-       struct dce_hwseq *hws,
-       int plane_id)
-{
-       DC_LOGGER_INIT(hws->ctx->logger);
-
-       if (hws->funcs.dpp_root_clock_control)
-               hws->funcs.dpp_root_clock_control(hws, plane_id, true);
-
-       if (REG(DC_IP_REQUEST_CNTL)) {
-               REG_SET(DC_IP_REQUEST_CNTL, 0,
-                               IP_REQUEST_EN, 1);
-
-               if (hws->funcs.dpp_pg_control)
-                       hws->funcs.dpp_pg_control(hws, plane_id, true);
-
-               if (hws->funcs.hubp_pg_control)
-                       hws->funcs.hubp_pg_control(hws, plane_id, true);
-
-               REG_SET(DC_IP_REQUEST_CNTL, 0,
-                               IP_REQUEST_EN, 0);
-               DC_LOG_DEBUG(
-                               "Un-gated front end for pipe %d\n", plane_id);
-       }
-}
-
-static void undo_DEGVIDCN10_253_wa(struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = dc->res_pool->hubps[0];
-
-       if (!hws->wa_state.DEGVIDCN10_253_applied)
-               return;
-
-       hubp->funcs->set_blank(hubp, true);
-
-       REG_SET(DC_IP_REQUEST_CNTL, 0,
-                       IP_REQUEST_EN, 1);
-
-       hws->funcs.hubp_pg_control(hws, 0, false);
-       REG_SET(DC_IP_REQUEST_CNTL, 0,
-                       IP_REQUEST_EN, 0);
-
-       hws->wa_state.DEGVIDCN10_253_applied = false;
-}
-
-static void apply_DEGVIDCN10_253_wa(struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = dc->res_pool->hubps[0];
-       int i;
-
-       if (dc->debug.disable_stutter)
-               return;
-
-       if (!hws->wa.DEGVIDCN10_253)
-               return;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (!dc->res_pool->hubps[i]->power_gated)
-                       return;
-       }
-
-       /* all pipe power gated, apply work around to enable stutter. */
-
-       REG_SET(DC_IP_REQUEST_CNTL, 0,
-                       IP_REQUEST_EN, 1);
-
-       hws->funcs.hubp_pg_control(hws, 0, true);
-       REG_SET(DC_IP_REQUEST_CNTL, 0,
-                       IP_REQUEST_EN, 0);
-
-       hubp->funcs->set_hubp_blank_en(hubp, false);
-       hws->wa_state.DEGVIDCN10_253_applied = true;
-}
-
-void dcn10_bios_golden_init(struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *bp = dc->ctx->dc_bios;
-       int i;
-       bool allow_self_fresh_force_enable = true;
-
-       if (hws->funcs.s0i3_golden_init_wa && hws->funcs.s0i3_golden_init_wa(dc))
-               return;
-
-       if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
-               allow_self_fresh_force_enable =
-                               dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
-
-
-       /* WA for making DF sleep when idle after resume from S0i3.
-        * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
-        * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
-        * before calling command table and it changed to 1 after,
-        * it should be set back to 0.
-        */
-
-       /* initialize dcn global */
-       bp->funcs->enable_disp_power_gating(bp,
-                       CONTROLLER_ID_D0, ASIC_PIPE_INIT);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               /* initialize dcn per pipe */
-               bp->funcs->enable_disp_power_gating(bp,
-                               CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
-       }
-
-       if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
-               if (allow_self_fresh_force_enable == false &&
-                               dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub))
-                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
-                                                                               !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
-
-}
-
-static void false_optc_underflow_wa(
-               struct dc *dc,
-               const struct dc_stream_state *stream,
-               struct timing_generator *tg)
-{
-       int i;
-       bool underflow;
-
-       if (!dc->hwseq->wa.false_optc_underflow)
-               return;
-
-       underflow = tg->funcs->is_optc_underflow_occurred(tg);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               if (old_pipe_ctx->stream != stream)
-                       continue;
-
-               dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, old_pipe_ctx);
-       }
-
-       if (tg->funcs->set_blank_data_double_buffer)
-               tg->funcs->set_blank_data_double_buffer(tg, true);
-
-       if (tg->funcs->is_optc_underflow_occurred(tg) && !underflow)
-               tg->funcs->clear_optc_underflow(tg);
-}
-
-static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
-{
-       struct pipe_ctx *other_pipe;
-       int vready_offset = pipe->pipe_dlg_param.vready_offset;
-
-       /* Always use the largest vready_offset of all connected pipes */
-       for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-       for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-       for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-       for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-
-       return vready_offset;
-}
-
-enum dc_status dcn10_enable_stream_timing(
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context,
-               struct dc *dc)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-
-       /* by upper caller loop, pipe0 is parent pipe and be called first.
-        * back end is set up by for pipe0. Other children pipe share back end
-        * with pipe 0. No program is needed.
-        */
-       if (pipe_ctx->top_pipe != NULL)
-               return DC_OK;
-
-       /* TODO check if timing_changed, disable stream if timing changed */
-
-       /* HW program guide assume display already disable
-        * by unplug sequence. OTG assume stop.
-        */
-       pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, true);
-
-       if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
-                       pipe_ctx->clock_source,
-                       &pipe_ctx->stream_res.pix_clk_params,
-                       dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
-                       &pipe_ctx->pll_settings)) {
-               BREAK_TO_DEBUGGER();
-               return DC_ERROR_UNEXPECTED;
-       }
-
-       if (dc_is_hdmi_tmds_signal(stream->signal)) {
-               stream->link->phy_state.symclk_ref_cnts.otg = 1;
-               if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
-                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
-               else
-                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-       }
-
-       pipe_ctx->stream_res.tg->funcs->program_timing(
-                       pipe_ctx->stream_res.tg,
-                       &stream->timing,
-                       calculate_vready_offset_for_group(pipe_ctx),
-                       pipe_ctx->pipe_dlg_param.vstartup_start,
-                       pipe_ctx->pipe_dlg_param.vupdate_offset,
-                       pipe_ctx->pipe_dlg_param.vupdate_width,
-                       pipe_ctx->stream->signal,
-                       true);
-
-#if 0 /* move to after enable_crtc */
-       /* TODO: OPP FMT, ABM. etc. should be done here. */
-       /* or FPGA now. instance 0 only. TODO: move to opp.c */
-
-       inst_offset = reg_offsets[pipe_ctx->stream_res.tg->inst].fmt;
-
-       pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
-                               pipe_ctx->stream_res.opp,
-                               &stream->bit_depth_params,
-                               &stream->clamping);
-#endif
-       /* program otg blank color */
-       color_space = stream->output_color_space;
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       /*
-        * The way 420 is packed, 2 channels carry Y component, 1 channel
-        * alternate between Cb and Cr, so both channels need the pixel
-        * value for Y
-        */
-       if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-               black_color.color_r_cr = black_color.color_g_y;
-
-       if (pipe_ctx->stream_res.tg->funcs->set_blank_color)
-               pipe_ctx->stream_res.tg->funcs->set_blank_color(
-                               pipe_ctx->stream_res.tg,
-                               &black_color);
-
-       if (pipe_ctx->stream_res.tg->funcs->is_blanked &&
-                       !pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) {
-               pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
-               hwss_wait_for_blank_complete(pipe_ctx->stream_res.tg);
-               false_optc_underflow_wa(dc, pipe_ctx->stream, pipe_ctx->stream_res.tg);
-       }
-
-       /* VTG is  within DCHUB command block. DCFCLK is always on */
-       if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(pipe_ctx->stream_res.tg)) {
-               BREAK_TO_DEBUGGER();
-               return DC_ERROR_UNEXPECTED;
-       }
-
-       /* TODO program crtc source select for non-virtual signal*/
-       /* TODO program FMT */
-       /* TODO setup link_enc */
-       /* TODO set stream attributes */
-       /* TODO program audio */
-       /* TODO enable stream if timing changed */
-       /* TODO unblank stream if DP */
-
-       return DC_OK;
-}
-
-static void dcn10_reset_back_end_for_pipe(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context)
-{
-       int i;
-       struct dc_link *link;
-       DC_LOGGER_INIT(dc->ctx->logger);
-       if (pipe_ctx->stream_res.stream_enc == NULL) {
-               pipe_ctx->stream = NULL;
-               return;
-       }
-
-       link = pipe_ctx->stream->link;
-       /* DPMS may already disable or */
-       /* dpms_off status is incorrect due to fastboot
-        * feature. When system resume from S4 with second
-        * screen only, the dpms_off would be true but
-        * VBIOS lit up eDP, so check link status too.
-        */
-       if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
-               dc->link_srv->set_dpms_off(pipe_ctx);
-       else if (pipe_ctx->stream_res.audio)
-               dc->hwss.disable_audio_stream(pipe_ctx);
-
-       if (pipe_ctx->stream_res.audio) {
-               /*disable az_endpoint*/
-               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
-
-               /*free audio*/
-               if (dc->caps.dynamic_audio == true) {
-                       /*we have to dynamic arbitrate the audio endpoints*/
-                       /*we free the resource, need reset is_audio_acquired*/
-                       update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
-                                       pipe_ctx->stream_res.audio, false);
-                       pipe_ctx->stream_res.audio = NULL;
-               }
-       }
-
-       /* by upper caller loop, parent pipe: pipe0, will be reset last.
-        * back end share by all pipes and will be disable only when disable
-        * parent pipe.
-        */
-       if (pipe_ctx->top_pipe == NULL) {
-
-               if (pipe_ctx->stream_res.abm)
-                       dc->hwss.set_abm_immediate_disable(pipe_ctx);
-
-               pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
-
-               pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
-               if (pipe_ctx->stream_res.tg->funcs->set_drr)
-                       pipe_ctx->stream_res.tg->funcs->set_drr(
-                                       pipe_ctx->stream_res.tg, NULL);
-               pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (&dc->current_state->res_ctx.pipe_ctx[i] == pipe_ctx)
-                       break;
-
-       if (i == dc->res_pool->pipe_count)
-               return;
-
-       pipe_ctx->stream = NULL;
-       DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
-                                       pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
-}
-
-static bool dcn10_hw_wa_force_recovery(struct dc *dc)
-{
-       struct hubp *hubp ;
-       unsigned int i;
-       bool need_recover = true;
-
-       if (!dc->debug.recovery_enabled)
-               return false;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx != NULL) {
-                       hubp = pipe_ctx->plane_res.hubp;
-                       if (hubp != NULL && hubp->funcs->hubp_get_underflow_status) {
-                               if (hubp->funcs->hubp_get_underflow_status(hubp) != 0) {
-                                       /* one pipe underflow, we will reset all the pipes*/
-                                       need_recover = true;
-                               }
-                       }
-               }
-       }
-       if (!need_recover)
-               return false;
-       /*
-       DCHUBP_CNTL:HUBP_BLANK_EN=1
-       DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1
-       DCHUBP_CNTL:HUBP_DISABLE=1
-       DCHUBP_CNTL:HUBP_DISABLE=0
-       DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=0
-       DCSURF_PRIMARY_SURFACE_ADDRESS
-       DCHUBP_CNTL:HUBP_BLANK_EN=0
-       */
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx != NULL) {
-                       hubp = pipe_ctx->plane_res.hubp;
-                       /*DCHUBP_CNTL:HUBP_BLANK_EN=1*/
-                       if (hubp != NULL && hubp->funcs->set_hubp_blank_en)
-                               hubp->funcs->set_hubp_blank_en(hubp, true);
-               }
-       }
-       /*DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1*/
-       hubbub1_soft_reset(dc->res_pool->hubbub, true);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx != NULL) {
-                       hubp = pipe_ctx->plane_res.hubp;
-                       /*DCHUBP_CNTL:HUBP_DISABLE=1*/
-                       if (hubp != NULL && hubp->funcs->hubp_disable_control)
-                               hubp->funcs->hubp_disable_control(hubp, true);
-               }
-       }
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx != NULL) {
-                       hubp = pipe_ctx->plane_res.hubp;
-                       /*DCHUBP_CNTL:HUBP_DISABLE=0*/
-                       if (hubp != NULL && hubp->funcs->hubp_disable_control)
-                               hubp->funcs->hubp_disable_control(hubp, true);
-               }
-       }
-       /*DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=0*/
-       hubbub1_soft_reset(dc->res_pool->hubbub, false);
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx != NULL) {
-                       hubp = pipe_ctx->plane_res.hubp;
-                       /*DCHUBP_CNTL:HUBP_BLANK_EN=0*/
-                       if (hubp != NULL && hubp->funcs->set_hubp_blank_en)
-                               hubp->funcs->set_hubp_blank_en(hubp, true);
-               }
-       }
-       return true;
-
-}
-
-void dcn10_verify_allow_pstate_change_high(struct dc *dc)
-{
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       static bool should_log_hw_state; /* prevent hw state log by default */
-
-       if (!hubbub->funcs->verify_allow_pstate_change_high)
-               return;
-
-       if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) {
-               int i = 0;
-
-               if (should_log_hw_state)
-                       dcn10_log_hw_state(dc, NULL);
-
-               TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
-               BREAK_TO_DEBUGGER();
-               if (dcn10_hw_wa_force_recovery(dc)) {
-                       /*check again*/
-                       if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub))
-                               BREAK_TO_DEBUGGER();
-               }
-       }
-}
-
-/* trigger HW to start disconnect plane from stream on the next vsync */
-void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       int dpp_id = pipe_ctx->plane_res.dpp->inst;
-       struct mpc *mpc = dc->res_pool->mpc;
-       struct mpc_tree *mpc_tree_params;
-       struct mpcc *mpcc_to_remove = NULL;
-       struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
-
-       mpc_tree_params = &(opp->mpc_tree_params);
-       mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
-
-       /*Already reset*/
-       if (mpcc_to_remove == NULL)
-               return;
-
-       mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
-       // Phantom pipes have OTG disabled by default, so MPCC_STATUS will never assert idle,
-       // so don't wait for MPCC_IDLE in the programming sequence
-       if (opp != NULL && !pipe_ctx->plane_state->is_phantom)
-               opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-
-       dc->optimized_required = true;
-
-       if (hubp->funcs->hubp_disconnect)
-               hubp->funcs->hubp_disconnect(hubp);
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-}
-
-/**
- * dcn10_plane_atomic_power_down - Power down plane components.
- *
- * @dc: dc struct reference. used for grab hwseq.
- * @dpp: dpp struct reference.
- * @hubp: hubp struct reference.
- *
- * Keep in mind that this operation requires a power gate configuration;
- * however, requests for switch power gate are precisely controlled to avoid
- * problems. For this reason, power gate request is usually disabled. This
- * function first needs to enable the power gate request before disabling DPP
- * and HUBP. Finally, it disables the power gate request again.
- */
-void dcn10_plane_atomic_power_down(struct dc *dc,
-               struct dpp *dpp,
-               struct hubp *hubp)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       DC_LOGGER_INIT(dc->ctx->logger);
-
-       if (REG(DC_IP_REQUEST_CNTL)) {
-               REG_SET(DC_IP_REQUEST_CNTL, 0,
-                               IP_REQUEST_EN, 1);
-
-               if (hws->funcs.dpp_pg_control)
-                       hws->funcs.dpp_pg_control(hws, dpp->inst, false);
-
-               if (hws->funcs.hubp_pg_control)
-                       hws->funcs.hubp_pg_control(hws, hubp->inst, false);
-
-               dpp->funcs->dpp_reset(dpp);
-
-               REG_SET(DC_IP_REQUEST_CNTL, 0,
-                               IP_REQUEST_EN, 0);
-               DC_LOG_DEBUG(
-                               "Power gated front end %d\n", hubp->inst);
-       }
-
-       if (hws->funcs.dpp_root_clock_control)
-               hws->funcs.dpp_root_clock_control(hws, dpp->inst, false);
-}
-
-/* disable HW used by plane.
- * note:  cannot disable until disconnect is complete
- */
-void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-       int opp_id = hubp->opp_id;
-
-       dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
-
-       hubp->funcs->hubp_clk_cntl(hubp, false);
-
-       dpp->funcs->dpp_dppclk_control(dpp, false, false);
-
-       if (opp_id != 0xf && pipe_ctx->stream_res.opp->mpc_tree_params.opp_list == NULL)
-               pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
-                               pipe_ctx->stream_res.opp,
-                               false);
-
-       hubp->power_gated = true;
-       dc->optimized_required = false; /* We're powering off, no need to optimize */
-
-       hws->funcs.plane_atomic_power_down(dc,
-                       pipe_ctx->plane_res.dpp,
-                       pipe_ctx->plane_res.hubp);
-
-       pipe_ctx->stream = NULL;
-       memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
-       memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
-       pipe_ctx->top_pipe = NULL;
-       pipe_ctx->bottom_pipe = NULL;
-       pipe_ctx->plane_state = NULL;
-}
-
-void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       DC_LOGGER_INIT(dc->ctx->logger);
-
-       if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
-               return;
-
-       hws->funcs.plane_atomic_disable(dc, pipe_ctx);
-
-       apply_DEGVIDCN10_253_wa(dc);
-
-       DC_LOG_DC("Power down front end %d\n",
-                                       pipe_ctx->pipe_idx);
-}
-
-void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       bool can_apply_seamless_boot = false;
-
-       for (i = 0; i < context->stream_count; i++) {
-               if (context->streams[i]->apply_seamless_boot_optimization) {
-                       can_apply_seamless_boot = true;
-                       break;
-               }
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* There is assumption that pipe_ctx is not mapping irregularly
-                * to non-preferred front end. If pipe_ctx->stream is not NULL,
-                * we will use the pipe, so don't disable
-                */
-               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
-                       continue;
-
-               /* Blank controller using driver code instead of
-                * command table.
-                */
-               if (tg->funcs->is_tg_enabled(tg)) {
-                       if (hws->funcs.init_blank != NULL) {
-                               hws->funcs.init_blank(dc, tg);
-                               tg->funcs->lock(tg);
-                       } else {
-                               tg->funcs->lock(tg);
-                               tg->funcs->set_blank(tg, true);
-                               hwss_wait_for_blank_complete(tg);
-                       }
-               }
-       }
-
-       /* Reset det size */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = dc->res_pool->hubps[i];
-
-               /* Do not need to reset for seamless boot */
-               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
-                       continue;
-
-               if (hubbub && hubp) {
-                       if (hubbub->funcs->program_det_size)
-                               hubbub->funcs->program_det_size(hubbub, hubp->inst, 0);
-               }
-       }
-
-       /* num_opp will be equal to number of mpcc */
-       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* Cannot reset the MPC mux if seamless boot */
-               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
-                       continue;
-
-               dc->res_pool->mpc->funcs->mpc_init_single_inst(
-                               dc->res_pool->mpc, i);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct hubp *hubp = dc->res_pool->hubps[i];
-               struct dpp *dpp = dc->res_pool->dpps[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* There is assumption that pipe_ctx is not mapping irregularly
-                * to non-preferred front end. If pipe_ctx->stream is not NULL,
-                * we will use the pipe, so don't disable
-                */
-               if (can_apply_seamless_boot &&
-                       pipe_ctx->stream != NULL &&
-                       pipe_ctx->stream_res.tg->funcs->is_tg_enabled(
-                               pipe_ctx->stream_res.tg)) {
-                       // Enable double buffering for OTG_BLANK no matter if
-                       // seamless boot is enabled or not to suppress global sync
-                       // signals when OTG blanked. This is to prevent pipe from
-                       // requesting data while in PSR.
-                       tg->funcs->tg_init(tg);
-                       hubp->power_gated = true;
-                       continue;
-               }
-
-               /* Disable on the current state so the new one isn't cleared. */
-               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               dpp->funcs->dpp_reset(dpp);
-
-               pipe_ctx->stream_res.tg = tg;
-               pipe_ctx->pipe_idx = i;
-
-               pipe_ctx->plane_res.hubp = hubp;
-               pipe_ctx->plane_res.dpp = dpp;
-               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
-               hubp->mpcc_id = dpp->inst;
-               hubp->opp_id = OPP_ID_INVALID;
-               hubp->power_gated = false;
-
-               dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
-               dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-               dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-               pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
-
-               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       tg->funcs->unlock(tg);
-
-               dc->hwss.disable_plane(dc, pipe_ctx);
-
-               pipe_ctx->stream_res.tg = NULL;
-               pipe_ctx->plane_res.hubp = NULL;
-
-               if (tg->funcs->is_tg_enabled(tg)) {
-                       if (tg->funcs->init_odm)
-                               tg->funcs->init_odm(tg);
-               }
-
-               tg->funcs->tg_init(tg);
-       }
-
-       /* Power gate DSCs */
-       if (hws->funcs.dsc_pg_control != NULL) {
-               uint32_t num_opps = 0;
-               uint32_t opp_id_src0 = OPP_ID_INVALID;
-               uint32_t opp_id_src1 = OPP_ID_INVALID;
-
-               // Step 1: To find out which OPTC is running & OPTC DSC is ON
-               // We can't use res_pool->res_cap->num_timing_generator to check
-               // Because it records display pipes default setting built in driver,
-               // not display pipes of the current chip.
-               // Some ASICs would be fused display pipes less than the default setting.
-               // In dcnxx_resource_construct function, driver would obatin real information.
-               for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-                       uint32_t optc_dsc_state = 0;
-                       struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-                       if (tg->funcs->is_tg_enabled(tg)) {
-                               if (tg->funcs->get_dsc_status)
-                                       tg->funcs->get_dsc_status(tg, &optc_dsc_state);
-                               // Only one OPTC with DSC is ON, so if we got one result, we would exit this block.
-                               // non-zero value is DSC enabled
-                               if (optc_dsc_state != 0) {
-                                       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-                                       break;
-                               }
-                       }
-               }
-
-               // Step 2: To power down DSC but skip DSC  of running OPTC
-               for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
-                       struct dcn_dsc_state s  = {0};
-
-                       dc->res_pool->dscs[i]->funcs->dsc_read_state(dc->res_pool->dscs[i], &s);
-
-                       if ((s.dsc_opp_source == opp_id_src0 || s.dsc_opp_source == opp_id_src1) &&
-                               s.dsc_clock_en && s.dsc_fw_en)
-                               continue;
-
-                       hws->funcs.dsc_pg_control(hws, dc->res_pool->dscs[i]->inst, false);
-               }
-       }
-}
-
-void dcn10_init_hw(struct dc *dc)
-{
-       int i;
-       struct abm *abm = dc->res_pool->abm;
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       struct resource_pool *res_pool = dc->res_pool;
-       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-       bool   is_optimized_init_done = false;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       /* Align bw context with hw config when system resume. */
-       if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
-               dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz;
-               dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz;
-       }
-
-       // Initialize the dccg
-       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init)
-               dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       if (!dcb->funcs->is_accelerated_mode(dcb))
-               hws->funcs.disable_vga(dc->hwseq);
-
-       if (!dc_dmub_srv_optimized_init_done(dc->ctx->dmub_srv))
-               hws->funcs.bios_golden_init(dc);
-
-
-       if (dc->ctx->dc_bios->fw_info_valid) {
-               res_pool->ref_clocks.xtalin_clock_inKhz =
-                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-               if (res_pool->dccg && res_pool->hubbub) {
-
-                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-               } else {
-                       // Not all ASICs have DCCG sw component
-                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-               }
-       } else
-               ASSERT_CRITICAL(false);
-
-       for (i = 0; i < dc->link_count; i++) {
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector).
-                */
-               struct dc_link *link = dc->links[i];
-
-               if (!is_optimized_init_done)
-                       link->link_enc->funcs->hw_init(link->link_enc);
-
-               /* Check for enabled DIG to identify enabled display */
-               if (link->link_enc->funcs->is_dig_enabled &&
-                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
-                       link->link_status.link_active = true;
-                       if (link->link_enc->funcs->fec_is_active &&
-                                       link->link_enc->funcs->fec_is_active(link->link_enc))
-                               link->fec_state = dc_link_fec_enabled;
-               }
-       }
-
-       /* we want to turn off all dp displays before doing detection */
-       dc->link_srv->blank_all_dp_displays(dc);
-
-       if (hws->funcs.enable_power_gating_plane)
-               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
-
-       /* If taking control over from VBIOS, we may want to optimize our first
-        * mode set, so we need to skip powering down pipes until we know which
-        * pipes we want to use.
-        * Otherwise, if taking control is not possible, we need to power
-        * everything down.
-        */
-       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
-               if (!is_optimized_init_done) {
-                       hws->funcs.init_pipes(dc, dc->current_state);
-                       if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
-                               dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
-                                               !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
-               }
-       }
-
-       if (!is_optimized_init_done) {
-
-               for (i = 0; i < res_pool->audio_count; i++) {
-                       struct audio *audio = res_pool->audios[i];
-
-                       audio->funcs->hw_init(audio);
-               }
-
-               for (i = 0; i < dc->link_count; i++) {
-                       struct dc_link *link = dc->links[i];
-
-                       if (link->panel_cntl)
-                               backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
-               }
-
-               if (abm != NULL)
-                       abm->funcs->abm_init(abm, backlight);
-
-               if (dmcu != NULL && !dmcu->auto_load_dmcu)
-                       dmcu->funcs->dmcu_init(dmcu);
-       }
-
-       if (abm != NULL && dmcu != NULL)
-               abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
-
-       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       if (!is_optimized_init_done)
-               REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-       if (!dc->debug.disable_clock_gate) {
-               /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
-               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-       }
-
-       if (dc->clk_mgr->funcs->notify_wm_ranges)
-               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
-}
-
-/* In headless boot cases, DIG may be turned
- * on which causes HW/SW discrepancies.
- * To avoid this, power down hardware on boot
- * if DIG is turned on
- */
-void dcn10_power_down_on_boot(struct dc *dc)
-{
-       struct dc_link *edp_links[MAX_NUM_EDP];
-       struct dc_link *edp_link = NULL;
-       int edp_num;
-       int i = 0;
-
-       dc_get_edp_links(dc, edp_links, &edp_num);
-       if (edp_num)
-               edp_link = edp_links[0];
-
-       if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
-                       edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                       dc->hwseq->funcs.edp_backlight_control &&
-                       dc->hwss.power_down &&
-                       dc->hwss.edp_power_control) {
-               dc->hwseq->funcs.edp_backlight_control(edp_link, false);
-               dc->hwss.power_down(dc);
-               dc->hwss.edp_power_control(edp_link, false);
-       } else {
-               for (i = 0; i < dc->link_count; i++) {
-                       struct dc_link *link = dc->links[i];
-
-                       if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
-                                       link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
-                                       dc->hwss.power_down) {
-                               dc->hwss.power_down(dc);
-                               break;
-                       }
-
-               }
-       }
-
-       /*
-        * Call update_clocks with empty context
-        * to send DISPLAY_OFF
-        * Otherwise DISPLAY_OFF may not be asserted
-        */
-       if (dc->clk_mgr->funcs->set_low_power_state)
-               dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
-}
-
-void dcn10_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* Reset Back End*/
-       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
-               struct pipe_ctx *pipe_ctx_old =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (!pipe_ctx_old->stream)
-                       continue;
-
-               if (pipe_ctx_old->top_pipe)
-                       continue;
-
-               if (!pipe_ctx->stream ||
-                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
-                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
-
-                       dcn10_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
-                       if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
-                       if (old_clk)
-                               old_clk->funcs->cs_power_down(old_clk);
-               }
-       }
-}
-
-static bool patch_address_for_sbs_tb_stereo(
-               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
-{
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       bool sec_split = pipe_ctx->top_pipe &&
-                       pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
-       if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
-               (pipe_ctx->stream->timing.timing_3d_format ==
-                TIMING_3D_FORMAT_SIDE_BY_SIDE ||
-                pipe_ctx->stream->timing.timing_3d_format ==
-                TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
-               *addr = plane_state->address.grph_stereo.left_addr;
-               plane_state->address.grph_stereo.left_addr =
-               plane_state->address.grph_stereo.right_addr;
-               return true;
-       } else {
-               if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
-                       plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
-                       plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
-                       plane_state->address.grph_stereo.right_addr =
-                       plane_state->address.grph_stereo.left_addr;
-                       plane_state->address.grph_stereo.right_meta_addr =
-                       plane_state->address.grph_stereo.left_meta_addr;
-               }
-       }
-       return false;
-}
-
-void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       bool addr_patched = false;
-       PHYSICAL_ADDRESS_LOC addr;
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-
-       if (plane_state == NULL)
-               return;
-
-       addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
-
-       pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
-                       pipe_ctx->plane_res.hubp,
-                       &plane_state->address,
-                       plane_state->flip_immediate);
-
-       plane_state->status.requested_address = plane_state->address;
-
-       if (plane_state->flip_immediate)
-               plane_state->status.current_address = plane_state->address;
-
-       if (addr_patched)
-               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
-}
-
-bool dcn10_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_state *plane_state)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       const struct dc_transfer_func *tf = NULL;
-       bool result = true;
-
-       if (dpp_base == NULL)
-               return false;
-
-       if (plane_state->in_transfer_func)
-               tf = plane_state->in_transfer_func;
-
-       if (plane_state->gamma_correction &&
-               !dpp_base->ctx->dc->debug.always_use_regamma
-               && !plane_state->gamma_correction->is_identity
-                       && dce_use_lut(plane_state->format))
-               dpp_base->funcs->dpp_program_input_lut(dpp_base, plane_state->gamma_correction);
-
-       if (tf == NULL)
-               dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
-       else if (tf->type == TF_TYPE_PREDEFINED) {
-               switch (tf->tf) {
-               case TRANSFER_FUNCTION_SRGB:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_HW_sRGB);
-                       break;
-               case TRANSFER_FUNCTION_BT709:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_HW_xvYCC);
-                       break;
-               case TRANSFER_FUNCTION_LINEAR:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
-                       break;
-               case TRANSFER_FUNCTION_PQ:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_USER_PWL);
-                       cm_helper_translate_curve_to_degamma_hw_format(tf, &dpp_base->degamma_params);
-                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base, &dpp_base->degamma_params);
-                       result = true;
-                       break;
-               default:
-                       result = false;
-                       break;
-               }
-       } else if (tf->type == TF_TYPE_BYPASS) {
-               dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
-       } else {
-               cm_helper_translate_curve_to_degamma_hw_format(tf,
-                                       &dpp_base->degamma_params);
-               dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
-                               &dpp_base->degamma_params);
-               result = true;
-       }
-
-       return result;
-}
-
-#define MAX_NUM_HW_POINTS 0x200
-
-static void log_tf(struct dc_context *ctx,
-                               struct dc_transfer_func *tf, uint32_t hw_points_num)
-{
-       // DC_LOG_GAMMA is default logging of all hw points
-       // DC_LOG_ALL_GAMMA logs all points, not only hw points
-       // DC_LOG_ALL_TF_POINTS logs all channels of the tf
-       int i = 0;
-
-       DC_LOG_GAMMA("Gamma Correction TF");
-       DC_LOG_ALL_GAMMA("Logging all tf points...");
-       DC_LOG_ALL_TF_CHANNELS("Logging all channels...");
-
-       for (i = 0; i < hw_points_num; i++) {
-               DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
-               DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
-               DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
-       }
-
-       for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) {
-               DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
-               DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
-               DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
-       }
-}
-
-bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream)
-{
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-
-       if (dpp == NULL)
-               return false;
-
-       dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
-
-       if (stream->out_transfer_func &&
-           stream->out_transfer_func->type == TF_TYPE_PREDEFINED &&
-           stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB)
-               dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_SRGB);
-
-       /* dcn10_translate_regamma_to_hw_format takes 750us, only do it when full
-        * update.
-        */
-       else if (cm_helper_translate_curve_to_hw_format(dc->ctx,
-                       stream->out_transfer_func,
-                       &dpp->regamma_params, false)) {
-               dpp->funcs->dpp_program_regamma_pwl(
-                               dpp,
-                               &dpp->regamma_params, OPP_REGAMMA_USER);
-       } else
-               dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS);
-
-       if (stream != NULL && stream->ctx != NULL &&
-                       stream->out_transfer_func != NULL) {
-               log_tf(stream->ctx,
-                               stream->out_transfer_func,
-                               dpp->regamma_params.hw_points_num);
-       }
-
-       return true;
-}
-
-void dcn10_pipe_control_lock(
-       struct dc *dc,
-       struct pipe_ctx *pipe,
-       bool lock)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* use TG master update lock to lock everything on the TG
-        * therefore only top pipe need to lock
-        */
-       if (!pipe || pipe->top_pipe)
-               return;
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-
-       if (lock)
-               pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
-       else
-               pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-}
-
-/**
- * delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE.
- *
- * Software keepout workaround to prevent cursor update locking from stalling
- * out cursor updates indefinitely or from old values from being retained in
- * the case where the viewport changes in the same frame as the cursor.
- *
- * The idea is to calculate the remaining time from VPOS to VUPDATE. If it's
- * too close to VUPDATE, then stall out until VUPDATE finishes.
- *
- * TODO: Optimize cursor programming to be once per frame before VUPDATE
- *       to avoid the need for this workaround.
- *
- * @dc: Current DC state
- * @pipe_ctx: Pipe_ctx pointer for delayed cursor update
- *
- * Return: void
- */
-static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct crtc_position position;
-       uint32_t vupdate_start, vupdate_end;
-       unsigned int lines_to_vupdate, us_to_vupdate, vpos;
-       unsigned int us_per_line, us_vupdate;
-
-       if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position)
-               return;
-
-       if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg)
-               return;
-
-       dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start,
-                                      &vupdate_end);
-
-       dc->hwss.get_position(&pipe_ctx, 1, &position);
-       vpos = position.vertical_count;
-
-       /* Avoid wraparound calculation issues */
-       vupdate_start += stream->timing.v_total;
-       vupdate_end += stream->timing.v_total;
-       vpos += stream->timing.v_total;
-
-       if (vpos <= vupdate_start) {
-               /* VPOS is in VACTIVE or back porch. */
-               lines_to_vupdate = vupdate_start - vpos;
-       } else if (vpos > vupdate_end) {
-               /* VPOS is in the front porch. */
-               return;
-       } else {
-               /* VPOS is in VUPDATE. */
-               lines_to_vupdate = 0;
-       }
-
-       /* Calculate time until VUPDATE in microseconds. */
-       us_per_line =
-               stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
-       us_to_vupdate = lines_to_vupdate * us_per_line;
-
-       /* 70 us is a conservative estimate of cursor update time*/
-       if (us_to_vupdate > 70)
-               return;
-
-       /* Stall out until the cursor update completes. */
-       if (vupdate_end < vupdate_start)
-               vupdate_end += stream->timing.v_total;
-       us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
-       udelay(us_to_vupdate + us_vupdate);
-}
-
-void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
-{
-       /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
-       if (!pipe || pipe->top_pipe)
-               return;
-
-       /* Prevent cursor lock from stalling out cursor updates. */
-       if (lock)
-               delay_cursor_until_vupdate(dc, pipe);
-
-       if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) {
-               union dmub_hw_lock_flags hw_locks = { 0 };
-               struct dmub_hw_lock_inst_flags inst_flags = { 0 };
-
-               hw_locks.bits.lock_cursor = 1;
-               inst_flags.opp_inst = pipe->stream_res.opp->inst;
-
-               dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
-                                       lock,
-                                       &hw_locks,
-                                       &inst_flags);
-       } else
-               dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
-                               pipe->stream_res.opp->inst, lock);
-}
-
-static bool wait_for_reset_trigger_to_occur(
-       struct dc_context *dc_ctx,
-       struct timing_generator *tg)
-{
-       bool rc = false;
-
-       DC_LOGGER_INIT(dc_ctx->logger);
-
-       /* To avoid endless loop we wait at most
-        * frames_to_wait_on_triggered_reset frames for the reset to occur. */
-       const uint32_t frames_to_wait_on_triggered_reset = 10;
-       int i;
-
-       for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
-
-               if (!tg->funcs->is_counter_moving(tg)) {
-                       DC_ERROR("TG counter is not moving!\n");
-                       break;
-               }
-
-               if (tg->funcs->did_triggered_reset_occur(tg)) {
-                       rc = true;
-                       /* usually occurs at i=1 */
-                       DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
-                                       i);
-                       break;
-               }
-
-               /* Wait for one frame. */
-               tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
-               tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
-       }
-
-       if (false == rc)
-               DC_ERROR("GSL: Timeout on reset trigger!\n");
-
-       return rc;
-}
-
-static uint64_t reduceSizeAndFraction(uint64_t *numerator,
-                                     uint64_t *denominator,
-                                     bool checkUint32Bounary)
-{
-       int i;
-       bool ret = checkUint32Bounary == false;
-       uint64_t max_int32 = 0xffffffff;
-       uint64_t num, denom;
-       static const uint16_t prime_numbers[] = {
-               2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
-               47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
-               107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
-               167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
-               229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
-               283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353,
-               359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
-               431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487,
-               491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
-               571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
-               641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
-               709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773,
-               787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857,
-               859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
-               941, 947, 953, 967, 971, 977, 983, 991, 997};
-       int count = ARRAY_SIZE(prime_numbers);
-
-       num = *numerator;
-       denom = *denominator;
-       for (i = 0; i < count; i++) {
-               uint32_t num_remainder, denom_remainder;
-               uint64_t num_result, denom_result;
-               if (checkUint32Bounary &&
-                       num <= max_int32 && denom <= max_int32) {
-                       ret = true;
-                       break;
-               }
-               do {
-                       num_result = div_u64_rem(num, prime_numbers[i], &num_remainder);
-                       denom_result = div_u64_rem(denom, prime_numbers[i], &denom_remainder);
-                       if (num_remainder == 0 && denom_remainder == 0) {
-                               num = num_result;
-                               denom = denom_result;
-                       }
-               } while (num_remainder == 0 && denom_remainder == 0);
-       }
-       *numerator = num;
-       *denominator = denom;
-       return ret;
-}
-
-static bool is_low_refresh_rate(struct pipe_ctx *pipe)
-{
-       uint32_t master_pipe_refresh_rate =
-               pipe->stream->timing.pix_clk_100hz * 100 /
-               pipe->stream->timing.h_total /
-               pipe->stream->timing.v_total;
-       return master_pipe_refresh_rate <= 30;
-}
-
-static uint8_t get_clock_divider(struct pipe_ctx *pipe,
-                                bool account_low_refresh_rate)
-{
-       uint32_t clock_divider = 1;
-       uint32_t numpipes = 1;
-
-       if (account_low_refresh_rate && is_low_refresh_rate(pipe))
-               clock_divider *= 2;
-
-       if (pipe->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-               clock_divider *= 2;
-
-       while (pipe->next_odm_pipe) {
-               pipe = pipe->next_odm_pipe;
-               numpipes++;
-       }
-       clock_divider *= numpipes;
-
-       return clock_divider;
-}
-
-static int dcn10_align_pixel_clocks(struct dc *dc, int group_size,
-                                   struct pipe_ctx *grouped_pipes[])
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       int i, master = -1, embedded = -1;
-       struct dc_crtc_timing *hw_crtc_timing;
-       uint64_t phase[MAX_PIPES];
-       uint64_t modulo[MAX_PIPES];
-       unsigned int pclk;
-
-       uint32_t embedded_pix_clk_100hz;
-       uint16_t embedded_h_total;
-       uint16_t embedded_v_total;
-       uint32_t dp_ref_clk_100hz =
-               dc->res_pool->dp_clock_source->ctx->dc->clk_mgr->dprefclk_khz*10;
-
-       DC_LOGGER_INIT(dc_ctx->logger);
-
-       hw_crtc_timing = kcalloc(MAX_PIPES, sizeof(*hw_crtc_timing), GFP_KERNEL);
-       if (!hw_crtc_timing)
-               return master;
-
-       if (dc->config.vblank_alignment_dto_params &&
-               dc->res_pool->dp_clock_source->funcs->override_dp_pix_clk) {
-               embedded_h_total =
-                       (dc->config.vblank_alignment_dto_params >> 32) & 0x7FFF;
-               embedded_v_total =
-                       (dc->config.vblank_alignment_dto_params >> 48) & 0x7FFF;
-               embedded_pix_clk_100hz =
-                       dc->config.vblank_alignment_dto_params & 0xFFFFFFFF;
-
-               for (i = 0; i < group_size; i++) {
-                       grouped_pipes[i]->stream_res.tg->funcs->get_hw_timing(
-                                       grouped_pipes[i]->stream_res.tg,
-                                       &hw_crtc_timing[i]);
-                       dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
-                               dc->res_pool->dp_clock_source,
-                               grouped_pipes[i]->stream_res.tg->inst,
-                               &pclk);
-                       hw_crtc_timing[i].pix_clk_100hz = pclk;
-                       if (dc_is_embedded_signal(
-                                       grouped_pipes[i]->stream->signal)) {
-                               embedded = i;
-                               master = i;
-                               phase[i] = embedded_pix_clk_100hz*100;
-                               modulo[i] = dp_ref_clk_100hz*100;
-                       } else {
-
-                               phase[i] = (uint64_t)embedded_pix_clk_100hz*
-                                       hw_crtc_timing[i].h_total*
-                                       hw_crtc_timing[i].v_total;
-                               phase[i] = div_u64(phase[i], get_clock_divider(grouped_pipes[i], true));
-                               modulo[i] = (uint64_t)dp_ref_clk_100hz*
-                                       embedded_h_total*
-                                       embedded_v_total;
-
-                               if (reduceSizeAndFraction(&phase[i],
-                                               &modulo[i], true) == false) {
-                                       /*
-                                        * this will help to stop reporting
-                                        * this timing synchronizable
-                                        */
-                                       DC_SYNC_INFO("Failed to reduce DTO parameters\n");
-                                       grouped_pipes[i]->stream->has_non_synchronizable_pclk = true;
-                               }
-                       }
-               }
-
-               for (i = 0; i < group_size; i++) {
-                       if (i != embedded && !grouped_pipes[i]->stream->has_non_synchronizable_pclk) {
-                               dc->res_pool->dp_clock_source->funcs->override_dp_pix_clk(
-                                       dc->res_pool->dp_clock_source,
-                                       grouped_pipes[i]->stream_res.tg->inst,
-                                       phase[i], modulo[i]);
-                               dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
-                                       dc->res_pool->dp_clock_source,
-                                       grouped_pipes[i]->stream_res.tg->inst, &pclk);
-                               grouped_pipes[i]->stream->timing.pix_clk_100hz =
-                                       pclk*get_clock_divider(grouped_pipes[i], false);
-                               if (master == -1)
-                                       master = i;
-                       }
-               }
-
-       }
-
-       kfree(hw_crtc_timing);
-       return master;
-}
-
-void dcn10_enable_vblanks_synchronization(
-       struct dc *dc,
-       int group_index,
-       int group_size,
-       struct pipe_ctx *grouped_pipes[])
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct output_pixel_processor *opp;
-       struct timing_generator *tg;
-       int i, width, height, master;
-
-       DC_LOGGER_INIT(dc_ctx->logger);
-
-       for (i = 1; i < group_size; i++) {
-               opp = grouped_pipes[i]->stream_res.opp;
-               tg = grouped_pipes[i]->stream_res.tg;
-               tg->funcs->get_otg_active_size(tg, &width, &height);
-
-               if (!tg->funcs->is_tg_enabled(tg)) {
-                       DC_SYNC_INFO("Skipping timing sync on disabled OTG\n");
-                       return;
-               }
-
-               if (opp->funcs->opp_program_dpg_dimensions)
-                       opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1);
-       }
-
-       for (i = 0; i < group_size; i++) {
-               if (grouped_pipes[i]->stream == NULL)
-                       continue;
-               grouped_pipes[i]->stream->vblank_synchronized = false;
-               grouped_pipes[i]->stream->has_non_synchronizable_pclk = false;
-       }
-
-       DC_SYNC_INFO("Aligning DP DTOs\n");
-
-       master = dcn10_align_pixel_clocks(dc, group_size, grouped_pipes);
-
-       DC_SYNC_INFO("Synchronizing VBlanks\n");
-
-       if (master >= 0) {
-               for (i = 0; i < group_size; i++) {
-                       if (i != master && !grouped_pipes[i]->stream->has_non_synchronizable_pclk)
-                               grouped_pipes[i]->stream_res.tg->funcs->align_vblanks(
-                                       grouped_pipes[master]->stream_res.tg,
-                                       grouped_pipes[i]->stream_res.tg,
-                                       grouped_pipes[master]->stream->timing.pix_clk_100hz,
-                                       grouped_pipes[i]->stream->timing.pix_clk_100hz,
-                                       get_clock_divider(grouped_pipes[master], false),
-                                       get_clock_divider(grouped_pipes[i], false));
-                       grouped_pipes[i]->stream->vblank_synchronized = true;
-               }
-               grouped_pipes[master]->stream->vblank_synchronized = true;
-               DC_SYNC_INFO("Sync complete\n");
-       }
-
-       for (i = 1; i < group_size; i++) {
-               opp = grouped_pipes[i]->stream_res.opp;
-               tg = grouped_pipes[i]->stream_res.tg;
-               tg->funcs->get_otg_active_size(tg, &width, &height);
-               if (opp->funcs->opp_program_dpg_dimensions)
-                       opp->funcs->opp_program_dpg_dimensions(opp, width, height);
-       }
-}
-
-void dcn10_enable_timing_synchronization(
-       struct dc *dc,
-       int group_index,
-       int group_size,
-       struct pipe_ctx *grouped_pipes[])
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       struct output_pixel_processor *opp;
-       struct timing_generator *tg;
-       int i, width, height;
-
-       DC_LOGGER_INIT(dc_ctx->logger);
-
-       DC_SYNC_INFO("Setting up OTG reset trigger\n");
-
-       for (i = 1; i < group_size; i++) {
-               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
-                       continue;
-
-               opp = grouped_pipes[i]->stream_res.opp;
-               tg = grouped_pipes[i]->stream_res.tg;
-               tg->funcs->get_otg_active_size(tg, &width, &height);
-
-               if (!tg->funcs->is_tg_enabled(tg)) {
-                       DC_SYNC_INFO("Skipping timing sync on disabled OTG\n");
-                       return;
-               }
-
-               if (opp->funcs->opp_program_dpg_dimensions)
-                       opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1);
-       }
-
-       for (i = 0; i < group_size; i++) {
-               if (grouped_pipes[i]->stream == NULL)
-                       continue;
-
-               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
-                       continue;
-
-               grouped_pipes[i]->stream->vblank_synchronized = false;
-       }
-
-       for (i = 1; i < group_size; i++) {
-               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
-                       continue;
-
-               grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
-                               grouped_pipes[i]->stream_res.tg,
-                               grouped_pipes[0]->stream_res.tg->inst);
-       }
-
-       DC_SYNC_INFO("Waiting for trigger\n");
-
-       /* Need to get only check 1 pipe for having reset as all the others are
-        * synchronized. Look at last pipe programmed to reset.
-        */
-
-       if (grouped_pipes[1]->stream && grouped_pipes[1]->stream->mall_stream_config.type != SUBVP_PHANTOM)
-               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[1]->stream_res.tg);
-
-       for (i = 1; i < group_size; i++) {
-               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
-                       continue;
-
-               grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
-                               grouped_pipes[i]->stream_res.tg);
-       }
-
-       for (i = 1; i < group_size; i++) {
-               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
-                       continue;
-
-               opp = grouped_pipes[i]->stream_res.opp;
-               tg = grouped_pipes[i]->stream_res.tg;
-               tg->funcs->get_otg_active_size(tg, &width, &height);
-               if (opp->funcs->opp_program_dpg_dimensions)
-                       opp->funcs->opp_program_dpg_dimensions(opp, width, height);
-       }
-
-       DC_SYNC_INFO("Sync complete\n");
-}
-
-void dcn10_enable_per_frame_crtc_position_reset(
-       struct dc *dc,
-       int group_size,
-       struct pipe_ctx *grouped_pipes[])
-{
-       struct dc_context *dc_ctx = dc->ctx;
-       int i;
-
-       DC_LOGGER_INIT(dc_ctx->logger);
-
-       DC_SYNC_INFO("Setting up\n");
-       for (i = 0; i < group_size; i++)
-               if (grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset)
-                       grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
-                                       grouped_pipes[i]->stream_res.tg,
-                                       0,
-                                       &grouped_pipes[i]->stream->triggered_crtc_reset);
-
-       DC_SYNC_INFO("Waiting for trigger\n");
-
-       for (i = 0; i < group_size; i++)
-               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
-
-       DC_SYNC_INFO("Multi-display sync is complete\n");
-}
-
-static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1,
-               struct vm_system_aperture_param *apt,
-               struct dce_hwseq *hws)
-{
-       PHYSICAL_ADDRESS_LOC physical_page_number;
-       uint32_t logical_addr_low;
-       uint32_t logical_addr_high;
-
-       REG_GET(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
-                       PHYSICAL_PAGE_NUMBER_MSB, &physical_page_number.high_part);
-       REG_GET(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
-                       PHYSICAL_PAGE_NUMBER_LSB, &physical_page_number.low_part);
-
-       REG_GET(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
-                       LOGICAL_ADDR, &logical_addr_low);
-
-       REG_GET(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
-                       LOGICAL_ADDR, &logical_addr_high);
-
-       apt->sys_default.quad_part =  physical_page_number.quad_part << 12;
-       apt->sys_low.quad_part =  (int64_t)logical_addr_low << 18;
-       apt->sys_high.quad_part =  (int64_t)logical_addr_high << 18;
-}
-
-/* Temporary read settings, future will get values from kmd directly */
-static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
-               struct vm_context0_param *vm0,
-               struct dce_hwseq *hws)
-{
-       PHYSICAL_ADDRESS_LOC fb_base;
-       PHYSICAL_ADDRESS_LOC fb_offset;
-       uint32_t fb_base_value;
-       uint32_t fb_offset_value;
-
-       REG_GET(DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, &fb_base_value);
-       REG_GET(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, &fb_offset_value);
-
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
-                       PAGE_DIRECTORY_ENTRY_HI32, &vm0->pte_base.high_part);
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
-                       PAGE_DIRECTORY_ENTRY_LO32, &vm0->pte_base.low_part);
-
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
-                       LOGICAL_PAGE_NUMBER_HI4, &vm0->pte_start.high_part);
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
-                       LOGICAL_PAGE_NUMBER_LO32, &vm0->pte_start.low_part);
-
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
-                       LOGICAL_PAGE_NUMBER_HI4, &vm0->pte_end.high_part);
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
-                       LOGICAL_PAGE_NUMBER_LO32, &vm0->pte_end.low_part);
-
-       REG_GET(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
-                       PHYSICAL_PAGE_ADDR_HI4, &vm0->fault_default.high_part);
-       REG_GET(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
-                       PHYSICAL_PAGE_ADDR_LO32, &vm0->fault_default.low_part);
-
-       /*
-        * The values in VM_CONTEXT0_PAGE_TABLE_BASE_ADDR is in UMA space.
-        * Therefore we need to do
-        * DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR
-        * - DCHUBBUB_SDPIF_FB_OFFSET + DCHUBBUB_SDPIF_FB_BASE
-        */
-       fb_base.quad_part = (uint64_t)fb_base_value << 24;
-       fb_offset.quad_part = (uint64_t)fb_offset_value << 24;
-       vm0->pte_base.quad_part += fb_base.quad_part;
-       vm0->pte_base.quad_part -= fb_offset.quad_part;
-}
-
-
-static void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp)
-{
-       struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
-       struct vm_system_aperture_param apt = {0};
-       struct vm_context0_param vm0 = {0};
-
-       mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
-       mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
-
-       hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt);
-       hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0);
-}
-
-static void dcn10_enable_plane(
-       struct dc *dc,
-       struct pipe_ctx *pipe_ctx,
-       struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-
-       if (dc->debug.sanity_checks) {
-               hws->funcs.verify_allow_pstate_change_high(dc);
-       }
-
-       undo_DEGVIDCN10_253_wa(dc);
-
-       power_on_plane_resources(dc->hwseq,
-               pipe_ctx->plane_res.hubp->inst);
-
-       /* enable DCFCLK current DCHUB */
-       pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
-
-       /* make sure OPP_PIPE_CLOCK_EN = 1 */
-       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
-                       pipe_ctx->stream_res.opp,
-                       true);
-
-       if (dc->config.gpu_vm_support)
-               dcn10_program_pte_vm(hws, pipe_ctx->plane_res.hubp);
-
-       if (dc->debug.sanity_checks) {
-               hws->funcs.verify_allow_pstate_change_high(dc);
-       }
-
-       if (!pipe_ctx->top_pipe
-               && pipe_ctx->plane_state
-               && pipe_ctx->plane_state->flip_int_enabled
-               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
-                       pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
-
-}
-
-void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
-{
-       int i = 0;
-       struct dpp_grph_csc_adjustment adjust;
-       memset(&adjust, 0, sizeof(adjust));
-       adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-
-
-       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
-               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
-                       adjust.temperature_matrix[i] =
-                               pipe_ctx->stream->gamut_remap_matrix.matrix[i];
-       } else if (pipe_ctx->plane_state &&
-                  pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) {
-               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
-                       adjust.temperature_matrix[i] =
-                               pipe_ctx->plane_state->gamut_remap_matrix.matrix[i];
-       }
-
-       pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
-}
-
-
-static bool dcn10_is_rear_mpo_fix_required(struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace)
-{
-       if (pipe_ctx->plane_state && pipe_ctx->plane_state->layer_index > 0 && is_rgb_cspace(colorspace)) {
-               if (pipe_ctx->top_pipe) {
-                       struct pipe_ctx *top = pipe_ctx->top_pipe;
-
-                       while (top->top_pipe)
-                               top = top->top_pipe; // Traverse to top pipe_ctx
-                       if (top->plane_state && top->plane_state->layer_index == 0)
-                               return true; // Front MPO plane not hidden
-               }
-       }
-       return false;
-}
-
-static void dcn10_set_csc_adjustment_rgb_mpo_fix(struct pipe_ctx *pipe_ctx, uint16_t *matrix)
-{
-       // Override rear plane RGB bias to fix MPO brightness
-       uint16_t rgb_bias = matrix[3];
-
-       matrix[3] = 0;
-       matrix[7] = 0;
-       matrix[11] = 0;
-       pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
-       matrix[3] = rgb_bias;
-       matrix[7] = rgb_bias;
-       matrix[11] = rgb_bias;
-}
-
-void dcn10_program_output_csc(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum dc_color_space colorspace,
-               uint16_t *matrix,
-               int opp_id)
-{
-       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
-               if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) {
-
-                       /* MPO is broken with RGB colorspaces when OCSC matrix
-                        * brightness offset >= 0 on DCN1 due to OCSC before MPC
-                        * Blending adds offsets from front + rear to rear plane
-                        *
-                        * Fix is to set RGB bias to 0 on rear plane, top plane
-                        * black value pixels add offset instead of rear + front
-                        */
-
-                       int16_t rgb_bias = matrix[3];
-                       // matrix[3/7/11] are all the same offset value
-
-                       if (rgb_bias > 0 && dcn10_is_rear_mpo_fix_required(pipe_ctx, colorspace)) {
-                               dcn10_set_csc_adjustment_rgb_mpo_fix(pipe_ctx, matrix);
-                       } else {
-                               pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
-                       }
-               }
-       } else {
-               if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL)
-                       pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
-       }
-}
-
-static void dcn10_update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state)
-{
-       struct dc_bias_and_scale bns_params = {0};
-
-       // program the input csc
-       dpp->funcs->dpp_setup(dpp,
-                       plane_state->format,
-                       EXPANSION_MODE_ZERO,
-                       plane_state->input_csc_color_matrix,
-                       plane_state->color_space,
-                       NULL);
-
-       //set scale and bias registers
-       build_prescale_params(&bns_params, plane_state);
-       if (dpp->funcs->dpp_program_bias_and_scale)
-               dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
-}
-
-void dcn10_update_visual_confirm_color(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               int mpcc_id)
-{
-       struct mpc *mpc = dc->res_pool->mpc;
-
-       if (mpc->funcs->set_bg_color) {
-               memcpy(&pipe_ctx->plane_state->visual_confirm_color, &(pipe_ctx->visual_confirm_color), sizeof(struct tg_color));
-               mpc->funcs->set_bg_color(mpc, &(pipe_ctx->visual_confirm_color), mpcc_id);
-       }
-}
-
-void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct mpcc_blnd_cfg blnd_cfg = {0};
-       bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
-       int mpcc_id;
-       struct mpcc *new_mpcc;
-       struct mpc *mpc = dc->res_pool->mpc;
-       struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
-
-       blnd_cfg.overlap_only = false;
-       blnd_cfg.global_gain = 0xff;
-
-       if (per_pixel_alpha) {
-               /* DCN1.0 has output CM before MPC which seems to screw with
-                * pre-multiplied alpha.
-                */
-               blnd_cfg.pre_multiplied_alpha = (is_rgb_cspace(
-                               pipe_ctx->stream->output_color_space)
-                                               && pipe_ctx->plane_state->pre_multiplied_alpha);
-               if (pipe_ctx->plane_state->global_alpha) {
-                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN;
-                       blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value;
-               } else {
-                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
-               }
-       } else {
-               blnd_cfg.pre_multiplied_alpha = false;
-               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
-       }
-
-       if (pipe_ctx->plane_state->global_alpha)
-               blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
-       else
-               blnd_cfg.global_alpha = 0xff;
-
-       /*
-        * TODO: remove hack
-        * Note: currently there is a bug in init_hw such that
-        * on resume from hibernate, BIOS sets up MPCC0, and
-        * we do mpcc_remove but the mpcc cannot go to idle
-        * after remove. This cause us to pick mpcc1 here,
-        * which causes a pstate hang for yet unknown reason.
-        */
-       mpcc_id = hubp->inst;
-
-       /* If there is no full update, don't need to touch MPC tree*/
-       if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
-               mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
-               dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
-               return;
-       }
-
-       /* check if this MPCC is already being used */
-       new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
-       /* remove MPCC if being used */
-       if (new_mpcc != NULL)
-               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, new_mpcc);
-       else
-               if (dc->debug.sanity_checks)
-                       mpc->funcs->assert_mpcc_idle_before_connect(
-                                       dc->res_pool->mpc, mpcc_id);
-
-       /* Call MPC to insert new plane */
-       new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
-                       mpc_tree_params,
-                       &blnd_cfg,
-                       NULL,
-                       NULL,
-                       hubp->inst,
-                       mpcc_id);
-       dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
-
-       ASSERT(new_mpcc != NULL);
-       hubp->opp_id = pipe_ctx->stream_res.opp->inst;
-       hubp->mpcc_id = mpcc_id;
-}
-
-static void update_scaler(struct pipe_ctx *pipe_ctx)
-{
-       bool per_pixel_alpha =
-                       pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
-
-       pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
-       pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP;
-       /* scaler configuration */
-       pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
-                       pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
-}
-
-static void dcn10_update_dchubp_dpp(
-       struct dc *dc,
-       struct pipe_ctx *pipe_ctx,
-       struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       struct plane_size size = plane_state->plane_size;
-       unsigned int compat_level = 0;
-       bool should_divided_by_2 = false;
-
-       /* depends on DML calculation, DPP clock value may change dynamically */
-       /* If request max dpp clk is lower than current dispclk, no need to
-        * divided by 2
-        */
-       if (plane_state->update_flags.bits.full_update) {
-
-               /* new calculated dispclk, dppclk are stored in
-                * context->bw_ctx.bw.dcn.clk.dispclk_khz / dppclk_khz. current
-                * dispclk, dppclk are from dc->clk_mgr->clks.dispclk_khz.
-                * dcn10_validate_bandwidth compute new dispclk, dppclk.
-                * dispclk will put in use after optimize_bandwidth when
-                * ramp_up_dispclk_with_dpp is called.
-                * there are two places for dppclk be put in use. One location
-                * is the same as the location as dispclk. Another is within
-                * update_dchubp_dpp which happens between pre_bandwidth and
-                * optimize_bandwidth.
-                * dppclk updated within update_dchubp_dpp will cause new
-                * clock values of dispclk and dppclk not be in use at the same
-                * time. when clocks are decreased, this may cause dppclk is
-                * lower than previous configuration and let pipe stuck.
-                * for example, eDP + external dp,  change resolution of DP from
-                * 1920x1080x144hz to 1280x960x60hz.
-                * before change: dispclk = 337889 dppclk = 337889
-                * change mode, dcn10_validate_bandwidth calculate
-                *                dispclk = 143122 dppclk = 143122
-                * update_dchubp_dpp be executed before dispclk be updated,
-                * dispclk = 337889, but dppclk use new value dispclk /2 =
-                * 168944. this will cause pipe pstate warning issue.
-                * solution: between pre_bandwidth and optimize_bandwidth, while
-                * dispclk is going to be decreased, keep dppclk = dispclk
-                **/
-               if (context->bw_ctx.bw.dcn.clk.dispclk_khz <
-                               dc->clk_mgr->clks.dispclk_khz)
-                       should_divided_by_2 = false;
-               else
-                       should_divided_by_2 =
-                                       context->bw_ctx.bw.dcn.clk.dppclk_khz <=
-                                       dc->clk_mgr->clks.dispclk_khz / 2;
-
-               dpp->funcs->dpp_dppclk_control(
-                               dpp,
-                               should_divided_by_2,
-                               true);
-
-               if (dc->res_pool->dccg)
-                       dc->res_pool->dccg->funcs->update_dpp_dto(
-                                       dc->res_pool->dccg,
-                                       dpp->inst,
-                                       pipe_ctx->plane_res.bw.dppclk_khz);
-               else
-                       dc->clk_mgr->clks.dppclk_khz = should_divided_by_2 ?
-                                               dc->clk_mgr->clks.dispclk_khz / 2 :
-                                                       dc->clk_mgr->clks.dispclk_khz;
-       }
-
-       /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
-        * VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
-        * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
-        */
-       if (plane_state->update_flags.bits.full_update) {
-               hubp->funcs->hubp_vtg_sel(hubp, pipe_ctx->stream_res.tg->inst);
-
-               hubp->funcs->hubp_setup(
-                       hubp,
-                       &pipe_ctx->dlg_regs,
-                       &pipe_ctx->ttu_regs,
-                       &pipe_ctx->rq_regs,
-                       &pipe_ctx->pipe_dlg_param);
-               hubp->funcs->hubp_setup_interdependent(
-                       hubp,
-                       &pipe_ctx->dlg_regs,
-                       &pipe_ctx->ttu_regs);
-       }
-
-       size.surface_size = pipe_ctx->plane_res.scl_data.viewport;
-
-       if (plane_state->update_flags.bits.full_update ||
-               plane_state->update_flags.bits.bpp_change)
-               dcn10_update_dpp(dpp, plane_state);
-
-       if (plane_state->update_flags.bits.full_update ||
-               plane_state->update_flags.bits.per_pixel_alpha_change ||
-               plane_state->update_flags.bits.global_alpha_change)
-               hws->funcs.update_mpcc(dc, pipe_ctx);
-
-       if (plane_state->update_flags.bits.full_update ||
-               plane_state->update_flags.bits.per_pixel_alpha_change ||
-               plane_state->update_flags.bits.global_alpha_change ||
-               plane_state->update_flags.bits.scaling_change ||
-               plane_state->update_flags.bits.position_change) {
-               update_scaler(pipe_ctx);
-       }
-
-       if (plane_state->update_flags.bits.full_update ||
-               plane_state->update_flags.bits.scaling_change ||
-               plane_state->update_flags.bits.position_change) {
-               hubp->funcs->mem_program_viewport(
-                       hubp,
-                       &pipe_ctx->plane_res.scl_data.viewport,
-                       &pipe_ctx->plane_res.scl_data.viewport_c);
-       }
-
-       if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
-               dc->hwss.set_cursor_position(pipe_ctx);
-               dc->hwss.set_cursor_attribute(pipe_ctx);
-
-               if (dc->hwss.set_cursor_sdr_white_level)
-                       dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
-       }
-
-       if (plane_state->update_flags.bits.full_update) {
-               /*gamut remap*/
-               dc->hwss.program_gamut_remap(pipe_ctx);
-
-               dc->hwss.program_output_csc(dc,
-                               pipe_ctx,
-                               pipe_ctx->stream->output_color_space,
-                               pipe_ctx->stream->csc_color_matrix.matrix,
-                               pipe_ctx->stream_res.opp->inst);
-       }
-
-       if (plane_state->update_flags.bits.full_update ||
-               plane_state->update_flags.bits.pixel_format_change ||
-               plane_state->update_flags.bits.horizontal_mirror_change ||
-               plane_state->update_flags.bits.rotation_change ||
-               plane_state->update_flags.bits.swizzle_change ||
-               plane_state->update_flags.bits.dcc_change ||
-               plane_state->update_flags.bits.bpp_change ||
-               plane_state->update_flags.bits.scaling_change ||
-               plane_state->update_flags.bits.plane_size_change) {
-               hubp->funcs->hubp_program_surface_config(
-                       hubp,
-                       plane_state->format,
-                       &plane_state->tiling_info,
-                       &size,
-                       plane_state->rotation,
-                       &plane_state->dcc,
-                       plane_state->horizontal_mirror,
-                       compat_level);
-       }
-
-       hubp->power_gated = false;
-
-       hws->funcs.update_plane_addr(dc, pipe_ctx);
-
-       if (is_pipe_tree_visible(pipe_ctx))
-               hubp->funcs->set_blank(hubp, false);
-}
-
-void dcn10_blank_pixel_data(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool blank)
-{
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-       struct stream_resource *stream_res = &pipe_ctx->stream_res;
-       struct dc_stream_state *stream = pipe_ctx->stream;
-
-       /* program otg blank color */
-       color_space = stream->output_color_space;
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       /*
-        * The way 420 is packed, 2 channels carry Y component, 1 channel
-        * alternate between Cb and Cr, so both channels need the pixel
-        * value for Y
-        */
-       if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-               black_color.color_r_cr = black_color.color_g_y;
-
-
-       if (stream_res->tg->funcs->set_blank_color)
-               stream_res->tg->funcs->set_blank_color(
-                               stream_res->tg,
-                               &black_color);
-
-       if (!blank) {
-               if (stream_res->tg->funcs->set_blank)
-                       stream_res->tg->funcs->set_blank(stream_res->tg, blank);
-               if (stream_res->abm) {
-                       dc->hwss.set_pipe(pipe_ctx);
-                       stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
-               }
-       } else {
-               dc->hwss.set_abm_immediate_disable(pipe_ctx);
-               if (stream_res->tg->funcs->set_blank) {
-                       stream_res->tg->funcs->wait_for_state(stream_res->tg, CRTC_STATE_VBLANK);
-                       stream_res->tg->funcs->set_blank(stream_res->tg, blank);
-               }
-       }
-}
-
-void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx)
-{
-       struct fixed31_32 multiplier = pipe_ctx->plane_state->hdr_mult;
-       uint32_t hw_mult = 0x1f000; // 1.0 default multiplier
-       struct custom_float_format fmt;
-
-       fmt.exponenta_bits = 6;
-       fmt.mantissa_bits = 12;
-       fmt.sign = true;
-
-
-       if (!dc_fixpt_eq(multiplier, dc_fixpt_from_int(0))) // check != 0
-               convert_to_custom_float_format(multiplier, &fmt, &hw_mult);
-
-       pipe_ctx->plane_res.dpp->funcs->dpp_set_hdr_multiplier(
-                       pipe_ctx->plane_res.dpp, hw_mult);
-}
-
-void dcn10_program_pipe(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-
-       if (pipe_ctx->top_pipe == NULL) {
-               bool blank = !is_pipe_tree_visible(pipe_ctx);
-
-               pipe_ctx->stream_res.tg->funcs->program_global_sync(
-                               pipe_ctx->stream_res.tg,
-                               calculate_vready_offset_for_group(pipe_ctx),
-                               pipe_ctx->pipe_dlg_param.vstartup_start,
-                               pipe_ctx->pipe_dlg_param.vupdate_offset,
-                               pipe_ctx->pipe_dlg_param.vupdate_width);
-
-               pipe_ctx->stream_res.tg->funcs->set_vtg_params(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
-
-               if (hws->funcs.setup_vupdate_interrupt)
-                       hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
-
-               hws->funcs.blank_pixel_data(dc, pipe_ctx, blank);
-       }
-
-       if (pipe_ctx->plane_state->update_flags.bits.full_update)
-               dcn10_enable_plane(dc, pipe_ctx, context);
-
-       dcn10_update_dchubp_dpp(dc, pipe_ctx, context);
-
-       hws->funcs.set_hdr_multiplier(pipe_ctx);
-
-       if (pipe_ctx->plane_state->update_flags.bits.full_update ||
-                       pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-                       pipe_ctx->plane_state->update_flags.bits.gamma_change)
-               hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
-
-       /* dcn10_translate_regamma_to_hw_format takes 750us to finish
-        * only do gamma programming for full update.
-        * TODO: This can be further optimized/cleaned up
-        * Always call this for now since it does memcmp inside before
-        * doing heavy calculation and programming
-        */
-       if (pipe_ctx->plane_state->update_flags.bits.full_update)
-               hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
-}
-
-void dcn10_wait_for_pending_cleared(struct dc *dc,
-               struct dc_state *context)
-{
-               struct pipe_ctx *pipe_ctx;
-               struct timing_generator *tg;
-               int i;
-
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       pipe_ctx = &context->res_ctx.pipe_ctx[i];
-                       tg = pipe_ctx->stream_res.tg;
-
-                       /*
-                        * Only wait for top pipe's tg penindg bit
-                        * Also skip if pipe is disabled.
-                        */
-                       if (pipe_ctx->top_pipe ||
-                           !pipe_ctx->stream || !pipe_ctx->plane_state ||
-                           !tg->funcs->is_tg_enabled(tg))
-                               continue;
-
-                       /*
-                        * Wait for VBLANK then VACTIVE to ensure we get VUPDATE.
-                        * For some reason waiting for OTG_UPDATE_PENDING cleared
-                        * seems to not trigger the update right away, and if we
-                        * lock again before VUPDATE then we don't get a separated
-                        * operation.
-                        */
-                       pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
-                       pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
-               }
-}
-
-void dcn10_post_unlock_program_front_end(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (!pipe_ctx->top_pipe &&
-                       !pipe_ctx->prev_odm_pipe &&
-                       pipe_ctx->stream) {
-                       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-
-                       if (context->stream_status[i].plane_count == 0)
-                               false_optc_underflow_wa(dc, pipe_ctx->stream, tg);
-               }
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
-                       dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) {
-                       dc->hwss.optimize_bandwidth(dc, context);
-                       break;
-               }
-
-       if (dc->hwseq->wa.DEGVIDCN10_254)
-               hubbub1_wm_change_req_wa(dc->res_pool->hubbub);
-}
-
-static void dcn10_stereo_hw_frame_pack_wa(struct dc *dc, struct dc_state *context)
-{
-       uint8_t i;
-
-       for (i = 0; i < context->stream_count; i++) {
-               if (context->streams[i]->timing.timing_3d_format
-                               == TIMING_3D_FORMAT_HW_FRAME_PACKING) {
-                       /*
-                        * Disable stutter
-                        */
-                       hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, false);
-                       break;
-               }
-       }
-}
-
-void dcn10_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       int min_fclk_khz, min_dcfclk_khz, socclk_khz;
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-
-       if (context->stream_count == 0)
-               context->bw_ctx.bw.dcn.clk.phyclk_khz = 0;
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       false);
-
-       dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
-                       &context->bw_ctx.bw.dcn.watermarks,
-                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
-                       true);
-       dcn10_stereo_hw_frame_pack_wa(dc, context);
-
-       if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
-               DC_FP_START();
-               dcn_get_soc_clks(
-                       dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
-               DC_FP_END();
-               dcn_bw_notify_pplib_of_wm_ranges(
-                       dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
-       }
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-}
-
-void dcn10_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       int min_fclk_khz, min_dcfclk_khz, socclk_khz;
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-
-       if (context->stream_count == 0)
-               context->bw_ctx.bw.dcn.clk.phyclk_khz = 0;
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       true);
-
-       hubbub->funcs->program_watermarks(hubbub,
-                       &context->bw_ctx.bw.dcn.watermarks,
-                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
-                       true);
-
-       dcn10_stereo_hw_frame_pack_wa(dc, context);
-
-       if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
-               DC_FP_START();
-               dcn_get_soc_clks(
-                       dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
-               DC_FP_END();
-               dcn_bw_notify_pplib_of_wm_ranges(
-                       dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
-       }
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-}
-
-void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
-               int num_pipes, struct dc_crtc_timing_adjust adjust)
-{
-       int i = 0;
-       struct drr_params params = {0};
-       // DRR set trigger event mapped to OTG_TRIG_A (bit 11) for manual control flow
-       unsigned int event_triggers = 0x800;
-       // Note DRR trigger events are generated regardless of whether num frames met.
-       unsigned int num_frames = 2;
-
-       params.vertical_total_max = adjust.v_total_max;
-       params.vertical_total_min = adjust.v_total_min;
-       params.vertical_total_mid = adjust.v_total_mid;
-       params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num;
-       /* TODO: If multiple pipes are to be supported, you need
-        * some GSL stuff. Static screen triggers may be programmed differently
-        * as well.
-        */
-       for (i = 0; i < num_pipes; i++) {
-               if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) {
-                       if (pipe_ctx[i]->stream_res.tg->funcs->set_drr)
-                               pipe_ctx[i]->stream_res.tg->funcs->set_drr(
-                                       pipe_ctx[i]->stream_res.tg, &params);
-                       if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
-                               if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control)
-                                       pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
-                                               pipe_ctx[i]->stream_res.tg,
-                                               event_triggers, num_frames);
-               }
-       }
-}
-
-void dcn10_get_position(struct pipe_ctx **pipe_ctx,
-               int num_pipes,
-               struct crtc_position *position)
-{
-       int i = 0;
-
-       /* TODO: handle pipes > 1
-        */
-       for (i = 0; i < num_pipes; i++)
-               pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
-}
-
-void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
-               int num_pipes, const struct dc_static_screen_params *params)
-{
-       unsigned int i;
-       unsigned int triggers = 0;
-
-       if (params->triggers.surface_update)
-               triggers |= 0x80;
-       if (params->triggers.cursor_update)
-               triggers |= 0x2;
-       if (params->triggers.force_trigger)
-               triggers |= 0x1;
-
-       for (i = 0; i < num_pipes; i++)
-               pipe_ctx[i]->stream_res.tg->funcs->
-                       set_static_screen_control(pipe_ctx[i]->stream_res.tg,
-                                       triggers, params->num_frames);
-}
-
-static void dcn10_config_stereo_parameters(
-               struct dc_stream_state *stream, struct crtc_stereo_flags *flags)
-{
-       enum view_3d_format view_format = stream->view_format;
-       enum dc_timing_3d_format timing_3d_format =\
-                       stream->timing.timing_3d_format;
-       bool non_stereo_timing = false;
-
-       if (timing_3d_format == TIMING_3D_FORMAT_NONE ||
-               timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE ||
-               timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM)
-               non_stereo_timing = true;
-
-       if (non_stereo_timing == false &&
-               view_format == VIEW_3D_FORMAT_FRAME_SEQUENTIAL) {
-
-               flags->PROGRAM_STEREO         = 1;
-               flags->PROGRAM_POLARITY       = 1;
-               if (timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE ||
-                       timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
-                       timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
-                       timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
-
-                       if (stream->link && stream->link->ddc) {
-                               enum display_dongle_type dongle = \
-                                               stream->link->ddc->dongle_type;
-
-                               if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
-                                       dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
-                                       dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
-                                       flags->DISABLE_STEREO_DP_SYNC = 1;
-                       }
-               }
-               flags->RIGHT_EYE_POLARITY =\
-                               stream->timing.flags.RIGHT_EYE_3D_POLARITY;
-               if (timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
-                       flags->FRAME_PACKED = 1;
-       }
-
-       return;
-}
-
-void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
-{
-       struct crtc_stereo_flags flags = { 0 };
-       struct dc_stream_state *stream = pipe_ctx->stream;
-
-       dcn10_config_stereo_parameters(stream, &flags);
-
-       if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
-               if (!dc_set_generic_gpio_for_stereo(true, dc->ctx->gpio_service))
-                       dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
-       } else {
-               dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
-       }
-
-       pipe_ctx->stream_res.opp->funcs->opp_program_stereo(
-               pipe_ctx->stream_res.opp,
-               flags.PROGRAM_STEREO == 1,
-               &stream->timing);
-
-       pipe_ctx->stream_res.tg->funcs->program_stereo(
-               pipe_ctx->stream_res.tg,
-               &stream->timing,
-               &flags);
-
-       return;
-}
-
-static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
-{
-       int i;
-
-       for (i = 0; i < res_pool->pipe_count; i++) {
-               if (res_pool->hubps[i]->inst == mpcc_inst)
-                       return res_pool->hubps[i];
-       }
-       ASSERT(false);
-       return NULL;
-}
-
-void dcn10_wait_for_mpcc_disconnect(
-               struct dc *dc,
-               struct resource_pool *res_pool,
-               struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       int mpcc_inst;
-
-       if (dc->debug.sanity_checks) {
-               hws->funcs.verify_allow_pstate_change_high(dc);
-       }
-
-       if (!pipe_ctx->stream_res.opp)
-               return;
-
-       for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
-               if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
-                       struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
-
-                       if (pipe_ctx->stream_res.tg &&
-                               pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg))
-                               res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
-                       pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
-                       hubp->funcs->set_blank(hubp, true);
-               }
-       }
-
-       if (dc->debug.sanity_checks) {
-               hws->funcs.verify_allow_pstate_change_high(dc);
-       }
-
-}
-
-bool dcn10_dummy_display_power_gating(
-       struct dc *dc,
-       uint8_t controller_id,
-       struct dc_bios *dcb,
-       enum pipe_gating_control power_gating)
-{
-       return true;
-}
-
-void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       bool flip_pending;
-       struct dc *dc = pipe_ctx->stream->ctx->dc;
-
-       if (plane_state == NULL)
-               return;
-
-       flip_pending = pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending(
-                                       pipe_ctx->plane_res.hubp);
-
-       plane_state->status.is_flip_pending = plane_state->status.is_flip_pending || flip_pending;
-
-       if (!flip_pending)
-               plane_state->status.current_address = plane_state->status.requested_address;
-
-       if (plane_state->status.current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
-                       tg->funcs->is_stereo_left_eye) {
-               plane_state->status.is_right_eye =
-                               !tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
-       }
-
-       if (dc->hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied) {
-               struct dce_hwseq *hwseq = dc->hwseq;
-               struct timing_generator *tg = dc->res_pool->timing_generators[0];
-               unsigned int cur_frame = tg->funcs->get_frame_count(tg);
-
-               if (cur_frame != hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied_on_frame) {
-                       struct hubbub *hubbub = dc->res_pool->hubbub;
-
-                       hubbub->funcs->allow_self_refresh_control(hubbub, !dc->debug.disable_stutter);
-                       hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied = false;
-               }
-       }
-}
-
-void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
-{
-       struct hubbub *hubbub = hws->ctx->dc->res_pool->hubbub;
-
-       /* In DCN, this programming sequence is owned by the hubbub */
-       hubbub->funcs->update_dchub(hubbub, dh_data);
-}
-
-static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *test_pipe, *split_pipe;
-       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
-       struct rect r1 = scl_data->recout, r2, r2_half;
-       int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
-       int cur_layer = pipe_ctx->plane_state->layer_index;
-
-       /**
-        * Disable the cursor if there's another pipe above this with a
-        * plane that contains this pipe's viewport to prevent double cursor
-        * and incorrect scaling artifacts.
-        */
-       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
-            test_pipe = test_pipe->top_pipe) {
-               // Skip invisible layer and pipe-split plane on same layer
-               if (!test_pipe->plane_state ||
-                   !test_pipe->plane_state->visible ||
-                   test_pipe->plane_state->layer_index == cur_layer)
-                       continue;
-
-               r2 = test_pipe->plane_res.scl_data.recout;
-               r2_r = r2.x + r2.width;
-               r2_b = r2.y + r2.height;
-               split_pipe = test_pipe;
-
-               /**
-                * There is another half plane on same layer because of
-                * pipe-split, merge together per same height.
-                */
-               for (split_pipe = pipe_ctx->top_pipe; split_pipe;
-                    split_pipe = split_pipe->top_pipe)
-                       if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
-                               r2_half = split_pipe->plane_res.scl_data.recout;
-                               r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
-                               r2.width = r2.width + r2_half.width;
-                               r2_r = r2.x + r2.width;
-                               break;
-                       }
-
-               if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
-                       return true;
-       }
-
-       return false;
-}
-
-void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-       struct dc_cursor_mi_param param = {
-               .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
-               .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz,
-               .viewport = pipe_ctx->plane_res.scl_data.viewport,
-               .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
-               .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
-               .rotation = pipe_ctx->plane_state->rotation,
-               .mirror = pipe_ctx->plane_state->horizontal_mirror
-       };
-       bool pipe_split_on = false;
-       bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
-               (pipe_ctx->prev_odm_pipe != NULL);
-
-       int x_plane = pipe_ctx->plane_state->dst_rect.x;
-       int y_plane = pipe_ctx->plane_state->dst_rect.y;
-       int x_pos = pos_cpy.x;
-       int y_pos = pos_cpy.y;
-
-       if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) {
-               if ((pipe_ctx->plane_state->src_rect.width != pipe_ctx->plane_res.scl_data.viewport.width) ||
-                       (pipe_ctx->plane_state->src_rect.height != pipe_ctx->plane_res.scl_data.viewport.height)) {
-                       pipe_split_on = true;
-               }
-       }
-
-       /**
-        * DC cursor is stream space, HW cursor is plane space and drawn
-        * as part of the framebuffer.
-        *
-        * Cursor position can't be negative, but hotspot can be used to
-        * shift cursor out of the plane bounds. Hotspot must be smaller
-        * than the cursor size.
-        */
-
-       /**
-        * Translate cursor from stream space to plane space.
-        *
-        * If the cursor is scaled then we need to scale the position
-        * to be in the approximately correct place. We can't do anything
-        * about the actual size being incorrect, that's a limitation of
-        * the hardware.
-        */
-       if (param.rotation == ROTATION_ANGLE_90 || param.rotation == ROTATION_ANGLE_270) {
-               x_pos = (x_pos - x_plane) * pipe_ctx->plane_state->src_rect.height /
-                               pipe_ctx->plane_state->dst_rect.width;
-               y_pos = (y_pos - y_plane) * pipe_ctx->plane_state->src_rect.width /
-                               pipe_ctx->plane_state->dst_rect.height;
-       } else {
-               x_pos = (x_pos - x_plane) * pipe_ctx->plane_state->src_rect.width /
-                               pipe_ctx->plane_state->dst_rect.width;
-               y_pos = (y_pos - y_plane) * pipe_ctx->plane_state->src_rect.height /
-                               pipe_ctx->plane_state->dst_rect.height;
-       }
-
-       /**
-        * If the cursor's source viewport is clipped then we need to
-        * translate the cursor to appear in the correct position on
-        * the screen.
-        *
-        * This translation isn't affected by scaling so it needs to be
-        * done *after* we adjust the position for the scale factor.
-        *
-        * This is only done by opt-in for now since there are still
-        * some usecases like tiled display that might enable the
-        * cursor on both streams while expecting dc to clip it.
-        */
-       if (pos_cpy.translate_by_source) {
-               x_pos += pipe_ctx->plane_state->src_rect.x;
-               y_pos += pipe_ctx->plane_state->src_rect.y;
-       }
-
-       /**
-        * If the position is negative then we need to add to the hotspot
-        * to shift the cursor outside the plane.
-        */
-
-       if (x_pos < 0) {
-               pos_cpy.x_hotspot -= x_pos;
-               x_pos = 0;
-       }
-
-       if (y_pos < 0) {
-               pos_cpy.y_hotspot -= y_pos;
-               y_pos = 0;
-       }
-
-       pos_cpy.x = (uint32_t)x_pos;
-       pos_cpy.y = (uint32_t)y_pos;
-
-       if (pipe_ctx->plane_state->address.type
-                       == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
-               pos_cpy.enable = false;
-
-       if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
-               pos_cpy.enable = false;
-
-
-       if (param.rotation == ROTATION_ANGLE_0) {
-               int viewport_width =
-                       pipe_ctx->plane_res.scl_data.viewport.width;
-               int viewport_x =
-                       pipe_ctx->plane_res.scl_data.viewport.x;
-
-               if (param.mirror) {
-                       if (pipe_split_on || odm_combine_on) {
-                               if (pos_cpy.x >= viewport_width + viewport_x) {
-                                       pos_cpy.x = 2 * viewport_width
-                                                       - pos_cpy.x + 2 * viewport_x;
-                               } else {
-                                       uint32_t temp_x = pos_cpy.x;
-
-                                       pos_cpy.x = 2 * viewport_x - pos_cpy.x;
-                                       if (temp_x >= viewport_x +
-                                               (int)hubp->curs_attr.width || pos_cpy.x
-                                               <= (int)hubp->curs_attr.width +
-                                               pipe_ctx->plane_state->src_rect.x) {
-                                               pos_cpy.x = temp_x + viewport_width;
-                                       }
-                               }
-                       } else {
-                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
-                       }
-               }
-       }
-       // Swap axis and mirror horizontally
-       else if (param.rotation == ROTATION_ANGLE_90) {
-               uint32_t temp_x = pos_cpy.x;
-
-               pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
-                               (pos_cpy.y - pipe_ctx->plane_res.scl_data.viewport.x) + pipe_ctx->plane_res.scl_data.viewport.x;
-               pos_cpy.y = temp_x;
-       }
-       // Swap axis and mirror vertically
-       else if (param.rotation == ROTATION_ANGLE_270) {
-               uint32_t temp_y = pos_cpy.y;
-               int viewport_height =
-                       pipe_ctx->plane_res.scl_data.viewport.height;
-               int viewport_y =
-                       pipe_ctx->plane_res.scl_data.viewport.y;
-
-               /**
-                * Display groups that are 1xnY, have pos_cpy.x > 2 * viewport.height
-                * For pipe split cases:
-                * - apply offset of viewport.y to normalize pos_cpy.x
-                * - calculate the pos_cpy.y as before
-                * - shift pos_cpy.y back by same offset to get final value
-                * - since we iterate through both pipes, use the lower
-                *   viewport.y for offset
-                * For non pipe split cases, use the same calculation for
-                *  pos_cpy.y as the 180 degree rotation case below,
-                *  but use pos_cpy.x as our input because we are rotating
-                *  270 degrees
-                */
-               if (pipe_split_on || odm_combine_on) {
-                       int pos_cpy_x_offset;
-                       int other_pipe_viewport_y;
-
-                       if (pipe_split_on) {
-                               if (pipe_ctx->bottom_pipe) {
-                                       other_pipe_viewport_y =
-                                               pipe_ctx->bottom_pipe->plane_res.scl_data.viewport.y;
-                               } else {
-                                       other_pipe_viewport_y =
-                                               pipe_ctx->top_pipe->plane_res.scl_data.viewport.y;
-                               }
-                       } else {
-                               if (pipe_ctx->next_odm_pipe) {
-                                       other_pipe_viewport_y =
-                                               pipe_ctx->next_odm_pipe->plane_res.scl_data.viewport.y;
-                               } else {
-                                       other_pipe_viewport_y =
-                                               pipe_ctx->prev_odm_pipe->plane_res.scl_data.viewport.y;
-                               }
-                       }
-                       pos_cpy_x_offset = (viewport_y > other_pipe_viewport_y) ?
-                               other_pipe_viewport_y : viewport_y;
-                       pos_cpy.x -= pos_cpy_x_offset;
-                       if (pos_cpy.x > viewport_height) {
-                               pos_cpy.x = pos_cpy.x - viewport_height;
-                               pos_cpy.y = viewport_height - pos_cpy.x;
-                       } else {
-                               pos_cpy.y = 2 * viewport_height - pos_cpy.x;
-                       }
-                       pos_cpy.y += pos_cpy_x_offset;
-               } else {
-                       pos_cpy.y = (2 * viewport_y) + viewport_height - pos_cpy.x;
-               }
-               pos_cpy.x = temp_y;
-       }
-       // Mirror horizontally and vertically
-       else if (param.rotation == ROTATION_ANGLE_180) {
-               int viewport_width =
-                       pipe_ctx->plane_res.scl_data.viewport.width;
-               int viewport_x =
-                       pipe_ctx->plane_res.scl_data.viewport.x;
-
-               if (!param.mirror) {
-                       if (pipe_split_on || odm_combine_on) {
-                               if (pos_cpy.x >= viewport_width + viewport_x) {
-                                       pos_cpy.x = 2 * viewport_width
-                                                       - pos_cpy.x + 2 * viewport_x;
-                               } else {
-                                       uint32_t temp_x = pos_cpy.x;
-
-                                       pos_cpy.x = 2 * viewport_x - pos_cpy.x;
-                                       if (temp_x >= viewport_x +
-                                               (int)hubp->curs_attr.width || pos_cpy.x
-                                               <= (int)hubp->curs_attr.width +
-                                               pipe_ctx->plane_state->src_rect.x) {
-                                               pos_cpy.x = 2 * viewport_width - temp_x;
-                                       }
-                               }
-                       } else {
-                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
-                       }
-               }
-
-               /**
-                * Display groups that are 1xnY, have pos_cpy.y > viewport.height
-                * Calculation:
-                *   delta_from_bottom = viewport.y + viewport.height - pos_cpy.y
-                *   pos_cpy.y_new = viewport.y + delta_from_bottom
-                * Simplify it as:
-                *   pos_cpy.y = viewport.y * 2 + viewport.height - pos_cpy.y
-                */
-               pos_cpy.y = (2 * pipe_ctx->plane_res.scl_data.viewport.y) +
-                       pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
-       }
-
-       hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
-       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
-}
-
-void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
-
-       pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
-                       pipe_ctx->plane_res.hubp, attributes);
-       pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
-               pipe_ctx->plane_res.dpp, attributes);
-}
-
-void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
-{
-       uint32_t sdr_white_level = pipe_ctx->stream->cursor_attributes.sdr_white_level;
-       struct fixed31_32 multiplier;
-       struct dpp_cursor_attributes opt_attr = { 0 };
-       uint32_t hw_scale = 0x3c00; // 1.0 default multiplier
-       struct custom_float_format fmt;
-
-       if (!pipe_ctx->plane_res.dpp->funcs->set_optional_cursor_attributes)
-               return;
-
-       fmt.exponenta_bits = 5;
-       fmt.mantissa_bits = 10;
-       fmt.sign = true;
-
-       if (sdr_white_level > 80) {
-               multiplier = dc_fixpt_from_fraction(sdr_white_level, 80);
-               convert_to_custom_float_format(multiplier, &fmt, &hw_scale);
-       }
-
-       opt_attr.scale = hw_scale;
-       opt_attr.bias = 0;
-
-       pipe_ctx->plane_res.dpp->funcs->set_optional_cursor_attributes(
-                       pipe_ctx->plane_res.dpp, &opt_attr);
-}
-
-/*
- * apply_front_porch_workaround  TODO FPGA still need?
- *
- * This is a workaround for a bug that has existed since R5xx and has not been
- * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
- */
-static void apply_front_porch_workaround(
-       struct dc_crtc_timing *timing)
-{
-       if (timing->flags.INTERLACE == 1) {
-               if (timing->v_front_porch < 2)
-                       timing->v_front_porch = 2;
-       } else {
-               if (timing->v_front_porch < 1)
-                       timing->v_front_porch = 1;
-       }
-}
-
-int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx)
-{
-       const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
-       struct dc_crtc_timing patched_crtc_timing;
-       int vesa_sync_start;
-       int asic_blank_end;
-       int interlace_factor;
-
-       patched_crtc_timing = *dc_crtc_timing;
-       apply_front_porch_workaround(&patched_crtc_timing);
-
-       interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1;
-
-       vesa_sync_start = patched_crtc_timing.v_addressable +
-                       patched_crtc_timing.v_border_bottom +
-                       patched_crtc_timing.v_front_porch;
-
-       asic_blank_end = (patched_crtc_timing.v_total -
-                       vesa_sync_start -
-                       patched_crtc_timing.v_border_top)
-                       * interlace_factor;
-
-       return asic_blank_end -
-                       pipe_ctx->pipe_dlg_param.vstartup_start + 1;
-}
-
-void dcn10_calc_vupdate_position(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               uint32_t *start_line,
-               uint32_t *end_line)
-{
-       const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
-       int vupdate_pos = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
-
-       if (vupdate_pos >= 0)
-               *start_line = vupdate_pos - ((vupdate_pos / timing->v_total) * timing->v_total);
-       else
-               *start_line = vupdate_pos + ((-vupdate_pos / timing->v_total) + 1) * timing->v_total - 1;
-       *end_line = (*start_line + 2) % timing->v_total;
-}
-
-static void dcn10_cal_vline_position(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               uint32_t *start_line,
-               uint32_t *end_line)
-{
-       const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
-       int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
-
-       if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
-               if (vline_pos > 0)
-                       vline_pos--;
-               else if (vline_pos < 0)
-                       vline_pos++;
-
-               vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
-               if (vline_pos >= 0)
-                       *start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total);
-               else
-                       *start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1;
-               *end_line = (*start_line + 2) % timing->v_total;
-       } else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) {
-               // vsync is line 0 so start_line is just the requested line offset
-               *start_line = vline_pos;
-               *end_line = (*start_line + 2) % timing->v_total;
-       } else
-               ASSERT(0);
-}
-
-void dcn10_setup_periodic_interrupt(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx)
-{
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       uint32_t start_line = 0;
-       uint32_t end_line = 0;
-
-       dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line);
-
-       tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
-}
-
-void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       int start_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
-
-       if (start_line < 0) {
-               ASSERT(0);
-               start_line = 0;
-       }
-
-       if (tg->funcs->setup_vertical_interrupt2)
-               tg->funcs->setup_vertical_interrupt2(tg, start_line);
-}
-
-void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings)
-{
-       struct encoder_unblank_param params = {0};
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dce_hwseq *hws = link->dc->hwseq;
-
-       /* only 3 items below are used by unblank */
-       params.timing = pipe_ctx->stream->timing;
-
-       params.link_settings.link_rate = link_settings->link_rate;
-
-       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               if (params.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-                       params.timing.pix_clk_100hz /= 2;
-               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
-       }
-
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-               hws->funcs.edp_backlight_control(link, true);
-       }
-}
-
-void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
-                               const uint8_t *custom_sdp_message,
-                               unsigned int sdp_message_size)
-{
-       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               pipe_ctx->stream_res.stream_enc->funcs->send_immediate_sdp_message(
-                               pipe_ctx->stream_res.stream_enc,
-                               custom_sdp_message,
-                               sdp_message_size);
-       }
-}
-enum dc_status dcn10_set_clock(struct dc *dc,
-                       enum dc_clock_type clock_type,
-                       uint32_t clk_khz,
-                       uint32_t stepping)
-{
-       struct dc_state *context = dc->current_state;
-       struct dc_clock_config clock_cfg = {0};
-       struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk;
-
-       if (!dc->clk_mgr || !dc->clk_mgr->funcs->get_clock)
-               return DC_FAIL_UNSUPPORTED_1;
-
-       dc->clk_mgr->funcs->get_clock(dc->clk_mgr,
-               context, clock_type, &clock_cfg);
-
-       if (clk_khz > clock_cfg.max_clock_khz)
-               return DC_FAIL_CLK_EXCEED_MAX;
-
-       if (clk_khz < clock_cfg.min_clock_khz)
-               return DC_FAIL_CLK_BELOW_MIN;
-
-       if (clk_khz < clock_cfg.bw_requirequired_clock_khz)
-               return DC_FAIL_CLK_BELOW_CFG_REQUIRED;
-
-       /*update internal request clock for update clock use*/
-       if (clock_type == DC_CLOCK_TYPE_DISPCLK)
-               current_clocks->dispclk_khz = clk_khz;
-       else if (clock_type == DC_CLOCK_TYPE_DPPCLK)
-               current_clocks->dppclk_khz = clk_khz;
-       else
-               return DC_ERROR_UNEXPECTED;
-
-       if (dc->clk_mgr->funcs->update_clocks)
-                               dc->clk_mgr->funcs->update_clocks(dc->clk_mgr,
-                               context, true);
-       return DC_OK;
-
-}
-
-void dcn10_get_clock(struct dc *dc,
-                       enum dc_clock_type clock_type,
-                       struct dc_clock_config *clock_cfg)
-{
-       struct dc_state *context = dc->current_state;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
-                               dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg);
-
-}
-
-void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits)
-{
-       struct resource_pool *pool = dc->res_pool;
-       int i;
-
-       for (i = 0; i < pool->pipe_count; i++) {
-               struct hubp *hubp = pool->hubps[i];
-               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
-
-               hubp->funcs->hubp_read_state(hubp);
-
-               if (!s->blank_en)
-                       dcc_en_bits[i] = s->dcc_en ? 1 : 0;
-       }
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
deleted file mode 100644 (file)
index ef6d56d..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-* Copyright 2016-2020 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_HWSS_DCN10_H__
-#define __DC_HWSS_DCN10_H__
-
-#include "core_types.h"
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dcn10_hw_sequencer_construct(struct dc *dc);
-
-int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx);
-void dcn10_calc_vupdate_position(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               uint32_t *start_line,
-               uint32_t *end_line);
-void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
-enum dc_status dcn10_enable_stream_timing(
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context,
-               struct dc *dc);
-void dcn10_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn10_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn10_pipe_control_lock(
-       struct dc *dc,
-       struct pipe_ctx *pipe,
-       bool lock);
-void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
-void dcn10_blank_pixel_data(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool blank);
-void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings);
-void dcn10_program_output_csc(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum dc_color_space colorspace,
-               uint16_t *matrix,
-               int opp_id);
-bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream);
-bool dcn10_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_state *plane_state);
-void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn10_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn10_lock_all_pipes(
-               struct dc *dc,
-               struct dc_state *context,
-               bool lock);
-void dcn10_post_unlock_program_front_end(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn10_hubp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int hubp_inst,
-               bool power_on);
-void dcn10_dpp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dpp_inst,
-               bool power_on);
-void dcn10_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable);
-void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn10_disable_vga(
-       struct dce_hwseq *hws);
-void dcn10_program_pipe(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context);
-void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx);
-void dcn10_init_hw(struct dc *dc);
-void dcn10_init_pipes(struct dc *dc, struct dc_state *context);
-void dcn10_power_down_on_boot(struct dc *dc);
-enum dc_status dce110_apply_ctx_to_hw(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data);
-void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx);
-void dce110_power_down(struct dc *dc);
-void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context);
-void dcn10_enable_timing_synchronization(
-               struct dc *dc,
-               int group_index,
-               int group_size,
-               struct pipe_ctx *grouped_pipes[]);
-void dcn10_enable_vblanks_synchronization(
-               struct dc *dc,
-               int group_index,
-               int group_size,
-               struct pipe_ctx *grouped_pipes[]);
-void dcn10_enable_per_frame_crtc_position_reset(
-               struct dc *dc,
-               int group_size,
-               struct pipe_ctx *grouped_pipes[]);
-void dce110_update_info_frame(struct pipe_ctx *pipe_ctx);
-void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
-               const uint8_t *custom_sdp_message,
-               unsigned int sdp_message_size);
-void dce110_blank_stream(struct pipe_ctx *pipe_ctx);
-void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx);
-void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx);
-bool dcn10_dummy_display_power_gating(
-               struct dc *dc,
-               uint8_t controller_id,
-               struct dc_bios *dcb,
-               enum pipe_gating_control power_gating);
-void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
-               int num_pipes, struct dc_crtc_timing_adjust adjust);
-void dcn10_get_position(struct pipe_ctx **pipe_ctx,
-               int num_pipes,
-               struct crtc_position *position);
-void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
-               int num_pipes, const struct dc_static_screen_params *params);
-void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc);
-void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
-void dcn10_log_hw_state(struct dc *dc,
-               struct dc_log_buffer_ctx *log_ctx);
-void dcn10_get_hw_state(struct dc *dc,
-               char *pBuf,
-               unsigned int bufSize,
-               unsigned int mask);
-void dcn10_clear_status_bits(struct dc *dc, unsigned int mask);
-void dcn10_wait_for_mpcc_disconnect(
-               struct dc *dc,
-               struct resource_pool *res_pool,
-               struct pipe_ctx *pipe_ctx);
-void dce110_edp_backlight_control(
-               struct dc_link *link,
-               bool enable);
-void dce110_edp_wait_for_T12(
-               struct dc_link *link);
-void dce110_edp_power_control(
-               struct dc_link *link,
-               bool power_up);
-void dce110_edp_wait_for_hpd_ready(
-               struct dc_link *link,
-               bool power_up);
-void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx);
-void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
-void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx);
-void dcn10_setup_periodic_interrupt(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx);
-enum dc_status dcn10_set_clock(struct dc *dc,
-               enum dc_clock_type clock_type,
-               uint32_t clk_khz,
-               uint32_t stepping);
-void dcn10_get_clock(struct dc *dc,
-               enum dc_clock_type clock_type,
-               struct dc_clock_config *clock_cfg);
-bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn10_bios_golden_init(struct dc *dc);
-void dcn10_plane_atomic_power_down(struct dc *dc,
-               struct dpp *dpp,
-               struct hubp *hubp);
-bool dcn10_disconnect_pipes(
-               struct dc *dc,
-               struct dc_state *context);
-
-void dcn10_wait_for_pending_cleared(struct dc *dc,
-               struct dc_state *context);
-void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx);
-void dcn10_verify_allow_pstate_change_high(struct dc *dc);
-
-void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits);
-
-void dcn10_update_visual_confirm_color(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               int mpcc_id);
-
-#endif /* __DC_HWSS_DCN10_H__ */
index 46a2ebc..92fdab7 100644 (file)
@@ -27,8 +27,8 @@
 #include "core_types.h"
 #include "resource.h"
 #include "custom_float.h"
-#include "dcn10_hw_sequencer.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dcn10/dcn10_hwseq.h"
+#include "dce110/dce110_hwseq.h"
 #include "dce/dce_hwseq.h"
 #include "abm.h"
 #include "dmcu.h"
index f2371c9..a5bdac7 100644 (file)
@@ -24,8 +24,8 @@
  */
 
 #include "hw_sequencer_private.h"
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 
 static const struct hw_sequencer_funcs dcn10_funcs = {
index 9f91457..d1d8e90 100644 (file)
@@ -36,8 +36,8 @@
 #include "irq/dcn10/irq_service_dcn10.h"
 #include "dcn10_dpp.h"
 #include "dcn10_optc.h"
-#include "dcn10_hw_sequencer.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dcn10/dcn10_hwseq.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn10_opp.h"
 #include "dcn10_link_encoder.h"
 #include "dcn10_stream_encoder.h"
index abaed21..d7dc969 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Makefile for DCN.
 
-DCN20 = dcn20_resource.o dcn20_init.o dcn20_hwseq.o dcn20_dpp.o dcn20_dpp_cm.o dcn20_hubp.o \
+DCN20 = dcn20_resource.o dcn20_init.o dcn20_dpp.o dcn20_dpp_cm.o dcn20_hubp.o \
                dcn20_mpc.o dcn20_opp.o dcn20_hubbub.o dcn20_optc.o dcn20_mmhubbub.o \
                dcn20_stream_encoder.o dcn20_link_encoder.o dcn20_dccg.o \
                dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
deleted file mode 100644 (file)
index f5a7002..0000000
+++ /dev/null
@@ -1,2941 +0,0 @@
-/*
- * 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 <linux/delay.h>
-
-#include "dm_services.h"
-#include "basics/dc_common.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dcn20_resource.h"
-#include "dcn20_hwseq.h"
-#include "dce/dce_hwseq.h"
-#include "dcn20_dsc.h"
-#include "dcn20_optc.h"
-#include "abm.h"
-#include "clk_mgr.h"
-#include "dmcu.h"
-#include "hubp.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "mcif_wb.h"
-#include "dchubbub.h"
-#include "reg_helper.h"
-#include "dcn10/dcn10_cm_common.h"
-#include "vm_helper.h"
-#include "dccg.h"
-#include "dc_dmub_srv.h"
-#include "dce/dmub_hw_lock_mgr.h"
-#include "hw_sequencer.h"
-#include "dpcd_defs.h"
-#include "inc/link_enc_cfg.h"
-#include "link_hwss.h"
-#include "link.h"
-
-#define DC_LOGGER \
-       dc_logger
-#define DC_LOGGER_INIT(logger) \
-       struct dal_logger *dc_logger = logger
-
-#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
-
-static int find_free_gsl_group(const struct dc *dc)
-{
-       if (dc->res_pool->gsl_groups.gsl_0 == 0)
-               return 1;
-       if (dc->res_pool->gsl_groups.gsl_1 == 0)
-               return 2;
-       if (dc->res_pool->gsl_groups.gsl_2 == 0)
-               return 3;
-
-       return 0;
-}
-
-/* NOTE: This is not a generic setup_gsl function (hence the suffix as_lock)
- * This is only used to lock pipes in pipe splitting case with immediate flip
- * Ordinary MPC/OTG locks suppress VUPDATE which doesn't help with immediate,
- * so we get tearing with freesync since we cannot flip multiple pipes
- * atomically.
- * We use GSL for this:
- * - immediate flip: find first available GSL group if not already assigned
- *                   program gsl with that group, set current OTG as master
- *                   and always us 0x4 = AND of flip_ready from all pipes
- * - vsync flip: disable GSL if used
- *
- * Groups in stream_res are stored as +1 from HW registers, i.e.
- * gsl_0 <=> pipe_ctx->stream_res.gsl_group == 1
- * Using a magic value like -1 would require tracking all inits/resets
- */
- void dcn20_setup_gsl_group_as_lock(
-               const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool enable)
-{
-       struct gsl_params gsl;
-       int group_idx;
-
-       memset(&gsl, 0, sizeof(struct gsl_params));
-
-       if (enable) {
-               /* return if group already assigned since GSL was set up
-                * for vsync flip, we would unassign so it can't be "left over"
-                */
-               if (pipe_ctx->stream_res.gsl_group > 0)
-                       return;
-
-               group_idx = find_free_gsl_group(dc);
-               ASSERT(group_idx != 0);
-               pipe_ctx->stream_res.gsl_group = group_idx;
-
-               /* set gsl group reg field and mark resource used */
-               switch (group_idx) {
-               case 1:
-                       gsl.gsl0_en = 1;
-                       dc->res_pool->gsl_groups.gsl_0 = 1;
-                       break;
-               case 2:
-                       gsl.gsl1_en = 1;
-                       dc->res_pool->gsl_groups.gsl_1 = 1;
-                       break;
-               case 3:
-                       gsl.gsl2_en = 1;
-                       dc->res_pool->gsl_groups.gsl_2 = 1;
-                       break;
-               default:
-                       BREAK_TO_DEBUGGER();
-                       return; // invalid case
-               }
-               gsl.gsl_master_en = 1;
-       } else {
-               group_idx = pipe_ctx->stream_res.gsl_group;
-               if (group_idx == 0)
-                       return; // if not in use, just return
-
-               pipe_ctx->stream_res.gsl_group = 0;
-
-               /* unset gsl group reg field and mark resource free */
-               switch (group_idx) {
-               case 1:
-                       gsl.gsl0_en = 0;
-                       dc->res_pool->gsl_groups.gsl_0 = 0;
-                       break;
-               case 2:
-                       gsl.gsl1_en = 0;
-                       dc->res_pool->gsl_groups.gsl_1 = 0;
-                       break;
-               case 3:
-                       gsl.gsl2_en = 0;
-                       dc->res_pool->gsl_groups.gsl_2 = 0;
-                       break;
-               default:
-                       BREAK_TO_DEBUGGER();
-                       return;
-               }
-               gsl.gsl_master_en = 0;
-       }
-
-       /* at this point we want to program whether it's to enable or disable */
-       if (pipe_ctx->stream_res.tg->funcs->set_gsl != NULL &&
-               pipe_ctx->stream_res.tg->funcs->set_gsl_source_select != NULL) {
-               pipe_ctx->stream_res.tg->funcs->set_gsl(
-                       pipe_ctx->stream_res.tg,
-                       &gsl);
-
-               pipe_ctx->stream_res.tg->funcs->set_gsl_source_select(
-                       pipe_ctx->stream_res.tg, group_idx,     enable ? 4 : 0);
-       } else
-               BREAK_TO_DEBUGGER();
-}
-
-void dcn20_set_flip_control_gsl(
-               struct pipe_ctx *pipe_ctx,
-               bool flip_immediate)
-{
-       if (pipe_ctx && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_control_surface_gsl)
-               pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_control_surface_gsl(
-                               pipe_ctx->plane_res.hubp, flip_immediate);
-
-}
-
-void dcn20_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable)
-{
-       bool force_on = true; /* disable power gating */
-       uint32_t org_ip_request_cntl = 0;
-
-       if (enable)
-               force_on = false;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       /* DCHUBP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
-       if (REG(DOMAIN8_PG_CONFIG))
-               REG_UPDATE(DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
-       if (REG(DOMAIN10_PG_CONFIG))
-               REG_UPDATE(DOMAIN10_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
-
-       /* DPP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
-       if (REG(DOMAIN9_PG_CONFIG))
-               REG_UPDATE(DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
-       if (REG(DOMAIN11_PG_CONFIG))
-               REG_UPDATE(DOMAIN11_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
-
-       /* DCS0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, force_on);
-       if (REG(DOMAIN19_PG_CONFIG))
-               REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, force_on);
-       if (REG(DOMAIN20_PG_CONFIG))
-               REG_UPDATE(DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, force_on);
-       if (REG(DOMAIN21_PG_CONFIG))
-               REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on);
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-
-}
-
-void dcn20_dccg_init(struct dce_hwseq *hws)
-{
-       /*
-        * set MICROSECOND_TIME_BASE_DIV
-        * 100Mhz refclk -> 0x120264
-        * 27Mhz refclk -> 0x12021b
-        * 48Mhz refclk -> 0x120230
-        *
-        */
-       REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264);
-
-       /*
-        * set MILLISECOND_TIME_BASE_DIV
-        * 100Mhz refclk -> 0x1186a0
-        * 27Mhz refclk -> 0x106978
-        * 48Mhz refclk -> 0x10bb80
-        *
-        */
-       REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0);
-
-       /* This value is dependent on the hardware pipeline delay so set once per SOC */
-       REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c);
-}
-
-void dcn20_disable_vga(
-       struct dce_hwseq *hws)
-{
-       REG_WRITE(D1VGA_CONTROL, 0);
-       REG_WRITE(D2VGA_CONTROL, 0);
-       REG_WRITE(D3VGA_CONTROL, 0);
-       REG_WRITE(D4VGA_CONTROL, 0);
-       REG_WRITE(D5VGA_CONTROL, 0);
-       REG_WRITE(D6VGA_CONTROL, 0);
-}
-
-void dcn20_program_triple_buffer(
-       const struct dc *dc,
-       struct pipe_ctx *pipe_ctx,
-       bool enable_triple_buffer)
-{
-       if (pipe_ctx->plane_res.hubp && pipe_ctx->plane_res.hubp->funcs) {
-               pipe_ctx->plane_res.hubp->funcs->hubp_enable_tripleBuffer(
-                       pipe_ctx->plane_res.hubp,
-                       enable_triple_buffer);
-       }
-}
-
-/* Blank pixel data during initialization */
-void dcn20_init_blank(
-               struct dc *dc,
-               struct timing_generator *tg)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-       struct output_pixel_processor *opp = NULL;
-       struct output_pixel_processor *bottom_opp = NULL;
-       uint32_t num_opps, opp_id_src0, opp_id_src1;
-       uint32_t otg_active_width, otg_active_height;
-
-       /* program opp dpg blank color */
-       color_space = COLOR_SPACE_SRGB;
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       /* get the OTG active size */
-       tg->funcs->get_otg_active_size(tg,
-                       &otg_active_width,
-                       &otg_active_height);
-
-       /* get the OPTC source */
-       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-
-       if (opp_id_src0 >= dc->res_pool->res_cap->num_opp) {
-               ASSERT(false);
-               return;
-       }
-       opp = dc->res_pool->opps[opp_id_src0];
-
-       /* don't override the blank pattern if already enabled with the correct one. */
-       if (opp->funcs->dpg_is_blanked && opp->funcs->dpg_is_blanked(opp))
-               return;
-
-       if (num_opps == 2) {
-               otg_active_width = otg_active_width / 2;
-
-               if (opp_id_src1 >= dc->res_pool->res_cap->num_opp) {
-                       ASSERT(false);
-                       return;
-               }
-               bottom_opp = dc->res_pool->opps[opp_id_src1];
-       }
-
-       opp->funcs->opp_set_disp_pattern_generator(
-                       opp,
-                       CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-                       CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-                       COLOR_DEPTH_UNDEFINED,
-                       &black_color,
-                       otg_active_width,
-                       otg_active_height,
-                       0);
-
-       if (num_opps == 2) {
-               bottom_opp->funcs->opp_set_disp_pattern_generator(
-                               bottom_opp,
-                               CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-                               CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-                               COLOR_DEPTH_UNDEFINED,
-                               &black_color,
-                               otg_active_width,
-                               otg_active_height,
-                               0);
-       }
-
-       hws->funcs.wait_for_blank_complete(opp);
-}
-
-void dcn20_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_dsc_power_gate)
-               return;
-
-       if (REG(DOMAIN16_PG_CONFIG) == 0)
-               return;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_UPDATE(DOMAIN16_PG_CONFIG,
-                               DOMAIN16_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN16_PG_STATUS,
-                               DOMAIN16_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DSC1 */
-               REG_UPDATE(DOMAIN17_PG_CONFIG,
-                               DOMAIN17_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN17_PG_STATUS,
-                               DOMAIN17_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DSC2 */
-               REG_UPDATE(DOMAIN18_PG_CONFIG,
-                               DOMAIN18_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN18_PG_STATUS,
-                               DOMAIN18_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DSC3 */
-               REG_UPDATE(DOMAIN19_PG_CONFIG,
-                               DOMAIN19_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN19_PG_STATUS,
-                               DOMAIN19_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 4: /* DSC4 */
-               REG_UPDATE(DOMAIN20_PG_CONFIG,
-                               DOMAIN20_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN20_PG_STATUS,
-                               DOMAIN20_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 5: /* DSC5 */
-               REG_UPDATE(DOMAIN21_PG_CONFIG,
-                               DOMAIN21_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN21_PG_STATUS,
-                               DOMAIN21_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-void dcn20_dpp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dpp_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-
-       if (hws->ctx->dc->debug.disable_dpp_power_gate)
-               return;
-       if (REG(DOMAIN1_PG_CONFIG) == 0)
-               return;
-
-       switch (dpp_inst) {
-       case 0: /* DPP0 */
-               REG_UPDATE(DOMAIN1_PG_CONFIG,
-                               DOMAIN1_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN1_PG_STATUS,
-                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DPP1 */
-               REG_UPDATE(DOMAIN3_PG_CONFIG,
-                               DOMAIN3_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN3_PG_STATUS,
-                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DPP2 */
-               REG_UPDATE(DOMAIN5_PG_CONFIG,
-                               DOMAIN5_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN5_PG_STATUS,
-                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DPP3 */
-               REG_UPDATE(DOMAIN7_PG_CONFIG,
-                               DOMAIN7_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN7_PG_STATUS,
-                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 4: /* DPP4 */
-               REG_UPDATE(DOMAIN9_PG_CONFIG,
-                               DOMAIN9_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN9_PG_STATUS,
-                               DOMAIN9_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 5: /* DPP5 */
-               /*
-                * Do not power gate DPP5, should be left at HW default, power on permanently.
-                * PG on Pipe5 is De-featured, attempting to put it to PG state may result in hard
-                * reset.
-                * REG_UPDATE(DOMAIN11_PG_CONFIG,
-                *              DOMAIN11_POWER_GATE, power_gate);
-                *
-                * REG_WAIT(DOMAIN11_PG_STATUS,
-                *              DOMAIN11_PGFSM_PWR_STATUS, pwr_status,
-                *              1, 1000);
-                */
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-
-void dcn20_hubp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int hubp_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-
-       if (hws->ctx->dc->debug.disable_hubp_power_gate)
-               return;
-       if (REG(DOMAIN0_PG_CONFIG) == 0)
-               return;
-
-       switch (hubp_inst) {
-       case 0: /* DCHUBP0 */
-               REG_UPDATE(DOMAIN0_PG_CONFIG,
-                               DOMAIN0_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN0_PG_STATUS,
-                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DCHUBP1 */
-               REG_UPDATE(DOMAIN2_PG_CONFIG,
-                               DOMAIN2_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN2_PG_STATUS,
-                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DCHUBP2 */
-               REG_UPDATE(DOMAIN4_PG_CONFIG,
-                               DOMAIN4_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN4_PG_STATUS,
-                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DCHUBP3 */
-               REG_UPDATE(DOMAIN6_PG_CONFIG,
-                               DOMAIN6_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN6_PG_STATUS,
-                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 4: /* DCHUBP4 */
-               REG_UPDATE(DOMAIN8_PG_CONFIG,
-                               DOMAIN8_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN8_PG_STATUS,
-                               DOMAIN8_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 5: /* DCHUBP5 */
-               /*
-                * Do not power gate DCHUB5, should be left at HW default, power on permanently.
-                * PG on Pipe5 is De-featured, attempting to put it to PG state may result in hard
-                * reset.
-                * REG_UPDATE(DOMAIN10_PG_CONFIG,
-                *              DOMAIN10_POWER_GATE, power_gate);
-                *
-                * REG_WAIT(DOMAIN10_PG_STATUS,
-                *              DOMAIN10_PGFSM_PWR_STATUS, pwr_status,
-                *              1, 1000);
-                */
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-
-/* disable HW used by plane.
- * note:  cannot disable until disconnect is complete
- */
-void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-
-       dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
-
-       /* In flip immediate with pipe splitting case GSL is used for
-        * synchronization so we must disable it when the plane is disabled.
-        */
-       if (pipe_ctx->stream_res.gsl_group != 0)
-               dcn20_setup_gsl_group_as_lock(dc, pipe_ctx, false);
-
-       if (hubp->funcs->hubp_update_mall_sel)
-               hubp->funcs->hubp_update_mall_sel(hubp, 0, false);
-
-       dc->hwss.set_flip_control_gsl(pipe_ctx, false);
-
-       hubp->funcs->hubp_clk_cntl(hubp, false);
-
-       dpp->funcs->dpp_dppclk_control(dpp, false, false);
-
-       hubp->power_gated = true;
-
-       hws->funcs.plane_atomic_power_down(dc,
-                       pipe_ctx->plane_res.dpp,
-                       pipe_ctx->plane_res.hubp);
-
-       pipe_ctx->stream = NULL;
-       memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
-       memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
-       pipe_ctx->top_pipe = NULL;
-       pipe_ctx->bottom_pipe = NULL;
-       pipe_ctx->prev_odm_pipe = NULL;
-       pipe_ctx->next_odm_pipe = NULL;
-       pipe_ctx->plane_state = NULL;
-}
-
-
-void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       bool is_phantom = pipe_ctx->plane_state && pipe_ctx->plane_state->is_phantom;
-       struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL;
-
-       DC_LOGGER_INIT(dc->ctx->logger);
-
-       if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
-               return;
-
-       dcn20_plane_atomic_disable(dc, pipe_ctx);
-
-       /* Turn back off the phantom OTG after the phantom plane is fully disabled
-        */
-       if (is_phantom)
-               if (tg && tg->funcs->disable_phantom_crtc)
-                       tg->funcs->disable_phantom_crtc(tg);
-
-       DC_LOG_DC("Power down front end %d\n",
-                                       pipe_ctx->pipe_idx);
-}
-
-void dcn20_disable_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank)
-{
-       dcn20_blank_pixel_data(dc, pipe_ctx, blank);
-}
-
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-               int opp_cnt)
-{
-       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-       int flow_ctrl_cnt;
-
-       if (opp_cnt >= 2)
-               hblank_halved = true;
-
-       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-                       stream->timing.h_border_left -
-                       stream->timing.h_border_right;
-
-       if (hblank_halved)
-               flow_ctrl_cnt /= 2;
-
-       /* ODM combine 4:1 case */
-       if (opp_cnt == 4)
-               flow_ctrl_cnt /= 2;
-
-       return flow_ctrl_cnt;
-}
-
-static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
-{
-       switch (link->link_enc->transmitter) {
-       case TRANSMITTER_UNIPHY_A:
-               return PHYD32CLKA;
-       case TRANSMITTER_UNIPHY_B:
-               return PHYD32CLKB;
-       case TRANSMITTER_UNIPHY_C:
-               return PHYD32CLKC;
-       case TRANSMITTER_UNIPHY_D:
-               return PHYD32CLKD;
-       case TRANSMITTER_UNIPHY_E:
-               return PHYD32CLKE;
-       default:
-               return PHYD32CLKA;
-       }
-}
-
-static int get_odm_segment_count(struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
-       int count = 1;
-
-       while (odm_pipe != NULL) {
-               count++;
-               odm_pipe = odm_pipe->next_odm_pipe;
-       }
-
-       return count;
-}
-
-enum dc_status dcn20_enable_stream_timing(
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context,
-               struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct drr_params params = {0};
-       unsigned int event_triggers = 0;
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 1;
-       int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst };
-       bool interlace = stream->timing.flags.INTERLACE;
-       int i;
-       struct mpc_dwb_flow_control flow_control;
-       struct mpc *mpc = dc->res_pool->mpc;
-       bool rate_control_2x_pclk = (interlace || optc2_is_two_pixels_per_containter(&stream->timing));
-       unsigned int k1_div = PIXEL_RATE_DIV_NA;
-       unsigned int k2_div = PIXEL_RATE_DIV_NA;
-
-       if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
-               hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
-
-               dc->res_pool->dccg->funcs->set_pixel_rate_div(
-                       dc->res_pool->dccg,
-                       pipe_ctx->stream_res.tg->inst,
-                       k1_div, k2_div);
-       }
-       /* by upper caller loop, pipe0 is parent pipe and be called first.
-        * back end is set up by for pipe0. Other children pipe share back end
-        * with pipe 0. No program is needed.
-        */
-       if (pipe_ctx->top_pipe != NULL)
-               return DC_OK;
-
-       /* TODO check if timing_changed, disable stream if timing changed */
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               opp_inst[opp_cnt] = odm_pipe->stream_res.opp->inst;
-               opp_cnt++;
-       }
-
-       if (opp_cnt > 1)
-               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
-                               pipe_ctx->stream_res.tg,
-                               opp_inst, opp_cnt,
-                               &pipe_ctx->stream->timing);
-
-       /* HW program guide assume display already disable
-        * by unplug sequence. OTG assume stop.
-        */
-       pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, true);
-
-       if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
-                       pipe_ctx->clock_source,
-                       &pipe_ctx->stream_res.pix_clk_params,
-                       dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
-                       &pipe_ctx->pll_settings)) {
-               BREAK_TO_DEBUGGER();
-               return DC_ERROR_UNEXPECTED;
-       }
-
-       if (dc_is_hdmi_tmds_signal(stream->signal)) {
-               stream->link->phy_state.symclk_ref_cnts.otg = 1;
-               if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
-                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
-               else
-                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-       }
-
-       if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal)))
-               dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx);
-
-       pipe_ctx->stream_res.tg->funcs->program_timing(
-                       pipe_ctx->stream_res.tg,
-                       &stream->timing,
-                       pipe_ctx->pipe_dlg_param.vready_offset,
-                       pipe_ctx->pipe_dlg_param.vstartup_start,
-                       pipe_ctx->pipe_dlg_param.vupdate_offset,
-                       pipe_ctx->pipe_dlg_param.vupdate_width,
-                       pipe_ctx->stream->signal,
-                       true);
-
-       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-       flow_control.flow_ctrl_mode = 0;
-       flow_control.flow_ctrl_cnt0 = 0x80;
-       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(stream, opp_cnt);
-       if (mpc->funcs->set_out_rate_control) {
-               for (i = 0; i < opp_cnt; ++i) {
-                       mpc->funcs->set_out_rate_control(
-                                       mpc, opp_inst[i],
-                                       true,
-                                       rate_control_2x_pclk,
-                                       &flow_control);
-               }
-       }
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
-                               odm_pipe->stream_res.opp,
-                               true);
-
-       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
-                       pipe_ctx->stream_res.opp,
-                       true);
-
-       hws->funcs.blank_pixel_data(dc, pipe_ctx, true);
-
-       /* VTG is  within DCHUB command block. DCFCLK is always on */
-       if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(pipe_ctx->stream_res.tg)) {
-               BREAK_TO_DEBUGGER();
-               return DC_ERROR_UNEXPECTED;
-       }
-
-       hws->funcs.wait_for_blank_complete(pipe_ctx->stream_res.opp);
-
-       params.vertical_total_min = stream->adjust.v_total_min;
-       params.vertical_total_max = stream->adjust.v_total_max;
-       params.vertical_total_mid = stream->adjust.v_total_mid;
-       params.vertical_total_mid_frame_num = stream->adjust.v_total_mid_frame_num;
-       if (pipe_ctx->stream_res.tg->funcs->set_drr)
-               pipe_ctx->stream_res.tg->funcs->set_drr(
-                       pipe_ctx->stream_res.tg, &params);
-
-       // DRR should set trigger event to monitor surface update event
-       if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
-               event_triggers = 0x80;
-       /* Event triggers and num frames initialized for DRR, but can be
-        * later updated for PSR use. Note DRR trigger events are generated
-        * regardless of whether num frames met.
-        */
-       if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
-               pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
-                               pipe_ctx->stream_res.tg, event_triggers, 2);
-
-       /* TODO program crtc source select for non-virtual signal*/
-       /* TODO program FMT */
-       /* TODO setup link_enc */
-       /* TODO set stream attributes */
-       /* TODO program audio */
-       /* TODO enable stream if timing changed */
-       /* TODO unblank stream if DP */
-
-       if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM) {
-               if (pipe_ctx->stream_res.tg && pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)
-                       pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg);
-       }
-
-       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               struct dccg *dccg = dc->res_pool->dccg;
-               struct timing_generator *tg = pipe_ctx->stream_res.tg;
-               struct dtbclk_dto_params dto_params = {0};
-
-               if (dccg->funcs->set_dtbclk_p_src)
-                       dccg->funcs->set_dtbclk_p_src(dccg, DTBCLK0, tg->inst);
-
-               dto_params.otg_inst = tg->inst;
-               dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
-               dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
-               dto_params.timing = &pipe_ctx->stream->timing;
-               dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
-               dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
-       }
-
-       return DC_OK;
-}
-
-void dcn20_program_output_csc(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum dc_color_space colorspace,
-               uint16_t *matrix,
-               int opp_id)
-{
-       struct mpc *mpc = dc->res_pool->mpc;
-       enum mpc_output_csc_mode ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
-       if (mpc->funcs->power_on_mpc_mem_pwr)
-               mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, true);
-
-       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
-               if (mpc->funcs->set_output_csc != NULL)
-                       mpc->funcs->set_output_csc(mpc,
-                                       opp_id,
-                                       matrix,
-                                       ocsc_mode);
-       } else {
-               if (mpc->funcs->set_ocsc_default != NULL)
-                       mpc->funcs->set_ocsc_default(mpc,
-                                       opp_id,
-                                       colorspace,
-                                       ocsc_mode);
-       }
-}
-
-bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream)
-{
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-       struct pwl_params *params = NULL;
-       /*
-        * program OGAM only for the top pipe
-        * if there is a pipe split then fix diagnostic is required:
-        * how to pass OGAM parameter for stream.
-        * if programming for all pipes is required then remove condition
-        * pipe_ctx->top_pipe == NULL ,but then fix the diagnostic.
-        */
-       if (mpc->funcs->power_on_mpc_mem_pwr)
-               mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, true);
-       if (pipe_ctx->top_pipe == NULL
-                       && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
-               if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
-                       params = &stream->out_transfer_func->pwl;
-               else if (pipe_ctx->stream->out_transfer_func->type ==
-                       TF_TYPE_DISTRIBUTED_POINTS &&
-                       cm_helper_translate_curve_to_hw_format(dc->ctx,
-                       stream->out_transfer_func,
-                       &mpc->blender_params, false))
-                       params = &mpc->blender_params;
-               /*
-                * there is no ROM
-                */
-               if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
-                       BREAK_TO_DEBUGGER();
-       }
-       /*
-        * if above if is not executed then 'params' equal to 0 and set in bypass
-        */
-       mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
-
-       return true;
-}
-
-bool dcn20_set_blend_lut(
-       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       bool result = true;
-       struct pwl_params *blend_lut = NULL;
-
-       if (plane_state->blend_tf) {
-               if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
-                       blend_lut = &plane_state->blend_tf->pwl;
-               else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                       plane_state->blend_tf,
-                                       &dpp_base->regamma_params, false);
-                       blend_lut = &dpp_base->regamma_params;
-               }
-       }
-       result = dpp_base->funcs->dpp_program_blnd_lut(dpp_base, blend_lut);
-
-       return result;
-}
-
-bool dcn20_set_shaper_3dlut(
-       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       bool result = true;
-       struct pwl_params *shaper_lut = NULL;
-
-       if (plane_state->in_shaper_func) {
-               if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL)
-                       shaper_lut = &plane_state->in_shaper_func->pwl;
-               else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                       plane_state->in_shaper_func,
-                                       &dpp_base->shaper_params, true);
-                       shaper_lut = &dpp_base->shaper_params;
-               }
-       }
-
-       result = dpp_base->funcs->dpp_program_shaper_lut(dpp_base, shaper_lut);
-       if (plane_state->lut3d_func &&
-               plane_state->lut3d_func->state.bits.initialized == 1)
-               result = dpp_base->funcs->dpp_program_3dlut(dpp_base,
-                                                               &plane_state->lut3d_func->lut_3d);
-       else
-               result = dpp_base->funcs->dpp_program_3dlut(dpp_base, NULL);
-
-       return result;
-}
-
-bool dcn20_set_input_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       const struct dc_transfer_func *tf = NULL;
-       bool result = true;
-       bool use_degamma_ram = false;
-
-       if (dpp_base == NULL || plane_state == NULL)
-               return false;
-
-       hws->funcs.set_shaper_3dlut(pipe_ctx, plane_state);
-       hws->funcs.set_blend_lut(pipe_ctx, plane_state);
-
-       if (plane_state->in_transfer_func)
-               tf = plane_state->in_transfer_func;
-
-
-       if (tf == NULL) {
-               dpp_base->funcs->dpp_set_degamma(dpp_base,
-                               IPP_DEGAMMA_MODE_BYPASS);
-               return true;
-       }
-
-       if (tf->type == TF_TYPE_HWPWL || tf->type == TF_TYPE_DISTRIBUTED_POINTS)
-               use_degamma_ram = true;
-
-       if (use_degamma_ram == true) {
-               if (tf->type == TF_TYPE_HWPWL)
-                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
-                                       &tf->pwl);
-               else if (tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm_helper_translate_curve_to_degamma_hw_format(tf,
-                                       &dpp_base->degamma_params);
-                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
-                               &dpp_base->degamma_params);
-               }
-               return true;
-       }
-       /* handle here the optimized cases when de-gamma ROM could be used.
-        *
-        */
-       if (tf->type == TF_TYPE_PREDEFINED) {
-               switch (tf->tf) {
-               case TRANSFER_FUNCTION_SRGB:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base,
-                                       IPP_DEGAMMA_MODE_HW_sRGB);
-                       break;
-               case TRANSFER_FUNCTION_BT709:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base,
-                                       IPP_DEGAMMA_MODE_HW_xvYCC);
-                       break;
-               case TRANSFER_FUNCTION_LINEAR:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base,
-                                       IPP_DEGAMMA_MODE_BYPASS);
-                       break;
-               case TRANSFER_FUNCTION_PQ:
-                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_USER_PWL);
-                       cm_helper_translate_curve_to_degamma_hw_format(tf, &dpp_base->degamma_params);
-                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base, &dpp_base->degamma_params);
-                       result = true;
-                       break;
-               default:
-                       result = false;
-                       break;
-               }
-       } else if (tf->type == TF_TYPE_BYPASS)
-               dpp_base->funcs->dpp_set_degamma(dpp_base,
-                               IPP_DEGAMMA_MODE_BYPASS);
-       else {
-               /*
-                * if we are here, we did not handle correctly.
-                * fix is required for this use case
-                */
-               BREAK_TO_DEBUGGER();
-               dpp_base->funcs->dpp_set_degamma(dpp_base,
-                               IPP_DEGAMMA_MODE_BYPASS);
-       }
-
-       return result;
-}
-
-void dcn20_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 1;
-       int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst };
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               opp_inst[opp_cnt] = odm_pipe->stream_res.opp->inst;
-               opp_cnt++;
-       }
-
-       if (opp_cnt > 1)
-               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
-                               pipe_ctx->stream_res.tg,
-                               opp_inst, opp_cnt,
-                               &pipe_ctx->stream->timing);
-       else
-               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
-}
-
-void dcn20_blank_pixel_data(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool blank)
-{
-       struct tg_color black_color = {0};
-       struct stream_resource *stream_res = &pipe_ctx->stream_res;
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       enum dc_color_space color_space = stream->output_color_space;
-       enum controller_dp_test_pattern test_pattern = CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR;
-       enum controller_dp_color_space test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
-       struct pipe_ctx *odm_pipe;
-       int odm_cnt = 1;
-       int h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
-       int v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
-       int odm_slice_width, last_odm_slice_width, offset = 0;
-
-       if (stream->link->test_pattern_enabled)
-               return;
-
-       /* get opp dpg blank color */
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-               odm_cnt++;
-       odm_slice_width = h_active / odm_cnt;
-       last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
-
-       if (blank) {
-               dc->hwss.set_abm_immediate_disable(pipe_ctx);
-
-               if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
-                       test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
-                       test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
-               }
-       } else {
-               test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
-       }
-
-       odm_pipe = pipe_ctx;
-
-       while (odm_pipe->next_odm_pipe) {
-               dc->hwss.set_disp_pattern_generator(dc,
-                               odm_pipe,
-                               test_pattern,
-                               test_pattern_color_space,
-                               stream->timing.display_color_depth,
-                               &black_color,
-                               odm_slice_width,
-                               v_active,
-                               offset);
-               offset += odm_slice_width;
-               odm_pipe = odm_pipe->next_odm_pipe;
-       }
-
-       dc->hwss.set_disp_pattern_generator(dc,
-                       odm_pipe,
-                       test_pattern,
-                       test_pattern_color_space,
-                       stream->timing.display_color_depth,
-                       &black_color,
-                       last_odm_slice_width,
-                       v_active,
-                       offset);
-
-       if (!blank)
-               if (stream_res->abm) {
-                       dc->hwss.set_pipe(pipe_ctx);
-                       stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
-               }
-}
-
-
-static void dcn20_power_on_plane_resources(
-       struct dce_hwseq *hws,
-       struct pipe_ctx *pipe_ctx)
-{
-       DC_LOGGER_INIT(hws->ctx->logger);
-
-       if (hws->funcs.dpp_root_clock_control)
-               hws->funcs.dpp_root_clock_control(hws, pipe_ctx->plane_res.dpp->inst, true);
-
-       if (REG(DC_IP_REQUEST_CNTL)) {
-               REG_SET(DC_IP_REQUEST_CNTL, 0,
-                               IP_REQUEST_EN, 1);
-
-               if (hws->funcs.dpp_pg_control)
-                       hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true);
-
-               if (hws->funcs.hubp_pg_control)
-                       hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true);
-
-               REG_SET(DC_IP_REQUEST_CNTL, 0,
-                               IP_REQUEST_EN, 0);
-               DC_LOG_DEBUG(
-                               "Un-gated front end for pipe %d\n", pipe_ctx->plane_res.hubp->inst);
-       }
-}
-
-static void dcn20_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                              struct dc_state *context)
-{
-       //if (dc->debug.sanity_checks) {
-       //      dcn10_verify_allow_pstate_change_high(dc);
-       //}
-       dcn20_power_on_plane_resources(dc->hwseq, pipe_ctx);
-
-       /* enable DCFCLK current DCHUB */
-       pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
-
-       /* initialize HUBP on power up */
-       pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp);
-
-       /* make sure OPP_PIPE_CLOCK_EN = 1 */
-       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
-                       pipe_ctx->stream_res.opp,
-                       true);
-
-/* TODO: enable/disable in dm as per update type.
-       if (plane_state) {
-               DC_LOG_DC(dc->ctx->logger,
-                               "Pipe:%d 0x%x: addr hi:0x%x, "
-                               "addr low:0x%x, "
-                               "src: %d, %d, %d,"
-                               " %d; dst: %d, %d, %d, %d;\n",
-                               pipe_ctx->pipe_idx,
-                               plane_state,
-                               plane_state->address.grph.addr.high_part,
-                               plane_state->address.grph.addr.low_part,
-                               plane_state->src_rect.x,
-                               plane_state->src_rect.y,
-                               plane_state->src_rect.width,
-                               plane_state->src_rect.height,
-                               plane_state->dst_rect.x,
-                               plane_state->dst_rect.y,
-                               plane_state->dst_rect.width,
-                               plane_state->dst_rect.height);
-
-               DC_LOG_DC(dc->ctx->logger,
-                               "Pipe %d: width, height, x, y         format:%d\n"
-                               "viewport:%d, %d, %d, %d\n"
-                               "recout:  %d, %d, %d, %d\n",
-                               pipe_ctx->pipe_idx,
-                               plane_state->format,
-                               pipe_ctx->plane_res.scl_data.viewport.width,
-                               pipe_ctx->plane_res.scl_data.viewport.height,
-                               pipe_ctx->plane_res.scl_data.viewport.x,
-                               pipe_ctx->plane_res.scl_data.viewport.y,
-                               pipe_ctx->plane_res.scl_data.recout.width,
-                               pipe_ctx->plane_res.scl_data.recout.height,
-                               pipe_ctx->plane_res.scl_data.recout.x,
-                               pipe_ctx->plane_res.scl_data.recout.y);
-               print_rq_dlg_ttu(dc, pipe_ctx);
-       }
-*/
-       if (dc->vm_pa_config.valid) {
-               struct vm_system_aperture_param apt;
-
-               apt.sys_default.quad_part = 0;
-
-               apt.sys_low.quad_part = dc->vm_pa_config.system_aperture.start_addr;
-               apt.sys_high.quad_part = dc->vm_pa_config.system_aperture.end_addr;
-
-               // Program system aperture settings
-               pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
-       }
-
-       if (!pipe_ctx->top_pipe
-               && pipe_ctx->plane_state
-               && pipe_ctx->plane_state->flip_int_enabled
-               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
-                       pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
-
-//     if (dc->debug.sanity_checks) {
-//             dcn10_verify_allow_pstate_change_high(dc);
-//     }
-}
-
-void dcn20_pipe_control_lock(
-       struct dc *dc,
-       struct pipe_ctx *pipe,
-       bool lock)
-{
-       struct pipe_ctx *temp_pipe;
-       bool flip_immediate = false;
-
-       /* use TG master update lock to lock everything on the TG
-        * therefore only top pipe need to lock
-        */
-       if (!pipe || pipe->top_pipe)
-               return;
-
-       if (pipe->plane_state != NULL)
-               flip_immediate = pipe->plane_state->flip_immediate;
-
-       if  (pipe->stream_res.gsl_group > 0) {
-           temp_pipe = pipe->bottom_pipe;
-           while (!flip_immediate && temp_pipe) {
-                   if (temp_pipe->plane_state != NULL)
-                           flip_immediate = temp_pipe->plane_state->flip_immediate;
-                   temp_pipe = temp_pipe->bottom_pipe;
-           }
-       }
-
-       if (flip_immediate && lock) {
-               const int TIMEOUT_FOR_FLIP_PENDING_US = 100000;
-               unsigned int polling_interval_us = 1;
-               int i;
-
-               temp_pipe = pipe;
-               while (temp_pipe) {
-                       if (temp_pipe->plane_state && temp_pipe->plane_state->flip_immediate) {
-                               for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING_US / polling_interval_us; ++i) {
-                                       if (!temp_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(temp_pipe->plane_res.hubp))
-                                               break;
-                                       udelay(polling_interval_us);
-                               }
-
-                               /* no reason it should take this long for immediate flips */
-                               ASSERT(i != TIMEOUT_FOR_FLIP_PENDING_US);
-                       }
-                       temp_pipe = temp_pipe->bottom_pipe;
-               }
-       }
-
-       /* In flip immediate and pipe splitting case, we need to use GSL
-        * for synchronization. Only do setup on locking and on flip type change.
-        */
-       if (lock && (pipe->bottom_pipe != NULL || !flip_immediate))
-               if ((flip_immediate && pipe->stream_res.gsl_group == 0) ||
-                   (!flip_immediate && pipe->stream_res.gsl_group > 0))
-                       dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate);
-
-       if (pipe->plane_state != NULL)
-               flip_immediate = pipe->plane_state->flip_immediate;
-
-       temp_pipe = pipe->bottom_pipe;
-       while (flip_immediate && temp_pipe) {
-           if (temp_pipe->plane_state != NULL)
-               flip_immediate = temp_pipe->plane_state->flip_immediate;
-           temp_pipe = temp_pipe->bottom_pipe;
-       }
-
-       if (!lock && pipe->stream_res.gsl_group > 0 && pipe->plane_state &&
-               !flip_immediate)
-           dcn20_setup_gsl_group_as_lock(dc, pipe, false);
-
-       if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) {
-               union dmub_hw_lock_flags hw_locks = { 0 };
-               struct dmub_hw_lock_inst_flags inst_flags = { 0 };
-
-               hw_locks.bits.lock_pipe = 1;
-               inst_flags.otg_inst =  pipe->stream_res.tg->inst;
-
-               if (pipe->plane_state != NULL)
-                       hw_locks.bits.triple_buffer_lock = pipe->plane_state->triplebuffer_flips;
-
-               dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
-                                       lock,
-                                       &hw_locks,
-                                       &inst_flags);
-       } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
-               if (lock)
-                       pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
-               else
-                       pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
-       } else {
-               if (lock)
-                       pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
-               else
-                       pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
-       }
-}
-
-static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx *new_pipe)
-{
-       new_pipe->update_flags.raw = 0;
-
-       /* If non-phantom pipe is being transitioned to a phantom pipe,
-        * set disable and return immediately. This is because the pipe
-        * that was previously in use must be fully disabled before we
-        * can "enable" it as a phantom pipe (since the OTG will certainly
-        * be different). The post_unlock sequence will set the correct
-        * update flags to enable the phantom pipe.
-        */
-       if (old_pipe->plane_state && !old_pipe->plane_state->is_phantom &&
-                       new_pipe->plane_state && new_pipe->plane_state->is_phantom) {
-               new_pipe->update_flags.bits.disable = 1;
-               return;
-       }
-
-       /* Exit on unchanged, unused pipe */
-       if (!old_pipe->plane_state && !new_pipe->plane_state)
-               return;
-       /* Detect pipe enable/disable */
-       if (!old_pipe->plane_state && new_pipe->plane_state) {
-               new_pipe->update_flags.bits.enable = 1;
-               new_pipe->update_flags.bits.mpcc = 1;
-               new_pipe->update_flags.bits.dppclk = 1;
-               new_pipe->update_flags.bits.hubp_interdependent = 1;
-               new_pipe->update_flags.bits.hubp_rq_dlg_ttu = 1;
-               new_pipe->update_flags.bits.unbounded_req = 1;
-               new_pipe->update_flags.bits.gamut_remap = 1;
-               new_pipe->update_flags.bits.scaler = 1;
-               new_pipe->update_flags.bits.viewport = 1;
-               new_pipe->update_flags.bits.det_size = 1;
-               if (!new_pipe->top_pipe && !new_pipe->prev_odm_pipe) {
-                       new_pipe->update_flags.bits.odm = 1;
-                       new_pipe->update_flags.bits.global_sync = 1;
-               }
-               return;
-       }
-
-       /* For SubVP we need to unconditionally enable because any phantom pipes are
-        * always removed then newly added for every full updates whenever SubVP is in use.
-        * The remove-add sequence of the phantom pipe always results in the pipe
-        * being blanked in enable_stream_timing (DPG).
-        */
-       if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
-               new_pipe->update_flags.bits.enable = 1;
-
-       /* Phantom pipes are effectively disabled, if the pipe was previously phantom
-        * we have to enable
-        */
-       if (old_pipe->plane_state && old_pipe->plane_state->is_phantom &&
-                       new_pipe->plane_state && !new_pipe->plane_state->is_phantom)
-               new_pipe->update_flags.bits.enable = 1;
-
-       if (old_pipe->plane_state && !new_pipe->plane_state) {
-               new_pipe->update_flags.bits.disable = 1;
-               return;
-       }
-
-       /* Detect plane change */
-       if (old_pipe->plane_state != new_pipe->plane_state) {
-               new_pipe->update_flags.bits.plane_changed = true;
-       }
-
-       /* Detect top pipe only changes */
-       if (resource_is_pipe_type(new_pipe, OTG_MASTER)) {
-               /* Detect odm changes */
-               if (resource_is_odm_topology_changed(new_pipe, old_pipe))
-                       new_pipe->update_flags.bits.odm = 1;
-
-               /* Detect global sync changes */
-               if (old_pipe->pipe_dlg_param.vready_offset != new_pipe->pipe_dlg_param.vready_offset
-                               || old_pipe->pipe_dlg_param.vstartup_start != new_pipe->pipe_dlg_param.vstartup_start
-                               || old_pipe->pipe_dlg_param.vupdate_offset != new_pipe->pipe_dlg_param.vupdate_offset
-                               || old_pipe->pipe_dlg_param.vupdate_width != new_pipe->pipe_dlg_param.vupdate_width)
-                       new_pipe->update_flags.bits.global_sync = 1;
-       }
-
-       if (old_pipe->det_buffer_size_kb != new_pipe->det_buffer_size_kb)
-               new_pipe->update_flags.bits.det_size = 1;
-
-       /*
-        * Detect opp / tg change, only set on change, not on enable
-        * Assume mpcc inst = pipe index, if not this code needs to be updated
-        * since mpcc is what is affected by these. In fact all of our sequence
-        * makes this assumption at the moment with how hubp reset is matched to
-        * same index mpcc reset.
-        */
-       if (old_pipe->stream_res.opp != new_pipe->stream_res.opp)
-               new_pipe->update_flags.bits.opp_changed = 1;
-       if (old_pipe->stream_res.tg != new_pipe->stream_res.tg)
-               new_pipe->update_flags.bits.tg_changed = 1;
-
-       /*
-        * Detect mpcc blending changes, only dpp inst and opp matter here,
-        * mpccs getting removed/inserted update connected ones during their own
-        * programming
-        */
-       if (old_pipe->plane_res.dpp != new_pipe->plane_res.dpp
-                       || old_pipe->stream_res.opp != new_pipe->stream_res.opp)
-               new_pipe->update_flags.bits.mpcc = 1;
-
-       /* Detect dppclk change */
-       if (old_pipe->plane_res.bw.dppclk_khz != new_pipe->plane_res.bw.dppclk_khz)
-               new_pipe->update_flags.bits.dppclk = 1;
-
-       /* Check for scl update */
-       if (memcmp(&old_pipe->plane_res.scl_data, &new_pipe->plane_res.scl_data, sizeof(struct scaler_data)))
-                       new_pipe->update_flags.bits.scaler = 1;
-       /* Check for vp update */
-       if (memcmp(&old_pipe->plane_res.scl_data.viewport, &new_pipe->plane_res.scl_data.viewport, sizeof(struct rect))
-                       || memcmp(&old_pipe->plane_res.scl_data.viewport_c,
-                               &new_pipe->plane_res.scl_data.viewport_c, sizeof(struct rect)))
-               new_pipe->update_flags.bits.viewport = 1;
-
-       /* Detect dlg/ttu/rq updates */
-       {
-               struct _vcs_dpi_display_dlg_regs_st old_dlg_attr = old_pipe->dlg_regs;
-               struct _vcs_dpi_display_ttu_regs_st old_ttu_attr = old_pipe->ttu_regs;
-               struct _vcs_dpi_display_dlg_regs_st *new_dlg_attr = &new_pipe->dlg_regs;
-               struct _vcs_dpi_display_ttu_regs_st *new_ttu_attr = &new_pipe->ttu_regs;
-
-               /* Detect pipe interdependent updates */
-               if (old_dlg_attr.dst_y_prefetch != new_dlg_attr->dst_y_prefetch ||
-                               old_dlg_attr.vratio_prefetch != new_dlg_attr->vratio_prefetch ||
-                               old_dlg_attr.vratio_prefetch_c != new_dlg_attr->vratio_prefetch_c ||
-                               old_dlg_attr.dst_y_per_vm_vblank != new_dlg_attr->dst_y_per_vm_vblank ||
-                               old_dlg_attr.dst_y_per_row_vblank != new_dlg_attr->dst_y_per_row_vblank ||
-                               old_dlg_attr.dst_y_per_vm_flip != new_dlg_attr->dst_y_per_vm_flip ||
-                               old_dlg_attr.dst_y_per_row_flip != new_dlg_attr->dst_y_per_row_flip ||
-                               old_dlg_attr.refcyc_per_meta_chunk_vblank_l != new_dlg_attr->refcyc_per_meta_chunk_vblank_l ||
-                               old_dlg_attr.refcyc_per_meta_chunk_vblank_c != new_dlg_attr->refcyc_per_meta_chunk_vblank_c ||
-                               old_dlg_attr.refcyc_per_meta_chunk_flip_l != new_dlg_attr->refcyc_per_meta_chunk_flip_l ||
-                               old_dlg_attr.refcyc_per_line_delivery_pre_l != new_dlg_attr->refcyc_per_line_delivery_pre_l ||
-                               old_dlg_attr.refcyc_per_line_delivery_pre_c != new_dlg_attr->refcyc_per_line_delivery_pre_c ||
-                               old_ttu_attr.refcyc_per_req_delivery_pre_l != new_ttu_attr->refcyc_per_req_delivery_pre_l ||
-                               old_ttu_attr.refcyc_per_req_delivery_pre_c != new_ttu_attr->refcyc_per_req_delivery_pre_c ||
-                               old_ttu_attr.refcyc_per_req_delivery_pre_cur0 != new_ttu_attr->refcyc_per_req_delivery_pre_cur0 ||
-                               old_ttu_attr.refcyc_per_req_delivery_pre_cur1 != new_ttu_attr->refcyc_per_req_delivery_pre_cur1 ||
-                               old_ttu_attr.min_ttu_vblank != new_ttu_attr->min_ttu_vblank ||
-                               old_ttu_attr.qos_level_flip != new_ttu_attr->qos_level_flip) {
-                       old_dlg_attr.dst_y_prefetch = new_dlg_attr->dst_y_prefetch;
-                       old_dlg_attr.vratio_prefetch = new_dlg_attr->vratio_prefetch;
-                       old_dlg_attr.vratio_prefetch_c = new_dlg_attr->vratio_prefetch_c;
-                       old_dlg_attr.dst_y_per_vm_vblank = new_dlg_attr->dst_y_per_vm_vblank;
-                       old_dlg_attr.dst_y_per_row_vblank = new_dlg_attr->dst_y_per_row_vblank;
-                       old_dlg_attr.dst_y_per_vm_flip = new_dlg_attr->dst_y_per_vm_flip;
-                       old_dlg_attr.dst_y_per_row_flip = new_dlg_attr->dst_y_per_row_flip;
-                       old_dlg_attr.refcyc_per_meta_chunk_vblank_l = new_dlg_attr->refcyc_per_meta_chunk_vblank_l;
-                       old_dlg_attr.refcyc_per_meta_chunk_vblank_c = new_dlg_attr->refcyc_per_meta_chunk_vblank_c;
-                       old_dlg_attr.refcyc_per_meta_chunk_flip_l = new_dlg_attr->refcyc_per_meta_chunk_flip_l;
-                       old_dlg_attr.refcyc_per_line_delivery_pre_l = new_dlg_attr->refcyc_per_line_delivery_pre_l;
-                       old_dlg_attr.refcyc_per_line_delivery_pre_c = new_dlg_attr->refcyc_per_line_delivery_pre_c;
-                       old_ttu_attr.refcyc_per_req_delivery_pre_l = new_ttu_attr->refcyc_per_req_delivery_pre_l;
-                       old_ttu_attr.refcyc_per_req_delivery_pre_c = new_ttu_attr->refcyc_per_req_delivery_pre_c;
-                       old_ttu_attr.refcyc_per_req_delivery_pre_cur0 = new_ttu_attr->refcyc_per_req_delivery_pre_cur0;
-                       old_ttu_attr.refcyc_per_req_delivery_pre_cur1 = new_ttu_attr->refcyc_per_req_delivery_pre_cur1;
-                       old_ttu_attr.min_ttu_vblank = new_ttu_attr->min_ttu_vblank;
-                       old_ttu_attr.qos_level_flip = new_ttu_attr->qos_level_flip;
-                       new_pipe->update_flags.bits.hubp_interdependent = 1;
-               }
-               /* Detect any other updates to ttu/rq/dlg */
-               if (memcmp(&old_dlg_attr, &new_pipe->dlg_regs, sizeof(old_dlg_attr)) ||
-                               memcmp(&old_ttu_attr, &new_pipe->ttu_regs, sizeof(old_ttu_attr)) ||
-                               memcmp(&old_pipe->rq_regs, &new_pipe->rq_regs, sizeof(old_pipe->rq_regs)))
-                       new_pipe->update_flags.bits.hubp_rq_dlg_ttu = 1;
-       }
-
-       if (old_pipe->unbounded_req != new_pipe->unbounded_req)
-               new_pipe->update_flags.bits.unbounded_req = 1;
-}
-
-static void dcn20_update_dchubp_dpp(
-       struct dc *dc,
-       struct pipe_ctx *pipe_ctx,
-       struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       struct dccg *dccg = dc->res_pool->dccg;
-       bool viewport_changed = false;
-
-       if (pipe_ctx->update_flags.bits.dppclk)
-               dpp->funcs->dpp_dppclk_control(dpp, false, true);
-
-       if (pipe_ctx->update_flags.bits.enable)
-               dccg->funcs->update_dpp_dto(dccg, dpp->inst, pipe_ctx->plane_res.bw.dppclk_khz);
-
-       /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
-        * VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
-        * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
-        */
-       if (pipe_ctx->update_flags.bits.hubp_rq_dlg_ttu) {
-               hubp->funcs->hubp_vtg_sel(hubp, pipe_ctx->stream_res.tg->inst);
-
-               hubp->funcs->hubp_setup(
-                       hubp,
-                       &pipe_ctx->dlg_regs,
-                       &pipe_ctx->ttu_regs,
-                       &pipe_ctx->rq_regs,
-                       &pipe_ctx->pipe_dlg_param);
-       }
-
-       if (pipe_ctx->update_flags.bits.unbounded_req && hubp->funcs->set_unbounded_requesting)
-               hubp->funcs->set_unbounded_requesting(hubp, pipe_ctx->unbounded_req);
-
-       if (pipe_ctx->update_flags.bits.hubp_interdependent)
-               hubp->funcs->hubp_setup_interdependent(
-                       hubp,
-                       &pipe_ctx->dlg_regs,
-                       &pipe_ctx->ttu_regs);
-
-       if (pipe_ctx->update_flags.bits.enable ||
-                       pipe_ctx->update_flags.bits.plane_changed ||
-                       plane_state->update_flags.bits.bpp_change ||
-                       plane_state->update_flags.bits.input_csc_change ||
-                       plane_state->update_flags.bits.color_space_change ||
-                       plane_state->update_flags.bits.coeff_reduction_change) {
-               struct dc_bias_and_scale bns_params = {0};
-
-               // program the input csc
-               dpp->funcs->dpp_setup(dpp,
-                               plane_state->format,
-                               EXPANSION_MODE_ZERO,
-                               plane_state->input_csc_color_matrix,
-                               plane_state->color_space,
-                               NULL);
-
-               if (dpp->funcs->dpp_program_bias_and_scale) {
-                       //TODO :for CNVC set scale and bias registers if necessary
-                       build_prescale_params(&bns_params, plane_state);
-                       dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
-               }
-       }
-
-       if (pipe_ctx->update_flags.bits.mpcc
-                       || pipe_ctx->update_flags.bits.plane_changed
-                       || plane_state->update_flags.bits.global_alpha_change
-                       || plane_state->update_flags.bits.per_pixel_alpha_change) {
-               // MPCC inst is equal to pipe index in practice
-               hws->funcs.update_mpcc(dc, pipe_ctx);
-       }
-
-       if (pipe_ctx->update_flags.bits.scaler ||
-                       plane_state->update_flags.bits.scaling_change ||
-                       plane_state->update_flags.bits.position_change ||
-                       plane_state->update_flags.bits.per_pixel_alpha_change ||
-                       pipe_ctx->stream->update_flags.bits.scaling) {
-               pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->plane_state->per_pixel_alpha;
-               ASSERT(pipe_ctx->plane_res.scl_data.lb_params.depth == LB_PIXEL_DEPTH_36BPP);
-               /* scaler configuration */
-               pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
-                               pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
-       }
-
-       if (pipe_ctx->update_flags.bits.viewport ||
-                       (context == dc->current_state && plane_state->update_flags.bits.position_change) ||
-                       (context == dc->current_state && plane_state->update_flags.bits.scaling_change) ||
-                       (context == dc->current_state && pipe_ctx->stream->update_flags.bits.scaling)) {
-
-               hubp->funcs->mem_program_viewport(
-                       hubp,
-                       &pipe_ctx->plane_res.scl_data.viewport,
-                       &pipe_ctx->plane_res.scl_data.viewport_c);
-               viewport_changed = true;
-       }
-
-       /* Any updates are handled in dc interface, just need to apply existing for plane enable */
-       if ((pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed ||
-                       pipe_ctx->update_flags.bits.scaler || viewport_changed == true) &&
-                       pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
-               dc->hwss.set_cursor_position(pipe_ctx);
-               dc->hwss.set_cursor_attribute(pipe_ctx);
-
-               if (dc->hwss.set_cursor_sdr_white_level)
-                       dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
-       }
-
-       /* Any updates are handled in dc interface, just need
-        * to apply existing for plane enable / opp change */
-       if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed
-                       || pipe_ctx->update_flags.bits.plane_changed
-                       || pipe_ctx->stream->update_flags.bits.gamut_remap
-                       || plane_state->update_flags.bits.gamut_remap_change
-                       || pipe_ctx->stream->update_flags.bits.out_csc) {
-               /* dpp/cm gamut remap*/
-               dc->hwss.program_gamut_remap(pipe_ctx);
-
-               /*call the dcn2 method which uses mpc csc*/
-               dc->hwss.program_output_csc(dc,
-                               pipe_ctx,
-                               pipe_ctx->stream->output_color_space,
-                               pipe_ctx->stream->csc_color_matrix.matrix,
-                               hubp->opp_id);
-       }
-
-       if (pipe_ctx->update_flags.bits.enable ||
-                       pipe_ctx->update_flags.bits.plane_changed ||
-                       pipe_ctx->update_flags.bits.opp_changed ||
-                       plane_state->update_flags.bits.pixel_format_change ||
-                       plane_state->update_flags.bits.horizontal_mirror_change ||
-                       plane_state->update_flags.bits.rotation_change ||
-                       plane_state->update_flags.bits.swizzle_change ||
-                       plane_state->update_flags.bits.dcc_change ||
-                       plane_state->update_flags.bits.bpp_change ||
-                       plane_state->update_flags.bits.scaling_change ||
-                       plane_state->update_flags.bits.plane_size_change) {
-               struct plane_size size = plane_state->plane_size;
-
-               size.surface_size = pipe_ctx->plane_res.scl_data.viewport;
-               hubp->funcs->hubp_program_surface_config(
-                       hubp,
-                       plane_state->format,
-                       &plane_state->tiling_info,
-                       &size,
-                       plane_state->rotation,
-                       &plane_state->dcc,
-                       plane_state->horizontal_mirror,
-                       0);
-               hubp->power_gated = false;
-       }
-
-       if (pipe_ctx->update_flags.bits.enable ||
-               pipe_ctx->update_flags.bits.plane_changed ||
-               plane_state->update_flags.bits.addr_update) {
-               if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) &&
-                               pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN) {
-                       union block_sequence_params params;
-
-                       params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
-                       params.subvp_save_surf_addr.addr = &pipe_ctx->plane_state->address;
-                       params.subvp_save_surf_addr.subvp_index = pipe_ctx->subvp_index;
-                       hwss_subvp_save_surf_addr(&params);
-               }
-               hws->funcs.update_plane_addr(dc, pipe_ctx);
-       }
-
-       if (pipe_ctx->update_flags.bits.enable)
-               hubp->funcs->set_blank(hubp, false);
-       /* If the stream paired with this plane is phantom, the plane is also phantom */
-       if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM
-                       && hubp->funcs->phantom_hubp_post_enable)
-               hubp->funcs->phantom_hubp_post_enable(hubp);
-}
-
-static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
-{
-       struct pipe_ctx *other_pipe;
-       int vready_offset = pipe->pipe_dlg_param.vready_offset;
-
-       /* Always use the largest vready_offset of all connected pipes */
-       for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-       for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-       for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-       for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
-               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
-                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
-       }
-
-       return vready_offset;
-}
-
-static void dcn20_program_pipe(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* Only need to unblank on top pipe */
-       if (resource_is_pipe_type(pipe_ctx, OTG_MASTER)) {
-               if (pipe_ctx->update_flags.bits.enable ||
-                               pipe_ctx->update_flags.bits.odm ||
-                               pipe_ctx->stream->update_flags.bits.abm_level)
-                       hws->funcs.blank_pixel_data(dc, pipe_ctx,
-                                       !pipe_ctx->plane_state ||
-                                       !pipe_ctx->plane_state->visible);
-       }
-
-       /* Only update TG on top pipe */
-       if (pipe_ctx->update_flags.bits.global_sync && !pipe_ctx->top_pipe
-                       && !pipe_ctx->prev_odm_pipe) {
-               pipe_ctx->stream_res.tg->funcs->program_global_sync(
-                               pipe_ctx->stream_res.tg,
-                               calculate_vready_offset_for_group(pipe_ctx),
-                               pipe_ctx->pipe_dlg_param.vstartup_start,
-                               pipe_ctx->pipe_dlg_param.vupdate_offset,
-                               pipe_ctx->pipe_dlg_param.vupdate_width);
-
-               if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM)
-                       pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
-
-               pipe_ctx->stream_res.tg->funcs->set_vtg_params(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
-
-               if (hws->funcs.setup_vupdate_interrupt)
-                       hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
-       }
-
-       if (pipe_ctx->update_flags.bits.odm)
-               hws->funcs.update_odm(dc, context, pipe_ctx);
-
-       if (pipe_ctx->update_flags.bits.enable) {
-               if (hws->funcs.enable_plane)
-                       hws->funcs.enable_plane(dc, pipe_ctx, context);
-               else
-                       dcn20_enable_plane(dc, pipe_ctx, context);
-
-               if (dc->res_pool->hubbub->funcs->force_wm_propagate_to_pipes)
-                       dc->res_pool->hubbub->funcs->force_wm_propagate_to_pipes(dc->res_pool->hubbub);
-       }
-
-       if (dc->res_pool->hubbub->funcs->program_det_size && pipe_ctx->update_flags.bits.det_size)
-               dc->res_pool->hubbub->funcs->program_det_size(
-                       dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->det_buffer_size_kb);
-
-       if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
-               dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
-
-       if (pipe_ctx->update_flags.bits.enable
-                       || pipe_ctx->plane_state->update_flags.bits.hdr_mult)
-               hws->funcs.set_hdr_multiplier(pipe_ctx);
-
-       if (pipe_ctx->update_flags.bits.enable ||
-           pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-           pipe_ctx->plane_state->update_flags.bits.gamma_change ||
-           pipe_ctx->plane_state->update_flags.bits.lut_3d)
-               hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
-
-       /* dcn10_translate_regamma_to_hw_format takes 750us to finish
-        * only do gamma programming for powering on, internal memcmp to avoid
-        * updating on slave planes
-        */
-       if (pipe_ctx->update_flags.bits.enable ||
-                       pipe_ctx->update_flags.bits.plane_changed ||
-                       pipe_ctx->stream->update_flags.bits.out_tf ||
-                       pipe_ctx->plane_state->update_flags.bits.output_tf_change)
-               hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
-
-       /* If the pipe has been enabled or has a different opp, we
-        * should reprogram the fmt. This deals with cases where
-        * interation between mpc and odm combine on different streams
-        * causes a different pipe to be chosen to odm combine with.
-        */
-       if (pipe_ctx->update_flags.bits.enable
-           || pipe_ctx->update_flags.bits.opp_changed) {
-
-               pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
-                       pipe_ctx->stream_res.opp,
-                       COLOR_SPACE_YCBCR601,
-                       pipe_ctx->stream->timing.display_color_depth,
-                       pipe_ctx->stream->signal);
-
-               pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
-                       pipe_ctx->stream_res.opp,
-                       &pipe_ctx->stream->bit_depth_params,
-                       &pipe_ctx->stream->clamping);
-       }
-
-       /* Set ABM pipe after other pipe configurations done */
-       if (pipe_ctx->plane_state->visible) {
-               if (pipe_ctx->stream_res.abm) {
-                       dc->hwss.set_pipe(pipe_ctx);
-                       pipe_ctx->stream_res.abm->funcs->set_abm_level(pipe_ctx->stream_res.abm,
-                               pipe_ctx->stream->abm_level);
-               }
-       }
-}
-
-void dcn20_program_front_end_for_ctx(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-       DC_LOGGER_INIT(dc->ctx->logger);
-
-       if (resource_is_pipe_topology_changed(dc->current_state, context))
-               resource_log_pipe_topology_update(dc, context);
-
-       if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-                       if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->plane_state) {
-                               ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
-                               /*turn off triple buffer for full update*/
-                               dc->hwss.program_triplebuffer(
-                                               dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
-                       }
-               }
-       }
-
-       /* Set pipe update flags and lock pipes */
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i],
-                               &context->res_ctx.pipe_ctx[i]);
-
-       /* When disabling phantom pipes, turn on phantom OTG first (so we can get double
-        * buffer updates properly)
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct dc_stream_state *stream = dc->current_state->res_ctx.pipe_ctx[i].stream;
-
-               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable && stream &&
-                       dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
-                       struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
-
-                       if (tg->funcs->enable_crtc) {
-                               if (dc->hwss.blank_phantom) {
-                                       int main_pipe_width, main_pipe_height;
-
-                                       main_pipe_width = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.width;
-                                       main_pipe_height = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.height;
-                                       dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
-                               }
-                               tg->funcs->enable_crtc(tg);
-                       }
-               }
-       }
-       /* OTG blank before disabling all front ends */
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
-                               && !context->res_ctx.pipe_ctx[i].top_pipe
-                               && !context->res_ctx.pipe_ctx[i].prev_odm_pipe
-                               && context->res_ctx.pipe_ctx[i].stream)
-                       hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);
-
-
-       /* Disconnect mpcc */
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
-                               || context->res_ctx.pipe_ctx[i].update_flags.bits.opp_changed) {
-                       struct hubbub *hubbub = dc->res_pool->hubbub;
-
-                       /* Phantom pipe DET should be 0, but if a pipe in use is being transitioned to phantom
-                        * then we want to do the programming here (effectively it's being disabled). If we do
-                        * the programming later the DET won't be updated until the OTG for the phantom pipe is
-                        * turned on (i.e. in an MCLK switch) which can come in too late and cause issues with
-                        * DET allocation.
-                        */
-                       if (hubbub->funcs->program_det_size && (context->res_ctx.pipe_ctx[i].update_flags.bits.disable ||
-                                       (context->res_ctx.pipe_ctx[i].plane_state && context->res_ctx.pipe_ctx[i].plane_state->is_phantom)))
-                               hubbub->funcs->program_det_size(hubbub, dc->current_state->res_ctx.pipe_ctx[i].plane_res.hubp->inst, 0);
-                       hws->funcs.plane_atomic_disconnect(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
-                       DC_LOG_DC("Reset mpcc for pipe %d\n", dc->current_state->res_ctx.pipe_ctx[i].pipe_idx);
-               }
-
-       /*
-        * Program all updated pipes, order matters for mpcc setup. Start with
-        * top pipe and program all pipes that follow in order
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe->plane_state && !pipe->top_pipe) {
-                       while (pipe) {
-                               if (hws->funcs.program_pipe)
-                                       hws->funcs.program_pipe(dc, pipe, context);
-                               else {
-                                       /* Don't program phantom pipes in the regular front end programming sequence.
-                                        * There is an MPO transition case where a pipe being used by a video plane is
-                                        * transitioned directly to be a phantom pipe when closing the MPO video. However
-                                        * the phantom pipe will program a new HUBP_VTG_SEL (update takes place right away),
-                                        * but the MPO still exists until the double buffered update of the main pipe so we
-                                        * will get a frame of underflow if the phantom pipe is programmed here.
-                                        */
-                                       if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_PHANTOM)
-                                               dcn20_program_pipe(dc, pipe, context);
-                               }
-
-                               pipe = pipe->bottom_pipe;
-                       }
-               }
-               /* Program secondary blending tree and writeback pipes */
-               pipe = &context->res_ctx.pipe_ctx[i];
-               if (!pipe->top_pipe && !pipe->prev_odm_pipe
-                               && pipe->stream && pipe->stream->num_wb_info > 0
-                               && (pipe->update_flags.raw || (pipe->plane_state && pipe->plane_state->update_flags.raw)
-                                       || pipe->stream->update_flags.raw)
-                               && hws->funcs.program_all_writeback_pipes_in_tree)
-                       hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context);
-
-               /* Avoid underflow by check of pipe line read when adding 2nd plane. */
-               if (hws->wa.wait_hubpret_read_start_during_mpo_transition &&
-                       !pipe->top_pipe &&
-                       pipe->stream &&
-                       pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start &&
-                       dc->current_state->stream_status[0].plane_count == 1 &&
-                       context->stream_status[0].plane_count > 1) {
-                       pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
-               }
-
-               /* when dynamic ODM is active, pipes must be reconfigured when all planes are
-                * disabled, as some transitions will leave software and hardware state
-                * mismatched.
-                */
-               if (dc->debug.enable_single_display_2to1_odm_policy &&
-                       pipe->stream &&
-                       pipe->update_flags.bits.disable &&
-                       !pipe->prev_odm_pipe &&
-                       hws->funcs.update_odm)
-                       hws->funcs.update_odm(dc, context, pipe);
-       }
-}
-
-void dcn20_post_unlock_program_front_end(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-       const unsigned int TIMEOUT_FOR_PIPE_ENABLE_US = 100000;
-       unsigned int polling_interval_us = 1;
-       struct dce_hwseq *hwseq = dc->hwseq;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
-                       dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
-
-       /*
-        * If we are enabling a pipe, we need to wait for pending clear as this is a critical
-        * part of the enable operation otherwise, DM may request an immediate flip which
-        * will cause HW to perform an "immediate enable" (as opposed to "vsync enable") which
-        * is unsupported on DCN.
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-               // Don't check flip pending on phantom pipes
-               if (pipe->plane_state && !pipe->top_pipe && pipe->update_flags.bits.enable &&
-                               pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
-                       struct hubp *hubp = pipe->plane_res.hubp;
-                       int j = 0;
-                       for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_US / polling_interval_us
-                                       && hubp->funcs->hubp_is_flip_pending(hubp); j++)
-                               udelay(polling_interval_us);
-               }
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe->plane_state && !pipe->top_pipe) {
-                       /* Program phantom pipe here to prevent a frame of underflow in the MPO transition
-                        * case (if a pipe being used for a video plane transitions to a phantom pipe, it
-                        * can underflow due to HUBP_VTG_SEL programming if done in the regular front end
-                        * programming sequence).
-                        */
-                       while (pipe) {
-                               if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
-                                       /* When turning on the phantom pipe we want to run through the
-                                        * entire enable sequence, so apply all the "enable" flags.
-                                        */
-                                       if (dc->hwss.apply_update_flags_for_phantom)
-                                               dc->hwss.apply_update_flags_for_phantom(pipe);
-                                       if (dc->hwss.update_phantom_vp_position)
-                                               dc->hwss.update_phantom_vp_position(dc, context, pipe);
-                                       dcn20_program_pipe(dc, pipe, context);
-                               }
-                               pipe = pipe->bottom_pipe;
-                       }
-               }
-       }
-
-       /* P-State support transitions:
-        * Natural -> FPO:              P-State disabled in prepare, force disallow anytime is safe
-        * FPO -> Natural:              Unforce anytime after FW disable is safe (P-State will assert naturally)
-        * Unsupported -> FPO:  P-State enabled in optimize, force disallow anytime is safe
-        * FPO -> Unsupported:  P-State disabled in prepare, unforce disallow anytime is safe
-        * FPO <-> SubVP:               Force disallow is maintained on the FPO / SubVP pipes
-        */
-       if (hwseq && hwseq->funcs.update_force_pstate)
-               dc->hwseq->funcs.update_force_pstate(dc, context);
-
-       /* Only program the MALL registers after all the main and phantom pipes
-        * are done programming.
-        */
-       if (hwseq->funcs.program_mall_pipe_config)
-               hwseq->funcs.program_mall_pipe_config(dc, context);
-
-       /* WA to apply WM setting*/
-       if (hwseq->wa.DEGVIDCN21)
-               dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub);
-
-
-       /* WA for stutter underflow during MPO transitions when adding 2nd plane */
-       if (hwseq->wa.disallow_self_refresh_during_multi_plane_transition) {
-
-               if (dc->current_state->stream_status[0].plane_count == 1 &&
-                               context->stream_status[0].plane_count > 1) {
-
-                       struct timing_generator *tg = dc->res_pool->timing_generators[0];
-
-                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, false);
-
-                       hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied = true;
-                       hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied_on_frame = tg->funcs->get_frame_count(tg);
-               }
-       }
-}
-
-void dcn20_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       unsigned int compbuf_size_kb = 0;
-       unsigned int cache_wm_a = context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns;
-       unsigned int i;
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       false);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               // At optimize don't restore the original watermark value
-               if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
-                       context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
-                       break;
-               }
-       }
-
-       /* program dchubbub watermarks:
-        * For assigning wm_optimized_required, use |= operator since we don't want
-        * to clear the value if the optimize has not happened yet
-        */
-       dc->wm_optimized_required |= hubbub->funcs->program_watermarks(hubbub,
-                                       &context->bw_ctx.bw.dcn.watermarks,
-                                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
-                                       false);
-
-       // Restore the real watermark so we can commit the value to DMCUB
-       // DMCUB uses the "original" watermark value in SubVP MCLK switch
-       context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = cache_wm_a;
-
-       /* decrease compbuf size */
-       if (hubbub->funcs->program_compbuf_size) {
-               if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) {
-                       compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes;
-                       dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
-               } else {
-                       compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb;
-                       dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
-               }
-
-               hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false);
-       }
-}
-
-void dcn20_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       int i;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               // At optimize don't need  to restore the original watermark value
-               if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
-                       context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
-                       break;
-               }
-       }
-
-       /* program dchubbub watermarks */
-       hubbub->funcs->program_watermarks(hubbub,
-                                       &context->bw_ctx.bw.dcn.watermarks,
-                                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
-                                       true);
-
-       if (dc->clk_mgr->dc_mode_softmax_enabled)
-               if (dc->clk_mgr->clks.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
-                               context->bw_ctx.bw.dcn.clk.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
-                       dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
-
-       /* increase compbuf size */
-       if (hubbub->funcs->program_compbuf_size)
-               hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
-
-       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
-               dc_dmub_srv_p_state_delegate(dc,
-                       true, context);
-               context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
-               dc->clk_mgr->clks.fw_based_mclk_switching = true;
-       } else {
-               dc->clk_mgr->clks.fw_based_mclk_switching = false;
-       }
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       true);
-       if (context->bw_ctx.bw.dcn.clk.zstate_support == DCN_ZSTATE_SUPPORT_ALLOW) {
-               for (i = 0; i < dc->res_pool->pipe_count; ++i) {
-                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-                       if (pipe_ctx->stream && pipe_ctx->plane_res.hubp->funcs->program_extended_blank
-                               && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max
-                               && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)
-                                       pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp,
-                                               pipe_ctx->dlg_regs.min_dst_y_next_start);
-               }
-       }
-}
-
-bool dcn20_update_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* recalculate DML parameters */
-       if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false))
-               return false;
-
-       /* apply updated bandwidth parameters */
-       dc->hwss.prepare_bandwidth(dc, context);
-
-       /* update hubp configs for all pipes */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->plane_state == NULL)
-                       continue;
-
-               if (pipe_ctx->top_pipe == NULL) {
-                       bool blank = !is_pipe_tree_visible(pipe_ctx);
-
-                       pipe_ctx->stream_res.tg->funcs->program_global_sync(
-                                       pipe_ctx->stream_res.tg,
-                                       calculate_vready_offset_for_group(pipe_ctx),
-                                       pipe_ctx->pipe_dlg_param.vstartup_start,
-                                       pipe_ctx->pipe_dlg_param.vupdate_offset,
-                                       pipe_ctx->pipe_dlg_param.vupdate_width);
-
-                       pipe_ctx->stream_res.tg->funcs->set_vtg_params(
-                                       pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, false);
-
-                       if (pipe_ctx->prev_odm_pipe == NULL)
-                               hws->funcs.blank_pixel_data(dc, pipe_ctx, blank);
-
-                       if (hws->funcs.setup_vupdate_interrupt)
-                               hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
-               }
-
-               pipe_ctx->plane_res.hubp->funcs->hubp_setup(
-                               pipe_ctx->plane_res.hubp,
-                                       &pipe_ctx->dlg_regs,
-                                       &pipe_ctx->ttu_regs,
-                                       &pipe_ctx->rq_regs,
-                                       &pipe_ctx->pipe_dlg_param);
-       }
-
-       return true;
-}
-
-void dcn20_enable_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context)
-{
-       struct dwbc *dwb;
-       struct mcif_wb *mcif_wb;
-       struct timing_generator *optc;
-
-       ASSERT(wb_info->dwb_pipe_inst < MAX_DWB_PIPES);
-       ASSERT(wb_info->wb_enabled);
-       dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
-       mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst];
-
-       /* set the OPTC source mux */
-       optc = dc->res_pool->timing_generators[dwb->otg_inst];
-       optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst);
-       /* set MCIF_WB buffer and arbitration configuration */
-       mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height);
-       mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]);
-       /* Enable MCIF_WB */
-       mcif_wb->funcs->enable_mcif(mcif_wb);
-       /* Enable DWB */
-       dwb->funcs->enable(dwb, &wb_info->dwb_params);
-       /* TODO: add sequence to enable/disable warmup */
-}
-
-void dcn20_disable_writeback(
-               struct dc *dc,
-               unsigned int dwb_pipe_inst)
-{
-       struct dwbc *dwb;
-       struct mcif_wb *mcif_wb;
-
-       ASSERT(dwb_pipe_inst < MAX_DWB_PIPES);
-       dwb = dc->res_pool->dwbc[dwb_pipe_inst];
-       mcif_wb = dc->res_pool->mcif_wb[dwb_pipe_inst];
-
-       dwb->funcs->disable(dwb);
-       mcif_wb->funcs->disable_mcif(mcif_wb);
-}
-
-bool dcn20_wait_for_blank_complete(
-               struct output_pixel_processor *opp)
-{
-       int counter;
-
-       for (counter = 0; counter < 1000; counter++) {
-               if (opp->funcs->dpg_is_blanked(opp))
-                       break;
-
-               udelay(100);
-       }
-
-       if (counter == 1000) {
-               dm_error("DC: failed to blank crtc!\n");
-               return false;
-       }
-
-       return true;
-}
-
-bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx)
-{
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-
-       if (!hubp)
-               return false;
-       return hubp->funcs->dmdata_status_done(hubp);
-}
-
-void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-
-       if (pipe_ctx->stream_res.dsc) {
-               struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
-
-               hws->funcs.dsc_pg_control(hws, pipe_ctx->stream_res.dsc->inst, true);
-               while (odm_pipe) {
-                       hws->funcs.dsc_pg_control(hws, odm_pipe->stream_res.dsc->inst, true);
-                       odm_pipe = odm_pipe->next_odm_pipe;
-               }
-       }
-}
-
-void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-
-       if (pipe_ctx->stream_res.dsc) {
-               struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
-
-               hws->funcs.dsc_pg_control(hws, pipe_ctx->stream_res.dsc->inst, false);
-               while (odm_pipe) {
-                       hws->funcs.dsc_pg_control(hws, odm_pipe->stream_res.dsc->inst, false);
-                       odm_pipe = odm_pipe->next_odm_pipe;
-               }
-       }
-}
-
-void dcn20_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_dmdata_attributes attr = { 0 };
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-
-       attr.dmdata_mode = DMDATA_HW_MODE;
-       attr.dmdata_size =
-               dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;
-       attr.address.quad_part =
-                       pipe_ctx->stream->dmdata_address.quad_part;
-       attr.dmdata_dl_delta = 0;
-       attr.dmdata_qos_mode = 0;
-       attr.dmdata_qos_level = 0;
-       attr.dmdata_repeat = 1; /* always repeat */
-       attr.dmdata_updated = 1;
-       attr.dmdata_sw_data = NULL;
-
-       hubp->funcs->dmdata_set_attributes(hubp, &attr);
-}
-
-void dcn20_init_vm_ctx(
-               struct dce_hwseq *hws,
-               struct dc *dc,
-               struct dc_virtual_addr_space_config *va_config,
-               int vmid)
-{
-       struct dcn_hubbub_virt_addr_config config;
-
-       if (vmid == 0) {
-               ASSERT(0); /* VMID cannot be 0 for vm context */
-               return;
-       }
-
-       config.page_table_start_addr = va_config->page_table_start_addr;
-       config.page_table_end_addr = va_config->page_table_end_addr;
-       config.page_table_block_size = va_config->page_table_block_size_in_bytes;
-       config.page_table_depth = va_config->page_table_depth;
-       config.page_table_base_addr = va_config->page_table_base_addr;
-
-       dc->res_pool->hubbub->funcs->init_vm_ctx(dc->res_pool->hubbub, &config, vmid);
-}
-
-int dcn20_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
-{
-       struct dcn_hubbub_phys_addr_config config;
-
-       config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
-       config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
-       config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
-       config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
-       config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
-       config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
-       config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
-       config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
-       config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
-       config.page_table_default_page_addr = pa_config->page_table_default_page_addr;
-
-       return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
-}
-
-static bool patch_address_for_sbs_tb_stereo(
-               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
-{
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       bool sec_split = pipe_ctx->top_pipe &&
-                       pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
-       if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
-                       (pipe_ctx->stream->timing.timing_3d_format ==
-                       TIMING_3D_FORMAT_SIDE_BY_SIDE ||
-                       pipe_ctx->stream->timing.timing_3d_format ==
-                       TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
-               *addr = plane_state->address.grph_stereo.left_addr;
-               plane_state->address.grph_stereo.left_addr =
-                               plane_state->address.grph_stereo.right_addr;
-               return true;
-       }
-
-       if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
-                       plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
-               plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
-               plane_state->address.grph_stereo.right_addr =
-                               plane_state->address.grph_stereo.left_addr;
-               plane_state->address.grph_stereo.right_meta_addr =
-                               plane_state->address.grph_stereo.left_meta_addr;
-       }
-       return false;
-}
-
-void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       bool addr_patched = false;
-       PHYSICAL_ADDRESS_LOC addr;
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-
-       if (plane_state == NULL)
-               return;
-
-       addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
-
-       // Call Helper to track VMID use
-       vm_helper_mark_vmid_used(dc->vm_helper, plane_state->address.vmid, pipe_ctx->plane_res.hubp->inst);
-
-       pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
-                       pipe_ctx->plane_res.hubp,
-                       &plane_state->address,
-                       plane_state->flip_immediate);
-
-       plane_state->status.requested_address = plane_state->address;
-
-       if (plane_state->flip_immediate)
-               plane_state->status.current_address = plane_state->address;
-
-       if (addr_patched)
-               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
-}
-
-void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings)
-{
-       struct encoder_unblank_param params = {0};
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dce_hwseq *hws = link->dc->hwseq;
-       struct pipe_ctx *odm_pipe;
-
-       params.opp_cnt = 1;
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               params.opp_cnt++;
-       }
-       /* only 3 items below are used by unblank */
-       params.timing = pipe_ctx->stream->timing;
-
-       params.link_settings.link_rate = link_settings->link_rate;
-
-       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
-               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
-                               pipe_ctx->stream_res.hpo_dp_stream_enc,
-                               pipe_ctx->stream_res.tg->inst);
-       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1)
-                       params.timing.pix_clk_100hz /= 2;
-               pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine(
-                               pipe_ctx->stream_res.stream_enc, params.opp_cnt > 1);
-               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
-       }
-
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-               hws->funcs.edp_backlight_control(link, true);
-       }
-}
-
-void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       int start_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
-
-       if (start_line < 0)
-               start_line = 0;
-
-       if (tg->funcs->setup_vertical_interrupt2)
-               tg->funcs->setup_vertical_interrupt2(tg, start_line);
-}
-
-static void dcn20_reset_back_end_for_pipe(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context)
-{
-       int i;
-       struct dc_link *link = pipe_ctx->stream->link;
-       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
-
-       DC_LOGGER_INIT(dc->ctx->logger);
-       if (pipe_ctx->stream_res.stream_enc == NULL) {
-               pipe_ctx->stream = NULL;
-               return;
-       }
-
-       /* DPMS may already disable or */
-       /* dpms_off status is incorrect due to fastboot
-        * feature. When system resume from S4 with second
-        * screen only, the dpms_off would be true but
-        * VBIOS lit up eDP, so check link status too.
-        */
-       if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
-               dc->link_srv->set_dpms_off(pipe_ctx);
-       else if (pipe_ctx->stream_res.audio)
-               dc->hwss.disable_audio_stream(pipe_ctx);
-
-       /* free acquired resources */
-       if (pipe_ctx->stream_res.audio) {
-               /*disable az_endpoint*/
-               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
-
-               /*free audio*/
-               if (dc->caps.dynamic_audio == true) {
-                       /*we have to dynamic arbitrate the audio endpoints*/
-                       /*we free the resource, need reset is_audio_acquired*/
-                       update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
-                                       pipe_ctx->stream_res.audio, false);
-                       pipe_ctx->stream_res.audio = NULL;
-               }
-       }
-
-       /* by upper caller loop, parent pipe: pipe0, will be reset last.
-        * back end share by all pipes and will be disable only when disable
-        * parent pipe.
-        */
-       if (pipe_ctx->top_pipe == NULL) {
-
-               dc->hwss.set_abm_immediate_disable(pipe_ctx);
-
-               pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
-
-               pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
-               if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
-                       pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
-                                       pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
-
-               if (pipe_ctx->stream_res.tg->funcs->set_drr)
-                       pipe_ctx->stream_res.tg->funcs->set_drr(
-                                       pipe_ctx->stream_res.tg, NULL);
-               /* TODO - convert symclk_ref_cnts for otg to a bit map to solve
-                * the case where the same symclk is shared across multiple otg
-                * instances
-                */
-               link->phy_state.symclk_ref_cnts.otg = 0;
-               if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) {
-                       link_hwss->disable_link_output(link,
-                                       &pipe_ctx->link_res, pipe_ctx->stream->signal);
-                       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
-               }
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++)
-               if (&dc->current_state->res_ctx.pipe_ctx[i] == pipe_ctx)
-                       break;
-
-       if (i == dc->res_pool->pipe_count)
-               return;
-
-       pipe_ctx->stream = NULL;
-       DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
-                                       pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
-}
-
-void dcn20_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* Reset Back End*/
-       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
-               struct pipe_ctx *pipe_ctx_old =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (!pipe_ctx_old->stream)
-                       continue;
-
-               if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
-                       continue;
-
-               if (!pipe_ctx->stream ||
-                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
-                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
-
-                       dcn20_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
-                       if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
-                       if (old_clk)
-                               old_clk->funcs->cs_power_down(old_clk);
-               }
-       }
-}
-
-void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct mpcc_blnd_cfg blnd_cfg = {0};
-       bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha;
-       int mpcc_id;
-       struct mpcc *new_mpcc;
-       struct mpc *mpc = dc->res_pool->mpc;
-       struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
-
-       blnd_cfg.overlap_only = false;
-       blnd_cfg.global_gain = 0xff;
-
-       if (per_pixel_alpha) {
-               blnd_cfg.pre_multiplied_alpha = pipe_ctx->plane_state->pre_multiplied_alpha;
-               if (pipe_ctx->plane_state->global_alpha) {
-                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN;
-                       blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value;
-               } else {
-                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
-               }
-       } else {
-               blnd_cfg.pre_multiplied_alpha = false;
-               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
-       }
-
-       if (pipe_ctx->plane_state->global_alpha)
-               blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
-       else
-               blnd_cfg.global_alpha = 0xff;
-
-       blnd_cfg.background_color_bpc = 4;
-       blnd_cfg.bottom_gain_mode = 0;
-       blnd_cfg.top_gain = 0x1f000;
-       blnd_cfg.bottom_inside_gain = 0x1f000;
-       blnd_cfg.bottom_outside_gain = 0x1f000;
-
-       if (pipe_ctx->plane_state->format
-                       == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA)
-               blnd_cfg.pre_multiplied_alpha = false;
-
-       /*
-        * TODO: remove hack
-        * Note: currently there is a bug in init_hw such that
-        * on resume from hibernate, BIOS sets up MPCC0, and
-        * we do mpcc_remove but the mpcc cannot go to idle
-        * after remove. This cause us to pick mpcc1 here,
-        * which causes a pstate hang for yet unknown reason.
-        */
-       mpcc_id = hubp->inst;
-
-       /* If there is no full update, don't need to touch MPC tree*/
-       if (!pipe_ctx->plane_state->update_flags.bits.full_update &&
-               !pipe_ctx->update_flags.bits.mpcc) {
-               mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
-               dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
-               return;
-       }
-
-       /* check if this MPCC is already being used */
-       new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
-       /* remove MPCC if being used */
-       if (new_mpcc != NULL)
-               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, new_mpcc);
-       else
-               if (dc->debug.sanity_checks)
-                       mpc->funcs->assert_mpcc_idle_before_connect(
-                                       dc->res_pool->mpc, mpcc_id);
-
-       /* Call MPC to insert new plane */
-       new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
-                       mpc_tree_params,
-                       &blnd_cfg,
-                       NULL,
-                       NULL,
-                       hubp->inst,
-                       mpcc_id);
-       dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
-
-       ASSERT(new_mpcc != NULL);
-       hubp->opp_id = pipe_ctx->stream_res.opp->inst;
-       hubp->mpcc_id = mpcc_id;
-}
-
-void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
-{
-       enum dc_lane_count lane_count =
-               pipe_ctx->stream->link->cur_link_settings.lane_count;
-
-       struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
-       struct dc_link *link = pipe_ctx->stream->link;
-
-       uint32_t active_total_with_borders;
-       uint32_t early_control = 0;
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
-       struct dc *dc = pipe_ctx->stream->ctx->dc;
-       struct dtbclk_dto_params dto_params = {0};
-       struct dccg *dccg = dc->res_pool->dccg;
-       enum phyd32clk_clock_source phyd32clk;
-       int dp_hpo_inst;
-       struct dce_hwseq *hws = dc->hwseq;
-       unsigned int k1_div = PIXEL_RATE_DIV_NA;
-       unsigned int k2_div = PIXEL_RATE_DIV_NA;
-
-       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               if (dc->hwseq->funcs.setup_hpo_hw_control)
-                       dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
-       }
-
-       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
-               dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
-
-               phyd32clk = get_phyd32clk_src(link);
-               dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
-
-               dto_params.otg_inst = tg->inst;
-               dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
-               dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
-               dto_params.timing = &pipe_ctx->stream->timing;
-               dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
-               dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
-       }
-       if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
-               hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
-
-               dc->res_pool->dccg->funcs->set_pixel_rate_div(
-                       dc->res_pool->dccg,
-                       pipe_ctx->stream_res.tg->inst,
-                       k1_div, k2_div);
-       }
-
-       link_hwss->setup_stream_encoder(pipe_ctx);
-
-       if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
-               if (dc->hwss.program_dmdata_engine)
-                       dc->hwss.program_dmdata_engine(pipe_ctx);
-       }
-
-       dc->hwss.update_info_frame(pipe_ctx);
-
-       if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
-
-       /* enable early control to avoid corruption on DP monitor*/
-       active_total_with_borders =
-                       timing->h_addressable
-                               + timing->h_border_left
-                               + timing->h_border_right;
-
-       if (lane_count != 0)
-               early_control = active_total_with_borders % lane_count;
-
-       if (early_control == 0)
-               early_control = lane_count;
-
-       tg->funcs->set_early_control(tg, early_control);
-
-       if (dc->hwseq->funcs.set_pixels_per_cycle)
-               dc->hwseq->funcs.set_pixels_per_cycle(pipe_ctx);
-}
-
-void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_stream_state    *stream     = pipe_ctx->stream;
-       struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
-       bool                       enable     = false;
-       struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
-       enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
-                                                       ? dmdata_dp
-                                                       : dmdata_hdmi;
-
-       /* if using dynamic meta, don't set up generic infopackets */
-       if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-               pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-               enable = true;
-       }
-
-       if (!hubp)
-               return;
-
-       if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
-               return;
-
-       stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
-                                               hubp->inst, mode);
-}
-
-void dcn20_fpga_init_hw(struct dc *dc)
-{
-       int i, j;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct resource_pool *res_pool = dc->res_pool;
-       struct dc_state  *context = dc->current_state;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       // Initialize the dccg
-       if (res_pool->dccg->funcs->dccg_init)
-               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       //Enable ability to power gate / don't force power on permanently
-       hws->funcs.enable_power_gating_plane(hws, true);
-
-       // Specific to FPGA dccg and registers
-       REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
-       REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
-
-       hws->funcs.dccg_init(hws);
-
-       REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
-       REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
-       if (REG(REFCLK_CNTL))
-               REG_WRITE(REFCLK_CNTL, 0);
-       //
-
-
-       /* Blank pixel data with OPP DPG */
-       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       dcn20_init_blank(dc, tg);
-       }
-
-       for (i = 0; i < res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       tg->funcs->lock(tg);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct dpp *dpp = res_pool->dpps[i];
-
-               dpp->funcs->dpp_reset(dpp);
-       }
-
-       /* Reset all MPCC muxes */
-       res_pool->mpc->funcs->mpc_init(res_pool->mpc);
-
-       /* initialize OPP mpc_tree parameter */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
-               res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-               for (j = 0; j < MAX_PIPES; j++)
-                       res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = dc->res_pool->hubps[i];
-               struct dpp *dpp = dc->res_pool->dpps[i];
-
-               pipe_ctx->stream_res.tg = tg;
-               pipe_ctx->pipe_idx = i;
-
-               pipe_ctx->plane_res.hubp = hubp;
-               pipe_ctx->plane_res.dpp = dpp;
-               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
-               hubp->mpcc_id = dpp->inst;
-               hubp->opp_id = OPP_ID_INVALID;
-               hubp->power_gated = false;
-               pipe_ctx->stream_res.opp = NULL;
-
-               hubp->funcs->hubp_init(hubp);
-
-               //dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
-               //dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-               dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-               pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
-               /*to do*/
-               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
-       }
-
-       /* initialize DWB pointer to MCIF_WB */
-       for (i = 0; i < res_pool->res_cap->num_dwb; i++)
-               res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
-
-       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       tg->funcs->unlock(tg);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               dc->hwss.disable_plane(dc, pipe_ctx);
-
-               pipe_ctx->stream_res.tg = NULL;
-               pipe_ctx->plane_res.hubp = NULL;
-       }
-
-       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-               tg->funcs->tg_init(tg);
-       }
-
-       if (dc->res_pool->hubbub->funcs->init_crb)
-               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
-}
-
-void dcn20_set_disp_pattern_generator(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum controller_dp_test_pattern test_pattern,
-               enum controller_dp_color_space color_space,
-               enum dc_color_depth color_depth,
-               const struct tg_color *solid_color,
-               int width, int height, int offset)
-{
-       pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern,
-                       color_space, color_depth, solid_color, width, height, offset);
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h
deleted file mode 100644 (file)
index ab02e4e..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
-* 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 __DC_HWSS_DCN20_H__
-#define __DC_HWSS_DCN20_H__
-
-#include "hw_sequencer_private.h"
-
-bool dcn20_set_blend_lut(
-       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
-bool dcn20_set_shaper_3dlut(
-       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
-void dcn20_program_front_end_for_ctx(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn20_post_unlock_program_front_end(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
-bool dcn20_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_state *plane_state);
-bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                       const struct dc_stream_state *stream);
-void dcn20_program_output_csc(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum dc_color_space colorspace,
-               uint16_t *matrix,
-               int opp_id);
-void dcn20_enable_stream(struct pipe_ctx *pipe_ctx);
-void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings);
-void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_disable_pixel_data(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool blank);
-void dcn20_blank_pixel_data(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool blank);
-void dcn20_pipe_control_lock(
-       struct dc *dc,
-       struct pipe_ctx *pipe,
-       bool lock);
-void dcn20_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn20_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-bool dcn20_update_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-void dcn20_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context);
-enum dc_status dcn20_enable_stream_timing(
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context,
-               struct dc *dc);
-void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_init_blank(
-               struct dc *dc,
-               struct timing_generator *tg);
-void dcn20_disable_vga(
-       struct dce_hwseq *hws);
-void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable);
-void dcn20_dpp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dpp_inst,
-               bool power_on);
-void dcn20_hubp_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int hubp_inst,
-               bool power_on);
-void dcn20_program_triple_buffer(
-       const struct dc *dc,
-       struct pipe_ctx *pipe_ctx,
-       bool enable_triple_buffer);
-void dcn20_enable_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context);
-void dcn20_disable_writeback(
-               struct dc *dc,
-               unsigned int dwb_pipe_inst);
-void dcn20_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
-bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx);
-void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx);
-void dcn20_set_dmdata_attributes(struct pipe_ctx *pipe_ctx);
-void dcn20_init_vm_ctx(
-               struct dce_hwseq *hws,
-               struct dc *dc,
-               struct dc_virtual_addr_space_config *va_config,
-               int vmid);
-void dcn20_set_flip_control_gsl(
-               struct pipe_ctx *pipe_ctx,
-               bool flip_immediate);
-void dcn20_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on);
-void dcn20_fpga_init_hw(struct dc *dc);
-bool dcn20_wait_for_blank_complete(
-               struct output_pixel_processor *opp);
-void dcn20_dccg_init(struct dce_hwseq *hws);
-int dcn20_init_sys_ctx(struct dce_hwseq *hws,
-               struct dc *dc,
-               struct dc_phy_addr_space_config *pa_config);
-
-void dcn20_set_disp_pattern_generator(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum controller_dp_test_pattern test_pattern,
-               enum controller_dp_color_space color_space,
-               enum dc_color_depth color_depth,
-               const struct tg_color *solid_color,
-               int width, int height, int offset);
-
-void dcn20_setup_gsl_group_as_lock(
-               const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool enable);
-
-#endif /* __DC_HWSS_DCN20_H__ */
-
index 15b66ed..884e3e3 100644 (file)
@@ -23,9 +23,9 @@
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
-#include "dcn20_hwseq.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
+#include "dcn20/dcn20_hwseq.h"
 
 #include "dcn20_init.h"
 
index 768fef7..7eda4bb 100644 (file)
@@ -45,8 +45,8 @@
 #include "irq/dcn20/irq_service_dcn20.h"
 #include "dcn20_dpp.h"
 #include "dcn20_optc.h"
-#include "dcn20_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dcn20/dcn20_hwseq.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn10/dcn10_resource.h"
 #include "dcn20_opp.h"
 
index 5c9ce2c..3a41a97 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: MIT
 #
 # Makefile for DCN.
-DCN201 = dcn201_init.o dcn201_resource.o dcn201_hwseq.o \
+DCN201 = dcn201_init.o dcn201_resource.o \
        dcn201_hubbub.o\
        dcn201_mpc.o dcn201_hubp.o dcn201_opp.o dcn201_optc.o dcn201_dpp.o \
        dcn201_dccg.o dcn201_link_encoder.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c
deleted file mode 100644 (file)
index 9e027db..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * 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 "dm_services.h"
-#include "basics/dc_common.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dcn201_hwseq.h"
-#include "dcn201_optc.h"
-#include "dce/dce_hwseq.h"
-#include "hubp.h"
-#include "dchubbub.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "dccg.h"
-#include "clk_mgr.h"
-#include "reg_helper.h"
-
-#define CTX \
-       hws->ctx
-
-#define REG(reg)\
-       hws->regs->reg
-
-#define DC_LOGGER \
-       dc->ctx->logger
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-
-static bool patch_address_for_sbs_tb_stereo(
-               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
-{
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       bool sec_split = pipe_ctx->top_pipe &&
-               pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
-
-       if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
-               (pipe_ctx->stream->timing.timing_3d_format ==
-                       TIMING_3D_FORMAT_SIDE_BY_SIDE ||
-               pipe_ctx->stream->timing.timing_3d_format ==
-                       TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
-               *addr = plane_state->address.grph_stereo.left_addr;
-               plane_state->address.grph_stereo.left_addr =
-                       plane_state->address.grph_stereo.right_addr;
-               return true;
-       } else {
-               if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
-                       plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
-                       plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
-                       plane_state->address.grph_stereo.right_addr =
-                       plane_state->address.grph_stereo.left_addr;
-                       plane_state->address.grph_stereo.right_meta_addr =
-                       plane_state->address.grph_stereo.left_meta_addr;
-               }
-       }
-       return false;
-}
-
-static bool gpu_addr_to_uma(struct dce_hwseq *hwseq,
-               PHYSICAL_ADDRESS_LOC *addr)
-{
-       bool is_in_uma;
-
-       if (hwseq->fb_base.quad_part <= addr->quad_part &&
-                       addr->quad_part < hwseq->fb_top.quad_part) {
-               addr->quad_part -= hwseq->fb_base.quad_part;
-               addr->quad_part += hwseq->fb_offset.quad_part;
-               is_in_uma = true;
-       } else if (hwseq->fb_offset.quad_part <= addr->quad_part &&
-                       addr->quad_part <= hwseq->uma_top.quad_part) {
-               is_in_uma = true;
-       } else {
-               is_in_uma = false;
-       }
-       return is_in_uma;
-}
-
-static void plane_address_in_gpu_space_to_uma(struct dce_hwseq *hwseq,
-               struct dc_plane_address *addr)
-{
-       switch (addr->type) {
-       case PLN_ADDR_TYPE_GRAPHICS:
-               gpu_addr_to_uma(hwseq, &addr->grph.addr);
-               gpu_addr_to_uma(hwseq, &addr->grph.meta_addr);
-               break;
-       case PLN_ADDR_TYPE_GRPH_STEREO:
-               gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_addr);
-               gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_meta_addr);
-               gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_addr);
-               gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_meta_addr);
-               break;
-       case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
-               gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_addr);
-               gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_meta_addr);
-               gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_addr);
-               gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_meta_addr);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       bool addr_patched = false;
-       PHYSICAL_ADDRESS_LOC addr;
-       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_plane_address uma;
-
-       if (plane_state == NULL)
-               return;
-
-       uma = plane_state->address;
-       addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
-
-       plane_address_in_gpu_space_to_uma(hws, &uma);
-
-       pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
-                       pipe_ctx->plane_res.hubp,
-                       &uma,
-                       plane_state->flip_immediate);
-
-       plane_state->status.requested_address = plane_state->address;
-
-       if (plane_state->flip_immediate)
-               plane_state->status.current_address = plane_state->address;
-
-       if (addr_patched)
-               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
-}
-
-/* Blank pixel data during initialization */
-void dcn201_init_blank(
-               struct dc *dc,
-               struct timing_generator *tg)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-       struct output_pixel_processor *opp = NULL;
-       uint32_t num_opps, opp_id_src0, opp_id_src1;
-       uint32_t otg_active_width, otg_active_height;
-
-       /* program opp dpg blank color */
-       color_space = COLOR_SPACE_SRGB;
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       /* get the OTG active size */
-       tg->funcs->get_otg_active_size(tg,
-                       &otg_active_width,
-                       &otg_active_height);
-
-       /* get the OPTC source */
-       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-       ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
-       opp = dc->res_pool->opps[opp_id_src0];
-
-       opp->funcs->opp_set_disp_pattern_generator(
-                       opp,
-                       CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-                       CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-                       COLOR_DEPTH_UNDEFINED,
-                       &black_color,
-                       otg_active_width,
-                       otg_active_height,
-                       0);
-
-       hws->funcs.wait_for_blank_complete(opp);
-}
-
-static void read_mmhub_vm_setup(struct dce_hwseq *hws)
-{
-       uint32_t fb_base = REG_READ(MC_VM_FB_LOCATION_BASE);
-       uint32_t fb_top = REG_READ(MC_VM_FB_LOCATION_TOP);
-       uint32_t fb_offset = REG_READ(MC_VM_FB_OFFSET);
-
-       /* MC_VM_FB_LOCATION_TOP is in pages, actual top should add 1 */
-       fb_top++;
-
-       /* bit 23:0 in register map to bit 47:24 in address */
-       hws->fb_base.low_part = fb_base;
-       hws->fb_base.quad_part <<= 24;
-
-       hws->fb_top.low_part  = fb_top;
-       hws->fb_top.quad_part <<= 24;
-       hws->fb_offset.low_part = fb_offset;
-       hws->fb_offset.quad_part <<= 24;
-
-       hws->uma_top.quad_part = hws->fb_top.quad_part
-                       - hws->fb_base.quad_part + hws->fb_offset.quad_part;
-}
-
-void dcn201_init_hw(struct dc *dc)
-{
-       int i, j;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct resource_pool *res_pool = dc->res_pool;
-       struct dc_state  *context = dc->current_state;
-
-       if (res_pool->dccg->funcs->dccg_init)
-               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       hws->funcs.bios_golden_init(dc);
-
-       if (dc->ctx->dc_bios->fw_info_valid) {
-               res_pool->ref_clocks.xtalin_clock_inKhz =
-                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-               if (res_pool->dccg && res_pool->hubbub) {
-                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-               } else {
-                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-               }
-       } else
-               ASSERT_CRITICAL(false);
-       for (i = 0; i < dc->link_count; i++) {
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector).
-                */
-               struct dc_link *link = dc->links[i];
-
-               link->link_enc->funcs->hw_init(link->link_enc);
-       }
-       if (hws->fb_offset.quad_part == 0)
-               read_mmhub_vm_setup(hws);
-
-       /* Blank pixel data with OPP DPG */
-       for (i = 0; i < res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = res_pool->timing_generators[i];
-
-               if (tg->funcs->is_tg_enabled(tg)) {
-                       dcn201_init_blank(dc, tg);
-               }
-       }
-
-       for (i = 0; i < res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = res_pool->timing_generators[i];
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       tg->funcs->lock(tg);
-       }
-
-       for (i = 0; i < res_pool->pipe_count; i++) {
-               struct dpp *dpp = res_pool->dpps[i];
-
-               dpp->funcs->dpp_reset(dpp);
-       }
-
-       /* Reset all MPCC muxes */
-       res_pool->mpc->funcs->mpc_init(res_pool->mpc);
-
-       /* initialize OPP mpc_tree parameter */
-       for (i = 0; i < res_pool->res_cap->num_opp; i++) {
-               res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
-               res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-               for (j = 0; j < MAX_PIPES; j++)
-                       res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
-       }
-
-       for (i = 0; i < res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = res_pool->timing_generators[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = res_pool->hubps[i];
-               struct dpp *dpp = res_pool->dpps[i];
-
-               pipe_ctx->stream_res.tg = tg;
-               pipe_ctx->pipe_idx = i;
-
-               pipe_ctx->plane_res.hubp = hubp;
-               pipe_ctx->plane_res.dpp = dpp;
-               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
-               hubp->mpcc_id = dpp->inst;
-               hubp->opp_id = OPP_ID_INVALID;
-               hubp->power_gated = false;
-               pipe_ctx->stream_res.opp = NULL;
-
-               hubp->funcs->hubp_init(hubp);
-
-               res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-               pipe_ctx->stream_res.opp = res_pool->opps[i];
-               /*To do: number of MPCC != number of opp*/
-               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
-       }
-
-       /* initialize DWB pointer to MCIF_WB */
-       for (i = 0; i < res_pool->res_cap->num_dwb; i++)
-               res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
-
-       for (i = 0; i < res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = res_pool->timing_generators[i];
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       tg->funcs->unlock(tg);
-       }
-
-       for (i = 0; i < res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               dc->hwss.disable_plane(dc, pipe_ctx);
-
-               pipe_ctx->stream_res.tg = NULL;
-               pipe_ctx->plane_res.hubp = NULL;
-       }
-
-       for (i = 0; i < res_pool->timing_generator_count; i++) {
-               struct timing_generator *tg = res_pool->timing_generators[i];
-
-               tg->funcs->tg_init(tg);
-       }
-
-       for (i = 0; i < res_pool->audio_count; i++) {
-               struct audio *audio = res_pool->audios[i];
-
-               audio->funcs->hw_init(audio);
-       }
-
-       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-       if (!dc->debug.disable_clock_gate) {
-               /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
-               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-       }
-}
-
-/* trigger HW to start disconnect plane from stream on the next vsync */
-void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       int dpp_id = pipe_ctx->plane_res.dpp->inst;
-       struct mpc *mpc = dc->res_pool->mpc;
-       struct mpc_tree *mpc_tree_params;
-       struct mpcc *mpcc_to_remove = NULL;
-       struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
-       bool mpcc_removed = false;
-
-       mpc_tree_params = &(opp->mpc_tree_params);
-
-       /* check if this plane is being used by an MPCC in the secondary blending chain */
-       if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
-               mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
-
-       /* remove MPCC from secondary if being used */
-       if (mpcc_to_remove != NULL && mpc->funcs->remove_mpcc_from_secondary) {
-               mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove);
-               mpcc_removed = true;
-       }
-
-       /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
-       mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
-       if (mpcc_to_remove != NULL) {
-               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
-               mpcc_removed = true;
-       }
-
-       /*Already reset*/
-       if (mpcc_removed == false)
-               return;
-
-       if (opp != NULL)
-               opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-
-       dc->optimized_required = true;
-
-       if (hubp->funcs->hubp_disconnect)
-               hubp->funcs->hubp_disconnect(hubp);
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-}
-
-void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct mpcc_blnd_cfg blnd_cfg;
-       bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
-       int mpcc_id, dpp_id;
-       struct mpcc *new_mpcc;
-       struct mpcc *remove_mpcc = NULL;
-       struct mpc *mpc = dc->res_pool->mpc;
-       struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
-
-       if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
-               get_hdr_visual_confirm_color(
-                               pipe_ctx, &blnd_cfg.black_color);
-       } else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
-               get_surface_visual_confirm_color(
-                               pipe_ctx, &blnd_cfg.black_color);
-       } else {
-               color_space_to_black_color(
-                               dc, pipe_ctx->stream->output_color_space,
-                               &blnd_cfg.black_color);
-       }
-
-       if (per_pixel_alpha)
-               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
-       else
-               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
-
-       blnd_cfg.overlap_only = false;
-
-       if (pipe_ctx->plane_state->global_alpha_value)
-               blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
-       else
-               blnd_cfg.global_alpha = 0xff;
-
-       blnd_cfg.global_gain = 0xff;
-       blnd_cfg.background_color_bpc = 4;
-       blnd_cfg.bottom_gain_mode = 0;
-       blnd_cfg.top_gain = 0x1f000;
-       blnd_cfg.bottom_inside_gain = 0x1f000;
-       blnd_cfg.bottom_outside_gain = 0x1f000;
-       /*the input to MPCC is RGB*/
-       blnd_cfg.black_color.color_b_cb = 0;
-       blnd_cfg.black_color.color_g_y = 0;
-       blnd_cfg.black_color.color_r_cr = 0;
-
-       /* DCN1.0 has output CM before MPC which seems to screw with
-        * pre-multiplied alpha. This is a w/a hopefully unnecessary for DCN2.
-        */
-       blnd_cfg.pre_multiplied_alpha = per_pixel_alpha;
-
-       /*
-        * TODO: remove hack
-        * Note: currently there is a bug in init_hw such that
-        * on resume from hibernate, BIOS sets up MPCC0, and
-        * we do mpcc_remove but the mpcc cannot go to idle
-        * after remove. This cause us to pick mpcc1 here,
-        * which causes a pstate hang for yet unknown reason.
-        */
-       dpp_id = hubp->inst;
-       mpcc_id = dpp_id;
-
-       /* If there is no full update, don't need to touch MPC tree*/
-       if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
-               dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
-               mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
-               return;
-       }
-
-       /* check if this plane is being used by an MPCC in the secondary blending chain */
-       if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
-               remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
-
-       /* remove MPCC from secondary if being used */
-       if (remove_mpcc != NULL && mpc->funcs->remove_mpcc_from_secondary)
-               mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc);
-
-       /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
-       remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
-       /* remove MPCC if being used */
-
-       if (remove_mpcc != NULL)
-               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc);
-       else
-               if (dc->debug.sanity_checks)
-                       mpc->funcs->assert_mpcc_idle_before_connect(
-                                       dc->res_pool->mpc, mpcc_id);
-
-       /* Call MPC to insert new plane */
-       dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
-       new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
-                       mpc_tree_params,
-                       &blnd_cfg,
-                       NULL,
-                       NULL,
-                       dpp_id,
-                       mpcc_id);
-
-       ASSERT(new_mpcc != NULL);
-       hubp->opp_id = pipe_ctx->stream_res.opp->inst;
-       hubp->mpcc_id = mpcc_id;
-}
-
-void dcn201_pipe_control_lock(
-       struct dc *dc,
-       struct pipe_ctx *pipe,
-       bool lock)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       /* use TG master update lock to lock everything on the TG
-        * therefore only top pipe need to lock
-        */
-       if (pipe->top_pipe)
-               return;
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-
-       if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
-               if (lock)
-                       pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
-               else
-                       pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
-       } else {
-               if (lock)
-                       pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
-               else
-                       pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
-       }
-
-       if (dc->debug.sanity_checks)
-               hws->funcs.verify_allow_pstate_change_high(dc);
-}
-
-void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
-
-       gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, &attributes->address);
-
-       pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
-                       pipe_ctx->plane_res.hubp, attributes);
-       pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
-               pipe_ctx->plane_res.dpp, attributes);
-}
-
-void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_dmdata_attributes attr = { 0 };
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-
-       gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq,
-                       &pipe_ctx->stream->dmdata_address);
-
-       attr.dmdata_mode = DMDATA_HW_MODE;
-       attr.dmdata_size =
-               dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;
-       attr.address.quad_part =
-                       pipe_ctx->stream->dmdata_address.quad_part;
-       attr.dmdata_dl_delta = 0;
-       attr.dmdata_qos_mode = 0;
-       attr.dmdata_qos_level = 0;
-       attr.dmdata_repeat = 1; /* always repeat */
-       attr.dmdata_updated = 1;
-       attr.dmdata_sw_data = NULL;
-
-       hubp->funcs->dmdata_set_attributes(hubp, &attr);
-}
-
-void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings)
-{
-       struct encoder_unblank_param params = { { 0 } };
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dce_hwseq *hws = link->dc->hwseq;
-
-       /* only 3 items below are used by unblank */
-       params.timing = pipe_ctx->stream->timing;
-
-       params.link_settings.link_rate = link_settings->link_rate;
-
-       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               /*check whether it is half the rate*/
-               if (optc201_is_two_pixels_per_containter(&stream->timing))
-                       params.timing.pix_clk_100hz /= 2;
-
-               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
-       }
-
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-               hws->funcs.edp_backlight_control(link, true);
-       }
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.h
deleted file mode 100644 (file)
index 26cd62b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2021 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_HWSS_DCN201_H__
-#define __DC_HWSS_DCN201_H__
-
-#include "hw_sequencer_private.h"
-
-void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx);
-void dcn201_init_hw(struct dc *dc);
-void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings);
-void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
-void dcn201_pipe_control_lock(
-       struct dc *dc,
-       struct pipe_ctx *pipe,
-       bool lock);
-void dcn201_init_blank(
-               struct dc *dc,
-               struct timing_generator *tg);
-#endif /* __DC_HWSS_DCN201_H__ */
index 92dd4cd..a13bf6c 100644 (file)
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
-#include "dcn201_hwseq.h"
+#include "dcn201/dcn201_hwseq.h"
 #include "dcn201_init.h"
 
 static const struct hw_sequencer_funcs dcn201_funcs = {
index 9389bd8..a11b2f6 100644 (file)
@@ -43,8 +43,8 @@
 #include "dcn201/dcn201_hubbub.h"
 #include "dcn201_dccg.h"
 #include "dcn201_optc.h"
-#include "dcn201_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dcn201/dcn201_hwseq.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn201_opp.h"
 #include "dcn201/dcn201_link_encoder.h"
 #include "dcn20/dcn20_stream_encoder.h"
index 0dc06e4..ce1be0a 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for DCN21.
 
 DCN21 = dcn21_init.o dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o \
-        dcn21_hwseq.o dcn21_link_encoder.o dcn21_dccg.o
+        dcn21_link_encoder.o dcn21_dccg.o
 
 AMD_DAL_DCN21 = $(addprefix $(AMDDALPATH)/dc/dcn21/,$(DCN21))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
deleted file mode 100644 (file)
index 43463d0..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * 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 "dm_services.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dce/dce_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn21_hwseq.h"
-#include "vmid.h"
-#include "reg_helper.h"
-#include "hw/clk_mgr.h"
-#include "dc_dmub_srv.h"
-#include "abm.h"
-#include "link.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#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
-
-/* Temporary read settings, future will get values from kmd directly */
-static void mmhub_update_page_table_config(struct dcn_hubbub_phys_addr_config *config,
-               struct dce_hwseq *hws)
-{
-       uint32_t page_table_base_hi;
-       uint32_t page_table_base_lo;
-
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
-                       PAGE_DIRECTORY_ENTRY_HI32, &page_table_base_hi);
-       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
-                       PAGE_DIRECTORY_ENTRY_LO32, &page_table_base_lo);
-
-       config->gart_config.page_table_base_addr = ((uint64_t)page_table_base_hi << 32) | page_table_base_lo;
-
-}
-
-int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
-{
-       struct dcn_hubbub_phys_addr_config config;
-
-       config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
-       config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
-       config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
-       config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
-       config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
-       config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
-       config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
-       config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
-       config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
-
-       mmhub_update_page_table_config(&config, hws);
-
-       return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
-}
-
-// work around for Renoir s0i3, if register is programmed, bypass golden init.
-
-bool dcn21_s0i3_golden_init_wa(struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       uint32_t value = 0;
-
-       value = REG_READ(MICROSECOND_TIME_BASE_DIV);
-
-       return value != 0x00120464;
-}
-
-void dcn21_exit_optimized_pwr_state(
-               const struct dc *dc,
-               struct dc_state *context)
-{
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       false);
-}
-
-void dcn21_optimize_pwr_state(
-               const struct dc *dc,
-               struct dc_state *context)
-{
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       context,
-                       true);
-}
-
-/* If user hotplug a HDMI monitor while in monitor off,
- * OS will do a mode set (with output timing) but keep output off.
- * In this case DAL will ask vbios to power up the pll in the PHY.
- * If user unplug the monitor (while we are on monitor off) or
- * system attempt to enter modern standby (which we will disable PLL),
- * PHY will hang on the next mode set attempt.
- * if enable PLL follow by disable PLL (without executing lane enable/disable),
- * RDPCS_PHY_DP_MPLLB_STATE remains 1,
- * which indicate that PLL disable attempt actually didn't go through.
- * As a workaround, insert PHY lane enable/disable before PLL disable.
- */
-void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx)
-{
-       if (!pipe_ctx->stream->dpms_off)
-               return;
-
-       pipe_ctx->stream->dpms_off = false;
-       pipe_ctx->stream->ctx->dc->link_srv->set_dpms_on(context, pipe_ctx);
-       pipe_ctx->stream->ctx->dc->link_srv->set_dpms_off(pipe_ctx);
-       pipe_ctx->stream->dpms_off = true;
-}
-
-static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst)
-{
-       union dmub_rb_cmd cmd;
-       struct dc_context *dc = abm->ctx;
-       uint32_t ramping_boundary = 0xFFFF;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
-       cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE;
-       cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst;
-       cmd.abm_set_pipe.abm_set_pipe_data.set_pipe_option = option;
-       cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst;
-       cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
-       cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
-
-       dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-
-       return true;
-}
-
-static void dmub_abm_set_backlight(struct dc_context *dc, uint32_t backlight_pwm_u16_16,
-                                                                       uint32_t frame_ramp, uint32_t panel_inst)
-{
-       union dmub_rb_cmd cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.abm_set_backlight.header.type = DMUB_CMD__ABM;
-       cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT;
-       cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp;
-       cmd.abm_set_backlight.abm_set_backlight_data.backlight_user_level = backlight_pwm_u16_16;
-       cmd.abm_set_backlight.abm_set_backlight_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
-       cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst);
-       cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
-
-       dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-}
-
-void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
-{
-       struct abm *abm = pipe_ctx->stream_res.abm;
-       uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
-       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
-
-       struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
-
-       if (dmcu) {
-               dce110_set_abm_immediate_disable(pipe_ctx);
-               return;
-       }
-
-       if (abm && panel_cntl) {
-               if (abm->funcs && abm->funcs->set_pipe_ex) {
-                       abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE,
-                       panel_cntl->inst);
-               } else {
-                       dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE, panel_cntl->inst);
-               }
-               panel_cntl->funcs->store_backlight_level(panel_cntl);
-       }
-}
-
-void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
-{
-       struct abm *abm = pipe_ctx->stream_res.abm;
-       uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
-       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
-       struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
-
-       if (dmcu) {
-               dce110_set_pipe(pipe_ctx);
-               return;
-       }
-
-       if (abm && panel_cntl) {
-               if (abm->funcs && abm->funcs->set_pipe_ex) {
-                       abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
-               } else {
-                       dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
-               }
-       }
-}
-
-bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
-               uint32_t backlight_pwm_u16_16,
-               uint32_t frame_ramp)
-{
-       struct dc_context *dc = pipe_ctx->stream->ctx;
-       struct abm *abm = pipe_ctx->stream_res.abm;
-       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
-
-       if (dc->dc->res_pool->dmcu) {
-               dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp);
-               return true;
-       }
-
-       if (abm != NULL) {
-               uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
-
-               if (abm && panel_cntl) {
-                       if (abm->funcs && abm->funcs->set_pipe_ex) {
-                               abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
-                       } else {
-                               dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
-                       }
-               }
-       }
-
-       if (abm && abm->funcs && abm->funcs->set_backlight_level_pwm)
-               abm->funcs->set_backlight_level_pwm(abm, backlight_pwm_u16_16,
-                       frame_ramp, 0, panel_cntl->inst);
-       else
-               dmub_abm_set_backlight(dc, backlight_pwm_u16_16, frame_ramp, panel_cntl->inst);
-
-       return true;
-}
-
-bool dcn21_is_abm_supported(struct dc *dc,
-               struct dc_state *context, struct dc_stream_state *stream)
-{
-       int i;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->stream == stream &&
-                               (pipe_ctx->prev_odm_pipe == NULL && pipe_ctx->next_odm_pipe == NULL))
-                       return true;
-       }
-       return false;
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h
deleted file mode 100644 (file)
index 9cee9bd..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* 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 __DC_HWSS_DCN21_H__
-#define __DC_HWSS_DCN21_H__
-
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-int dcn21_init_sys_ctx(struct dce_hwseq *hws,
-               struct dc *dc,
-               struct dc_phy_addr_space_config *pa_config);
-
-bool dcn21_s0i3_golden_init_wa(struct dc *dc);
-
-void dcn21_exit_optimized_pwr_state(
-               const struct dc *dc,
-               struct dc_state *context);
-
-void dcn21_optimize_pwr_state(
-               const struct dc *dc,
-               struct dc_state *context);
-
-void dcn21_PLAT_58856_wa(struct dc_state *context,
-               struct pipe_ctx *pipe_ctx);
-
-void dcn21_set_pipe(struct pipe_ctx *pipe_ctx);
-void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
-bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
-               uint32_t backlight_pwm_u16_16,
-               uint32_t frame_ramp);
-bool dcn21_is_abm_supported(struct dc *dc,
-               struct dc_state *context, struct dc_stream_state *stream);
-
-#endif /* __DC_HWSS_DCN21_H__ */
index 647e666..18249c6 100644 (file)
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
-#include "dcn21_hwseq.h"
+#include "dcn21/dcn21_hwseq.h"
 
 #include "dcn21_init.h"
 
index d8d77dd..58a0d37 100644 (file)
@@ -49,7 +49,7 @@
 #include "dcn20/dcn20_dpp.h"
 #include "dcn20/dcn20_optc.h"
 #include "dcn21/dcn21_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn20/dcn20_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn21/dcn21_link_encoder.h"
index 4a3e9e4..af4d206 100644 (file)
@@ -30,7 +30,6 @@ DCN30 := \
        dcn30_dpp.o \
        dcn30_optc.o \
        dcn30_dccg.o \
-       dcn30_hwseq.o \
        dcn30_mpc.o dcn30_vpg.o \
        dcn30_afmt.o \
        dcn30_dio_stream_encoder.o \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
deleted file mode 100644 (file)
index af9a9fc..0000000
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- * Copyright 2020 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 "dm_services.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dcn30_hwseq.h"
-#include "dccg.h"
-#include "dce/dce_hwseq.h"
-#include "dcn30_mpc.h"
-#include "dcn30_dpp.h"
-#include "dcn10/dcn10_cm_common.h"
-#include "dcn30_cm_common.h"
-#include "reg_helper.h"
-#include "abm.h"
-#include "clk_mgr.h"
-#include "hubp.h"
-#include "dchubbub.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "mcif_wb.h"
-#include "dc_dmub_srv.h"
-#include "link_hwss.h"
-#include "dpcd_defs.h"
-#include "../dcn20/dcn20_hwseq.h"
-#include "dcn30_resource.h"
-#include "link.h"
-
-
-
-
-#define DC_LOGGER_INIT(logger)
-
-#define CTX \
-       hws->ctx
-#define REG(reg)\
-       hws->regs->reg
-#define DC_LOGGER \
-               dc->ctx->logger
-
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-
-bool dcn30_set_blend_lut(
-       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       bool result = true;
-       struct pwl_params *blend_lut = NULL;
-
-       if (plane_state->blend_tf) {
-               if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
-                       blend_lut = &plane_state->blend_tf->pwl;
-               else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm3_helper_translate_curve_to_hw_format(
-                                       plane_state->blend_tf, &dpp_base->regamma_params, false);
-                       blend_lut = &dpp_base->regamma_params;
-               }
-       }
-       result = dpp_base->funcs->dpp_program_blnd_lut(dpp_base, blend_lut);
-
-       return result;
-}
-
-static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
-                                      const struct dc_stream_state *stream)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-       bool result = false;
-       int acquired_rmu = 0;
-       int mpcc_id_projected = 0;
-
-       const struct pwl_params *shaper_lut = NULL;
-       //get the shaper lut params
-       if (stream->func_shaper) {
-               if (stream->func_shaper->type == TF_TYPE_HWPWL) {
-                       shaper_lut = &stream->func_shaper->pwl;
-               } else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm_helper_translate_curve_to_hw_format(stream->ctx, stream->func_shaper,
-                                                              &dpp_base->shaper_params, true);
-                       shaper_lut = &dpp_base->shaper_params;
-               }
-       }
-
-       if (stream->lut3d_func &&
-           stream->lut3d_func->state.bits.initialized == 1 &&
-           stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
-               if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
-                       mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux;
-               else if (stream->lut3d_func->state.bits.rmu_mux_num == 1)
-                       mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu1_mux;
-               else if (stream->lut3d_func->state.bits.rmu_mux_num == 2)
-                       mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu2_mux;
-               if (mpcc_id_projected != mpcc_id)
-                       BREAK_TO_DEBUGGER();
-               /* find the reason why logical layer assigned a different
-                * mpcc_id into acquire_post_bldn_3dlut
-                */
-               acquired_rmu = mpc->funcs->acquire_rmu(mpc, mpcc_id,
-                                                      stream->lut3d_func->state.bits.rmu_mux_num);
-               if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
-                       BREAK_TO_DEBUGGER();
-
-               result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
-                                                  stream->lut3d_func->state.bits.rmu_mux_num);
-               result = mpc->funcs->program_shaper(mpc, shaper_lut,
-                                                   stream->lut3d_func->state.bits.rmu_mux_num);
-       } else {
-               // loop through the available mux and release the requested mpcc_id
-               mpc->funcs->release_rmu(mpc, mpcc_id);
-       }
-
-       return result;
-}
-
-bool dcn30_set_input_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       enum dc_transfer_func_predefined tf;
-       bool result = true;
-       struct pwl_params *params = NULL;
-
-       if (dpp_base == NULL || plane_state == NULL)
-               return false;
-
-       tf = TRANSFER_FUNCTION_UNITY;
-
-       if (plane_state->in_transfer_func &&
-               plane_state->in_transfer_func->type == TF_TYPE_PREDEFINED)
-               tf = plane_state->in_transfer_func->tf;
-
-       dpp_base->funcs->dpp_set_pre_degam(dpp_base, tf);
-
-       if (plane_state->in_transfer_func) {
-               if (plane_state->in_transfer_func->type == TF_TYPE_HWPWL)
-                       params = &plane_state->in_transfer_func->pwl;
-               else if (plane_state->in_transfer_func->type == TF_TYPE_DISTRIBUTED_POINTS &&
-                       cm3_helper_translate_curve_to_hw_format(plane_state->in_transfer_func,
-                                       &dpp_base->degamma_params, false))
-                       params = &dpp_base->degamma_params;
-       }
-
-       result = dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
-
-       if (pipe_ctx->stream_res.opp && pipe_ctx->stream_res.opp->ctx) {
-               if (dpp_base->funcs->dpp_program_blnd_lut)
-                       hws->funcs.set_blend_lut(pipe_ctx, plane_state);
-               if (dpp_base->funcs->dpp_program_shaper_lut &&
-                               dpp_base->funcs->dpp_program_3dlut)
-                       hws->funcs.set_shaper_3dlut(pipe_ctx, plane_state);
-       }
-
-       return result;
-}
-
-void dcn30_program_gamut_remap(struct pipe_ctx *pipe_ctx)
-{
-       int i = 0;
-       struct dpp_grph_csc_adjustment dpp_adjust;
-       struct mpc_grph_gamut_adjustment mpc_adjust;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-
-       memset(&dpp_adjust, 0, sizeof(dpp_adjust));
-       dpp_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-
-       if (pipe_ctx->plane_state &&
-           pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) {
-               dpp_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
-                       dpp_adjust.temperature_matrix[i] =
-                               pipe_ctx->plane_state->gamut_remap_matrix.matrix[i];
-       }
-
-       pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp,
-                                                           &dpp_adjust);
-
-       memset(&mpc_adjust, 0, sizeof(mpc_adjust));
-       mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-
-       if (pipe_ctx->top_pipe == NULL) {
-               if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
-                       mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-                       for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
-                               mpc_adjust.temperature_matrix[i] =
-                                       pipe_ctx->stream->gamut_remap_matrix.matrix[i];
-               }
-       }
-
-       mpc->funcs->set_gamut_remap(mpc, mpcc_id, &mpc_adjust);
-}
-
-bool dcn30_set_output_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream)
-{
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-       struct pwl_params *params = NULL;
-       bool ret = false;
-
-       /* program OGAM or 3DLUT only for the top pipe*/
-       if (pipe_ctx->top_pipe == NULL) {
-               /*program rmu shaper and 3dlut in MPC*/
-               ret = dcn30_set_mpc_shaper_3dlut(pipe_ctx, stream);
-               if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
-                       if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
-                               params = &stream->out_transfer_func->pwl;
-                       else if (pipe_ctx->stream->out_transfer_func->type ==
-                                       TF_TYPE_DISTRIBUTED_POINTS &&
-                                       cm3_helper_translate_curve_to_hw_format(
-                                       stream->out_transfer_func,
-                                       &mpc->blender_params, false))
-                               params = &mpc->blender_params;
-                        /* there are no ROM LUTs in OUTGAM */
-                       if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
-                               BREAK_TO_DEBUGGER();
-               }
-       }
-
-       mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
-       return ret;
-}
-
-static void dcn30_set_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context)
-{
-       struct mcif_wb *mcif_wb;
-       struct mcif_buf_params *mcif_buf_params;
-
-       ASSERT(wb_info->dwb_pipe_inst < MAX_DWB_PIPES);
-       ASSERT(wb_info->wb_enabled);
-       ASSERT(wb_info->mpcc_inst >= 0);
-       ASSERT(wb_info->mpcc_inst < dc->res_pool->mpcc_count);
-       mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst];
-       mcif_buf_params = &wb_info->mcif_buf_params;
-
-       /* set DWB MPC mux */
-       dc->res_pool->mpc->funcs->set_dwb_mux(dc->res_pool->mpc,
-                       wb_info->dwb_pipe_inst, wb_info->mpcc_inst);
-       /* set MCIF_WB buffer and arbitration configuration */
-       mcif_wb->funcs->config_mcif_buf(mcif_wb, mcif_buf_params, wb_info->dwb_params.dest_height);
-       mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]);
-}
-
-void dcn30_update_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context)
-{
-       struct dwbc *dwb;
-       dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
-       DC_LOG_DWB("%s dwb_pipe_inst = %d, mpcc_inst = %d",\
-               __func__, wb_info->dwb_pipe_inst,\
-               wb_info->mpcc_inst);
-
-       dcn30_set_writeback(dc, wb_info, context);
-
-       /* update DWB */
-       dwb->funcs->update(dwb, &wb_info->dwb_params);
-}
-
-bool dcn30_mmhubbub_warmup(
-       struct dc *dc,
-       unsigned int num_dwb,
-       struct dc_writeback_info *wb_info)
-{
-       struct dwbc *dwb;
-       struct mcif_wb *mcif_wb;
-       struct mcif_warmup_params warmup_params = {0};
-       unsigned int  i, i_buf;
-       /*make sure there is no active DWB eanbled */
-       for (i = 0; i < num_dwb; i++) {
-               dwb = dc->res_pool->dwbc[wb_info[i].dwb_pipe_inst];
-               if (dwb->dwb_is_efc_transition || dwb->dwb_is_drc) {
-                       /*can not do warmup while any dwb enabled*/
-                       return false;
-               }
-       }
-
-       if (wb_info->mcif_warmup_params.p_vmid == 0)
-               return false;
-
-       /*check whether this is new interface: warmup big buffer once*/
-       if (wb_info->mcif_warmup_params.start_address.quad_part != 0 &&
-               wb_info->mcif_warmup_params.region_size != 0) {
-               /*mmhubbub is shared, so it does not matter which MCIF*/
-               mcif_wb = dc->res_pool->mcif_wb[0];
-               /*warmup a big chunk of VM buffer at once*/
-               warmup_params.start_address.quad_part = wb_info->mcif_warmup_params.start_address.quad_part;
-               warmup_params.address_increment =  wb_info->mcif_warmup_params.region_size;
-               warmup_params.region_size = wb_info->mcif_warmup_params.region_size;
-               warmup_params.p_vmid = wb_info->mcif_warmup_params.p_vmid;
-
-               if (warmup_params.address_increment == 0)
-                       warmup_params.address_increment = dc->dml.soc.vmm_page_size_bytes;
-
-               mcif_wb->funcs->warmup_mcif(mcif_wb, &warmup_params);
-               return true;
-       }
-       /*following is the original: warmup each DWB's mcif buffer*/
-       for (i = 0; i < num_dwb; i++) {
-               dwb = dc->res_pool->dwbc[wb_info[i].dwb_pipe_inst];
-               mcif_wb = dc->res_pool->mcif_wb[wb_info[i].dwb_pipe_inst];
-               /*warmup is for VM mode only*/
-               if (wb_info[i].mcif_buf_params.p_vmid == 0)
-                       return false;
-
-               /* Warmup MCIF_WB */
-               for (i_buf = 0; i_buf < MCIF_BUF_COUNT; i_buf++) {
-                       warmup_params.start_address.quad_part = wb_info[i].mcif_buf_params.luma_address[i_buf];
-                       warmup_params.address_increment = dc->dml.soc.vmm_page_size_bytes;
-                       warmup_params.region_size = wb_info[i].mcif_buf_params.luma_pitch * wb_info[i].dwb_params.dest_height;
-                       warmup_params.p_vmid = wb_info[i].mcif_buf_params.p_vmid;
-                       mcif_wb->funcs->warmup_mcif(mcif_wb, &warmup_params);
-               }
-       }
-       return true;
-}
-
-void dcn30_enable_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context)
-{
-       struct dwbc *dwb;
-       struct mcif_wb *mcif_wb;
-
-       dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
-       mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst];
-
-       DC_LOG_DWB("%s dwb_pipe_inst = %d, mpcc_inst = %d",\
-               __func__, wb_info->dwb_pipe_inst,\
-               wb_info->mpcc_inst);
-
-       /* Warmup interface */
-       dcn30_mmhubbub_warmup(dc, 1, wb_info);
-
-       /* Update writeback pipe */
-       dcn30_set_writeback(dc, wb_info, context);
-
-       /* Enable MCIF_WB */
-       mcif_wb->funcs->enable_mcif(mcif_wb);
-       /* Enable DWB */
-       dwb->funcs->enable(dwb, &wb_info->dwb_params);
-}
-
-void dcn30_disable_writeback(
-               struct dc *dc,
-               unsigned int dwb_pipe_inst)
-{
-       struct dwbc *dwb;
-       struct mcif_wb *mcif_wb;
-
-       ASSERT(dwb_pipe_inst < MAX_DWB_PIPES);
-       dwb = dc->res_pool->dwbc[dwb_pipe_inst];
-       mcif_wb = dc->res_pool->mcif_wb[dwb_pipe_inst];
-       DC_LOG_DWB("%s dwb_pipe_inst = %d",\
-               __func__, dwb_pipe_inst);
-
-       /* disable DWB */
-       dwb->funcs->disable(dwb);
-       /* disable MCIF */
-       mcif_wb->funcs->disable_mcif(mcif_wb);
-       /* disable MPC DWB mux */
-       dc->res_pool->mpc->funcs->disable_dwb_mux(dc->res_pool->mpc, dwb_pipe_inst);
-}
-
-void dcn30_program_all_writeback_pipes_in_tree(
-               struct dc *dc,
-               const struct dc_stream_state *stream,
-               struct dc_state *context)
-{
-       struct dc_writeback_info wb_info;
-       struct dwbc *dwb;
-       struct dc_stream_status *stream_status = NULL;
-       int i_wb, i_pipe, i_stream;
-       DC_LOG_DWB("%s", __func__);
-
-       ASSERT(stream);
-       for (i_stream = 0; i_stream < context->stream_count; i_stream++) {
-               if (context->streams[i_stream] == stream) {
-                       stream_status = &context->stream_status[i_stream];
-                       break;
-               }
-       }
-       ASSERT(stream_status);
-
-       ASSERT(stream->num_wb_info <= dc->res_pool->res_cap->num_dwb);
-       /* For each writeback pipe */
-       for (i_wb = 0; i_wb < stream->num_wb_info; i_wb++) {
-
-               /* copy writeback info to local non-const so mpcc_inst can be set */
-               wb_info = stream->writeback_info[i_wb];
-               if (wb_info.wb_enabled) {
-
-                       /* get the MPCC instance for writeback_source_plane */
-                       wb_info.mpcc_inst = -1;
-                       for (i_pipe = 0; i_pipe < dc->res_pool->pipe_count; i_pipe++) {
-                               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i_pipe];
-
-                               if (!pipe_ctx->plane_state)
-                                       continue;
-
-                               if (pipe_ctx->plane_state == wb_info.writeback_source_plane) {
-                                       wb_info.mpcc_inst = pipe_ctx->plane_res.mpcc_inst;
-                                       break;
-                               }
-                       }
-
-                       if (wb_info.mpcc_inst == -1) {
-                               /* Disable writeback pipe and disconnect from MPCC
-                                * if source plane has been removed
-                                */
-                               dc->hwss.disable_writeback(dc, wb_info.dwb_pipe_inst);
-                               continue;
-                       }
-
-                       ASSERT(wb_info.dwb_pipe_inst < dc->res_pool->res_cap->num_dwb);
-                       dwb = dc->res_pool->dwbc[wb_info.dwb_pipe_inst];
-                       if (dwb->funcs->is_enabled(dwb)) {
-                               /* writeback pipe already enabled, only need to update */
-                               dc->hwss.update_writeback(dc, &wb_info, context);
-                       } else {
-                               /* Enable writeback pipe and connect to MPCC */
-                               dc->hwss.enable_writeback(dc, &wb_info, context);
-                       }
-               } else {
-                       /* Disable writeback pipe and disconnect from MPCC */
-                       dc->hwss.disable_writeback(dc, wb_info.dwb_pipe_inst);
-               }
-       }
-}
-
-void dcn30_init_hw(struct dc *dc)
-{
-       struct abm **abms = dc->res_pool->multiple_abms;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       struct resource_pool *res_pool = dc->res_pool;
-       int i;
-       int edp_num;
-       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       // Initialize the dccg
-       if (res_pool->dccg->funcs->dccg_init)
-               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       if (!dcb->funcs->is_accelerated_mode(dcb)) {
-               hws->funcs.bios_golden_init(dc);
-               hws->funcs.disable_vga(dc->hwseq);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.dmcu) {
-               // Force ERAM to shutdown if DMCU is not enabled
-               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
-                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
-               }
-       }
-
-       // Set default OPTC memory power states
-       if (dc->debug.enable_mem_low_power.bits.optc) {
-               // Shutdown when unassigned and light sleep in VBLANK
-               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.vga) {
-               // Power down VGA memory
-               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
-       }
-
-       if (dc->ctx->dc_bios->fw_info_valid) {
-               res_pool->ref_clocks.xtalin_clock_inKhz =
-                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-               if (res_pool->dccg && res_pool->hubbub) {
-
-                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-               } else {
-                       // Not all ASICs have DCCG sw component
-                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-               }
-       } else
-               ASSERT_CRITICAL(false);
-
-       for (i = 0; i < dc->link_count; i++) {
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector).
-                */
-               struct dc_link *link = dc->links[i];
-
-               link->link_enc->funcs->hw_init(link->link_enc);
-
-               /* Check for enabled DIG to identify enabled display */
-               if (link->link_enc->funcs->is_dig_enabled &&
-                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
-                       link->link_status.link_active = true;
-                       if (link->link_enc->funcs->fec_is_active &&
-                                       link->link_enc->funcs->fec_is_active(link->link_enc))
-                               link->fec_state = dc_link_fec_enabled;
-               }
-       }
-
-       /* we want to turn off all dp displays before doing detection */
-       dc->link_srv->blank_all_dp_displays(dc);
-
-       if (hws->funcs.enable_power_gating_plane)
-               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
-
-       /* If taking control over from VBIOS, we may want to optimize our first
-        * mode set, so we need to skip powering down pipes until we know which
-        * pipes we want to use.
-        * Otherwise, if taking control is not possible, we need to power
-        * everything down.
-        */
-       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
-               hws->funcs.init_pipes(dc, dc->current_state);
-               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
-                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
-                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
-       }
-
-       /* In headless boot cases, DIG may be turned
-        * on which causes HW/SW discrepancies.
-        * To avoid this, power down hardware on boot
-        * if DIG is turned on and seamless boot not enabled
-        */
-       if (!dc->config.seamless_boot_edp_requested) {
-               struct dc_link *edp_links[MAX_NUM_EDP];
-               struct dc_link *edp_link = NULL;
-
-               dc_get_edp_links(dc, edp_links, &edp_num);
-               if (edp_num)
-                       edp_link = edp_links[0];
-               if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
-                               edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                               dc->hwss.edp_backlight_control &&
-                               dc->hwss.power_down &&
-                               dc->hwss.edp_power_control) {
-                       dc->hwss.edp_backlight_control(edp_link, false);
-                       dc->hwss.power_down(dc);
-                       dc->hwss.edp_power_control(edp_link, false);
-               } else {
-                       for (i = 0; i < dc->link_count; i++) {
-                               struct dc_link *link = dc->links[i];
-
-                               if (link->link_enc->funcs->is_dig_enabled &&
-                                               link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
-                                               dc->hwss.power_down) {
-                                       dc->hwss.power_down(dc);
-                                       break;
-                               }
-
-                       }
-               }
-       }
-
-       for (i = 0; i < res_pool->audio_count; i++) {
-               struct audio *audio = res_pool->audios[i];
-
-               audio->funcs->hw_init(audio);
-       }
-
-       for (i = 0; i < dc->link_count; i++) {
-               struct dc_link *link = dc->links[i];
-
-               if (link->panel_cntl)
-                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (abms[i] != NULL)
-                       abms[i]->funcs->abm_init(abms[i], backlight);
-       }
-
-       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-       if (!dc->debug.disable_clock_gate) {
-               /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
-               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-       }
-
-       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
-               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
-
-       if (dc->clk_mgr->funcs->notify_wm_ranges)
-               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
-
-       //if softmax is enabled then hardmax will be set by a different call
-       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
-               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
-
-       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
-               dc->res_pool->hubbub->funcs->force_pstate_change_control(
-                               dc->res_pool->hubbub, false, false);
-       if (dc->res_pool->hubbub->funcs->init_crb)
-               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
-
-       // Get DMCUB capabilities
-       dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
-       dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
-       dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
-}
-
-void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
-{
-       if (pipe_ctx == NULL)
-               return;
-
-       if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL)
-               pipe_ctx->stream_res.stream_enc->funcs->set_avmute(
-                               pipe_ctx->stream_res.stream_enc,
-                               enable);
-}
-
-void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx)
-{
-       bool is_hdmi_tmds;
-       bool is_dp;
-
-       ASSERT(pipe_ctx->stream);
-
-       if (pipe_ctx->stream_res.stream_enc == NULL)
-               return;  /* this is not root pipe */
-
-       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
-       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
-
-       if (!is_hdmi_tmds && !is_dp)
-               return;
-
-       if (is_hdmi_tmds)
-               pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
-                       pipe_ctx->stream_res.stream_enc,
-                       &pipe_ctx->stream_res.encoder_info_frame);
-       else {
-               if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)
-                       pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(
-                               pipe_ctx->stream_res.stream_enc,
-                               &pipe_ctx->stream_res.encoder_info_frame);
-
-               pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
-                       pipe_ctx->stream_res.stream_enc,
-                       &pipe_ctx->stream_res.encoder_info_frame);
-       }
-}
-
-void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
-{
-       struct dc_stream_state    *stream     = pipe_ctx->stream;
-       struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
-       bool                       enable     = false;
-       struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
-       enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
-                                                       ? dmdata_dp
-                                                       : dmdata_hdmi;
-
-       /* if using dynamic meta, don't set up generic infopackets */
-       if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-               pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-               enable = true;
-       }
-
-       if (!hubp)
-               return;
-
-       if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
-               return;
-
-       stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
-                                                       hubp->inst, mode);
-}
-
-bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
-{
-       union dmub_rb_cmd cmd;
-       uint32_t tmr_delay = 0, tmr_scale = 0;
-       struct dc_cursor_attributes cursor_attr;
-       bool cursor_cache_enable = false;
-       struct dc_stream_state *stream = NULL;
-       struct dc_plane_state *plane = NULL;
-
-       if (!dc->ctx->dmub_srv)
-               return false;
-
-       if (enable) {
-               if (dc->current_state) {
-                       int i;
-
-                       /* First, check no-memory-requests case */
-                       for (i = 0; i < dc->current_state->stream_count; i++) {
-                               if (dc->current_state->stream_status[i].plane_count)
-                                       /* Fail eligibility on a visible stream */
-                                       break;
-                       }
-
-                       if (i == dc->current_state->stream_count) {
-                               /* Enable no-memory-requests case */
-                               memset(&cmd, 0, sizeof(cmd));
-                               cmd.mall.header.type = DMUB_CMD__MALL;
-                               cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_NO_DF_REQ;
-                               cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header);
-
-                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
-                               return true;
-                       }
-
-                       stream = dc->current_state->streams[0];
-                       plane = (stream ? dc->current_state->stream_status[0].plane_states[0] : NULL);
-
-                       if (stream && plane) {
-                               cursor_cache_enable = stream->cursor_position.enable &&
-                                               plane->address.grph.cursor_cache_addr.quad_part;
-                               cursor_attr = stream->cursor_attributes;
-                       }
-
-                       /*
-                        * Second, check MALL eligibility
-                        *
-                        * single display only, single surface only, 8 and 16 bit formats only, no VM,
-                        * do not use MALL for displays that support PSR as they use D0i3.2 in DMCUB FW
-                        *
-                        * TODO: When we implement multi-display, PSR displays will be allowed if there is
-                        * a non-PSR display present, since in that case we can't do D0i3.2
-                        */
-                       if (dc->current_state->stream_count == 1 &&
-                                       stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED &&
-                                       dc->current_state->stream_status[0].plane_count == 1 &&
-                                       plane->format <= SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F &&
-                                       plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888 &&
-                                       plane->address.page_table_base.quad_part == 0 &&
-                                       dc->hwss.does_plane_fit_in_mall &&
-                                       dc->hwss.does_plane_fit_in_mall(dc, plane,
-                                                       cursor_cache_enable ? &cursor_attr : NULL)) {
-                               unsigned int v_total = stream->adjust.v_total_max ?
-                                               stream->adjust.v_total_max : stream->timing.v_total;
-                               unsigned int refresh_hz = div_u64((unsigned long long) stream->timing.pix_clk_100hz *
-                                               100LL, (v_total * stream->timing.h_total));
-
-                               /*
-                                * one frame time in microsec:
-                                * Delay_Us = 1000000 / refresh
-                                * dynamic_delay_us = 1000000 / refresh + 2 * stutter_period
-                                *
-                                * one frame time modified by 'additional timer percent' (p):
-                                * Delay_Us_modified = dynamic_delay_us + dynamic_delay_us * p / 100
-                                *                   = dynamic_delay_us * (1 + p / 100)
-                                *                   = (1000000 / refresh + 2 * stutter_period) * (100 + p) / 100
-                                *                   = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (100 * refresh)
-                                *
-                                * formula for timer duration based on parameters, from regspec:
-                                * dynamic_delay_us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale
-                                *
-                                * dynamic_delay_us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale
-                                * (dynamic_delay_us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly
-                                * MallFrameCacheTmrDly = ((dynamic_delay_us / 65.28) / 2^MallFrameCacheTmrScale) - 64
-                                *                      = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (100 * refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64
-                                *                      = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64
-                                *
-                                * need to round up the result of the division before the subtraction
-                                */
-                               unsigned int denom = refresh_hz * 6528;
-                               unsigned int stutter_period = dc->current_state->perf_params.stutter_period_us;
-
-                               tmr_delay = div_u64(((1000000LL + 2 * stutter_period * refresh_hz) *
-                                               (100LL + dc->debug.mall_additional_timer_percent) + denom - 1),
-                                               denom) - 64LL;
-
-                               /* In some cases the stutter period is really big (tiny modes) in these
-                                * cases MALL cant be enabled, So skip these cases to avoid a ASSERT()
-                                *
-                                * We can check if stutter_period is more than 1/10th the frame time to
-                                * consider if we can actually meet the range of hysteresis timer
-                                */
-                               if (stutter_period > 100000/refresh_hz)
-                                       return false;
-
-                               /* scale should be increased until it fits into 6 bits */
-                               while (tmr_delay & ~0x3F) {
-                                       tmr_scale++;
-
-                                       if (tmr_scale > 3) {
-                                               /* Delay exceeds range of hysteresis timer */
-                                               ASSERT(false);
-                                               return false;
-                                       }
-
-                                       denom *= 2;
-                                       tmr_delay = div_u64(((1000000LL + 2 * stutter_period * refresh_hz) *
-                                                       (100LL + dc->debug.mall_additional_timer_percent) + denom - 1),
-                                                       denom) - 64LL;
-                               }
-
-                               /* Copy HW cursor */
-                               if (cursor_cache_enable) {
-                                       memset(&cmd, 0, sizeof(cmd));
-                                       cmd.mall.header.type = DMUB_CMD__MALL;
-                                       cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_COPY_CURSOR;
-                                       cmd.mall.header.payload_bytes =
-                                                       sizeof(cmd.mall) - sizeof(cmd.mall.header);
-
-                                       switch (cursor_attr.color_format) {
-                                       case CURSOR_MODE_MONO:
-                                               cmd.mall.cursor_bpp = 2;
-                                               break;
-                                       case CURSOR_MODE_COLOR_1BIT_AND:
-                                       case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
-                                       case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
-                                               cmd.mall.cursor_bpp = 32;
-                                               break;
-
-                                       case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
-                                       case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
-                                               cmd.mall.cursor_bpp = 64;
-                                               break;
-                                       }
-
-                                       cmd.mall.cursor_copy_src.quad_part = cursor_attr.address.quad_part;
-                                       cmd.mall.cursor_copy_dst.quad_part =
-                                                       (plane->address.grph.cursor_cache_addr.quad_part + 2047) & ~2047;
-                                       cmd.mall.cursor_width = cursor_attr.width;
-                                       cmd.mall.cursor_height = cursor_attr.height;
-                                       cmd.mall.cursor_pitch = cursor_attr.pitch;
-
-                                       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-
-                                       /* Use copied cursor, and it's okay to not switch back */
-                                       cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
-                                       dc_stream_set_cursor_attributes(stream, &cursor_attr);
-                               }
-
-                               /* Enable MALL */
-                               memset(&cmd, 0, sizeof(cmd));
-                               cmd.mall.header.type = DMUB_CMD__MALL;
-                               cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_ALLOW;
-                               cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header);
-                               cmd.mall.tmr_delay = tmr_delay;
-                               cmd.mall.tmr_scale = tmr_scale;
-                               cmd.mall.debug_bits = dc->debug.mall_error_as_fatal;
-
-                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
-                               return true;
-                       }
-               }
-
-               /* No applicable optimizations */
-               return false;
-       }
-
-       /* Disable MALL */
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.mall.header.type = DMUB_CMD__MALL;
-       cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_DISALLOW;
-       cmd.mall.header.payload_bytes =
-               sizeof(cmd.mall) - sizeof(cmd.mall.header);
-
-       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-
-       return true;
-}
-
-bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane, struct dc_cursor_attributes *cursor_attr)
-{
-       // add meta size?
-       unsigned int surface_size = plane->plane_size.surface_pitch * plane->plane_size.surface_size.height *
-                       (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
-       unsigned int mall_size = dc->caps.mall_size_total;
-       unsigned int cursor_size = 0;
-
-       if (dc->debug.mall_size_override)
-               mall_size = 1024 * 1024 * dc->debug.mall_size_override;
-
-       if (cursor_attr) {
-               cursor_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size;
-
-               switch (cursor_attr->color_format) {
-               case CURSOR_MODE_MONO:
-                       cursor_size /= 2;
-                       break;
-               case CURSOR_MODE_COLOR_1BIT_AND:
-               case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
-               case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
-                       cursor_size *= 4;
-                       break;
-
-               case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
-               case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
-                       cursor_size *= 8;
-                       break;
-               }
-       }
-
-       return (surface_size + cursor_size) < mall_size;
-}
-
-void dcn30_hardware_release(struct dc *dc)
-{
-       bool subvp_in_use = false;
-       uint32_t i;
-
-       dc_dmub_srv_p_state_delegate(dc, false, NULL);
-       dc_dmub_setup_subvp_dmub_command(dc, dc->current_state, false);
-
-       /* SubVP treated the same way as FPO. If driver disable and
-        * we are using a SubVP config, disable and force on DCN side
-        * to prevent P-State hang on driver enable.
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               if (!pipe->stream)
-                       continue;
-
-               if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
-                       subvp_in_use = true;
-                       break;
-               }
-       }
-       /* If pstate unsupported, or still supported
-        * by firmware, force it supported by dcn
-        */
-       if (dc->current_state)
-               if ((!dc->clk_mgr->clks.p_state_change_support || subvp_in_use ||
-                               dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) &&
-                               dc->res_pool->hubbub->funcs->force_pstate_change_control)
-                       dc->res_pool->hubbub->funcs->force_pstate_change_control(
-                                       dc->res_pool->hubbub, true, true);
-}
-
-void dcn30_set_disp_pattern_generator(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum controller_dp_test_pattern test_pattern,
-               enum controller_dp_color_space color_space,
-               enum dc_color_depth color_depth,
-               const struct tg_color *solid_color,
-               int width, int height, int offset)
-{
-       pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern,
-                       color_space, color_depth, solid_color, width, height, offset);
-}
-
-void dcn30_prepare_bandwidth(struct dc *dc,
-       struct dc_state *context)
-{
-       bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
-       /* Any transition into an FPO config should disable MCLK switching first to avoid
-        * driver and FW P-State synchronization issues.
-        */
-       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
-               dc->optimized_required = true;
-               context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
-       }
-
-       if (dc->clk_mgr->dc_mode_softmax_enabled)
-               if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
-                               context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
-                       dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
-
-       dcn20_prepare_bandwidth(dc, context);
-       /*
-        * enabled -> enabled: do not disable
-        * enabled -> disabled: disable
-        * disabled -> enabled: don't care
-        * disabled -> disabled: don't care
-        */
-       if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
-               dc_dmub_srv_p_state_delegate(dc, false, context);
-
-       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
-               /* After disabling P-State, restore the original value to ensure we get the correct P-State
-                * on the next optimize. */
-               context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
-       }
-}
-
-void dcn30_set_static_screen_control(struct pipe_ctx **pipe_ctx,
-               int num_pipes, const struct dc_static_screen_params *params)
-{
-       unsigned int i;
-       unsigned int triggers = 0;
-
-       if (params->triggers.surface_update)
-               triggers |= 0x100;
-       if (params->triggers.cursor_update)
-               triggers |= 0x8;
-       if (params->triggers.force_trigger)
-               triggers |= 0x1;
-
-       for (i = 0; i < num_pipes; i++)
-               pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(pipe_ctx[i]->stream_res.tg,
-                                       triggers, params->num_frames);
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h
deleted file mode 100644 (file)
index e557e2b..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-* Copyright 2020 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_HWSS_DCN30_H__
-#define __DC_HWSS_DCN30_H__
-
-#include "hw_sequencer_private.h"
-#include "dcn20/dcn20_hwseq.h"
-struct dc;
-
-void dcn30_init_hw(struct dc *dc);
-void dcn30_program_all_writeback_pipes_in_tree(
-               struct dc *dc,
-               const struct dc_stream_state *stream,
-               struct dc_state *context);
-void dcn30_update_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context);
-void dcn30_enable_writeback(
-               struct dc *dc,
-               struct dc_writeback_info *wb_info,
-               struct dc_state *context);
-void dcn30_disable_writeback(
-               struct dc *dc,
-               unsigned int dwb_pipe_inst);
-
-bool dcn30_mmhubbub_warmup(
-       struct dc *dc,
-       unsigned int num_dwb,
-       struct dc_writeback_info *wb_info);
-
-bool dcn30_set_blend_lut(struct pipe_ctx *pipe_ctx,
-               const struct dc_plane_state *plane_state);
-
-bool dcn30_set_input_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state);
-
-void dcn30_program_gamut_remap(struct pipe_ctx *pipe_ctx);
-
-bool dcn30_set_output_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream);
-void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
-void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx);
-void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx);
-
-bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane,
-               struct dc_cursor_attributes *cursor_attr);
-
-bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable);
-
-void dcn30_hardware_release(struct dc *dc);
-
-void dcn30_set_disp_pattern_generator(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               enum controller_dp_test_pattern test_pattern,
-               enum controller_dp_color_space color_space,
-               enum dc_color_depth color_depth,
-               const struct tg_color *solid_color,
-               int width, int height, int offset);
-
-void dcn30_set_hubp_blank(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               bool blank_enable);
-
-void dcn30_prepare_bandwidth(struct dc *dc,
-       struct dc_state *context);
-
-void dcn30_set_static_screen_control(struct pipe_ctx **pipe_ctx,
-               int num_pipes, const struct dc_static_screen_params *params);
-
-#endif /* __DC_HWSS_DCN30_H__ */
index e56fca6..9894cae 100644 (file)
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn21/dcn21_hwseq.h"
-#include "dcn30_hwseq.h"
+#include "dcn30/dcn30_hwseq.h"
 
 #include "dcn30_init.h"
 
index 9f3c862..473581c 100644 (file)
@@ -44,7 +44,7 @@
 #include "dcn30/dcn30_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index 9002cb1..30fbc5e 100644 (file)
@@ -11,7 +11,7 @@
 # Makefile for dcn30.
 
 DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \
-               dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o \
+               dcn301_dio_link_encoder.o dcn301_panel_cntl.o dcn301_hubbub.o \
                dcn301_optc.o
 
 AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hwseq.c
deleted file mode 100644 (file)
index 10bedb2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2020 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 "core_types.h"
-#include "dce/dce_hwseq.h"
-#include "dcn301_hwseq.h"
-#include "reg_helper.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#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
-
-
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hwseq.h
deleted file mode 100644 (file)
index aa3df3f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-* Copyright 2020 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_HWSS_DCN301_H__
-#define __DC_HWSS_DCN301_H__
-
-#include "hw_sequencer_private.h"
-
-
-#endif /* __DC_HWSS_DCN301_H__ */
index fdbe3d4..6477009 100644 (file)
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn21/dcn21_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dcn301_hwseq.h"
+#include "dcn301/dcn301_hwseq.h"
 
 #include "dcn301_init.h"
 
index 6d2f99c..b4b3b52 100644 (file)
@@ -45,7 +45,7 @@
 #include "dcn301/dcn301_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index ebd01cb..95b66ba 100644 (file)
@@ -5,7 +5,7 @@
 #
 # Makefile for dcn302.
 
-DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o
+DCN3_02 = dcn302_init.o dcn302_resource.o
 
 AMD_DAL_DCN3_02 = $(addprefix $(AMDDALPATH)/dc/dcn302/,$(DCN3_02))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.c
deleted file mode 100644 (file)
index 0a6d58d..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2020 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 "dcn302_hwseq.h"
-
-#include "dce/dce_hwseq.h"
-
-#include "reg_helper.h"
-#include "dc.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#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 dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-
-       if (hws->ctx->dc->debug.disable_dpp_power_gate)
-               return;
-       if (REG(DOMAIN1_PG_CONFIG) == 0)
-               return;
-
-       switch (dpp_inst) {
-       case 0: /* DPP0 */
-               REG_UPDATE(DOMAIN1_PG_CONFIG,
-                               DOMAIN1_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN1_PG_STATUS,
-                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DPP1 */
-               REG_UPDATE(DOMAIN3_PG_CONFIG,
-                               DOMAIN3_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN3_PG_STATUS,
-                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DPP2 */
-               REG_UPDATE(DOMAIN5_PG_CONFIG,
-                               DOMAIN5_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN5_PG_STATUS,
-                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DPP3 */
-               REG_UPDATE(DOMAIN7_PG_CONFIG,
-                               DOMAIN7_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN7_PG_STATUS,
-                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 4: /* DPP4 */
-               REG_UPDATE(DOMAIN9_PG_CONFIG,
-                               DOMAIN9_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN9_PG_STATUS,
-                               DOMAIN9_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-
-       if (hws->ctx->dc->debug.disable_hubp_power_gate)
-               return;
-       if (REG(DOMAIN0_PG_CONFIG) == 0)
-               return;
-
-       switch (hubp_inst) {
-       case 0: /* DCHUBP0 */
-               REG_UPDATE(DOMAIN0_PG_CONFIG,
-                               DOMAIN0_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN0_PG_STATUS,
-                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DCHUBP1 */
-               REG_UPDATE(DOMAIN2_PG_CONFIG,
-                               DOMAIN2_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN2_PG_STATUS,
-                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DCHUBP2 */
-               REG_UPDATE(DOMAIN4_PG_CONFIG,
-                               DOMAIN4_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN4_PG_STATUS,
-                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DCHUBP3 */
-               REG_UPDATE(DOMAIN6_PG_CONFIG,
-                               DOMAIN6_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN6_PG_STATUS,
-                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 4: /* DCHUBP4 */
-               REG_UPDATE(DOMAIN8_PG_CONFIG,
-                               DOMAIN8_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN8_PG_STATUS,
-                               DOMAIN8_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_dsc_power_gate)
-               return;
-
-       if (REG(DOMAIN16_PG_CONFIG) == 0)
-               return;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_UPDATE(DOMAIN16_PG_CONFIG,
-                               DOMAIN16_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN16_PG_STATUS,
-                               DOMAIN16_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DSC1 */
-               REG_UPDATE(DOMAIN17_PG_CONFIG,
-                               DOMAIN17_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN17_PG_STATUS,
-                               DOMAIN17_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DSC2 */
-               REG_UPDATE(DOMAIN18_PG_CONFIG,
-                               DOMAIN18_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN18_PG_STATUS,
-                               DOMAIN18_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DSC3 */
-               REG_UPDATE(DOMAIN19_PG_CONFIG,
-                               DOMAIN19_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN19_PG_STATUS,
-                               DOMAIN19_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 4: /* DSC4 */
-               REG_UPDATE(DOMAIN20_PG_CONFIG,
-                               DOMAIN20_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN20_PG_STATUS,
-                               DOMAIN20_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.h
deleted file mode 100644 (file)
index 1e5126a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2020 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_HWSS_DCN302_H__
-#define __DC_HWSS_DCN302_H__
-
-#include "hw_sequencer_private.h"
-
-void dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on);
-void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
-void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
-
-#endif /* __DC_HWSS_DCN302_H__ */
index eb375f3..637f951 100644 (file)
@@ -23,7 +23,7 @@
  *
  */
 
-#include "dcn302_hwseq.h"
+#include "dcn302/dcn302_hwseq.h"
 
 #include "dcn30/dcn30_init.h"
 
index 8702e0b..d7b3ad7 100644 (file)
@@ -6,7 +6,7 @@
 #
 # Makefile for dcn303.
 
-DCN3_03 = dcn303_init.o dcn303_hwseq.o dcn303_resource.o
+DCN3_03 = dcn303_init.o dcn303_resource.o
 
 AMD_DAL_DCN3_03 = $(addprefix $(AMDDALPATH)/dc/dcn303/,$(DCN3_03))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_hwseq.c
deleted file mode 100644 (file)
index b48b732..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright (C) 2021 Advanced Micro Devices, Inc.
- *
- * Authors: AMD
- */
-
-#include "dcn303_hwseq.h"
-
-#include "dce/dce_hwseq.h"
-
-#include "reg_helper.h"
-#include "dc.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#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 dcn303_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on)
-{
-       /*DCN303 removes PG registers*/
-}
-
-void dcn303_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
-{
-       /*DCN303 removes PG registers*/
-}
-
-void dcn303_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on)
-{
-       /*DCN303 removes PG registers*/
-}
-
-void dcn303_enable_power_gating_plane(struct dce_hwseq *hws, bool enable)
-{
-       /*DCN303 removes PG registers*/
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_hwseq.h
deleted file mode 100644 (file)
index 8b69a3b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright (C) 2021 Advanced Micro Devices, Inc.
- *
- * Authors: AMD
- */
-
-#ifndef __DC_HWSS_DCN303_H__
-#define __DC_HWSS_DCN303_H__
-
-#include "hw_sequencer_private.h"
-
-void dcn303_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on);
-void dcn303_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
-void dcn303_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
-void dcn303_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
-
-#endif /* __DC_HWSS_DCN303_H__ */
index f499f8a..39cf7a5 100644 (file)
@@ -5,7 +5,7 @@
  * Authors: AMD
  */
 
-#include "dcn303_hwseq.h"
+#include "dcn303/dcn303_hwseq.h"
 #include "dcn30/dcn30_init.h"
 #include "dc.h"
 
index ec041e3..996d8c1 100644 (file)
@@ -10,7 +10,7 @@
 #
 # Makefile for dcn31.
 
-DCN31 = dcn31_resource.o dcn31_hubbub.o dcn31_hwseq.o dcn31_init.o dcn31_hubp.o \
+DCN31 = dcn31_resource.o dcn31_hubbub.o dcn31_init.o dcn31_hubp.o \
        dcn31_dccg.o dcn31_optc.o dcn31_dio_link_encoder.o dcn31_panel_cntl.o \
        dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o \
        dcn31_afmt.o dcn31_vpg.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
deleted file mode 100644 (file)
index 65e8504..0000000
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * 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 "dm_services.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dccg.h"
-#include "dce/dce_hwseq.h"
-#include "clk_mgr.h"
-#include "reg_helper.h"
-#include "abm.h"
-#include "hubp.h"
-#include "dchubbub.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "mcif_wb.h"
-#include "dc_dmub_srv.h"
-#include "dcn31_hwseq.h"
-#include "link_hwss.h"
-#include "dpcd_defs.h"
-#include "dce/dmub_outbox.h"
-#include "link.h"
-#include "dcn10/dcn10_hw_sequencer.h"
-#include "inc/link_enc_cfg.h"
-#include "dcn30/dcn30_vpg.h"
-#include "dce/dce_i2c_hw.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#define CTX \
-       hws->ctx
-#define REG(reg)\
-       hws->regs->reg
-#define DC_LOGGER \
-               dc->ctx->logger
-
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-
-static void enable_memory_low_power(struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       int i;
-
-       if (dc->debug.enable_mem_low_power.bits.dmcu) {
-               // Force ERAM to shutdown if DMCU is not enabled
-               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
-                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
-               }
-       }
-
-       // Set default OPTC memory power states
-       if (dc->debug.enable_mem_low_power.bits.optc) {
-               // Shutdown when unassigned and light sleep in VBLANK
-               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.vga) {
-               // Power down VGA memory
-               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.mpc &&
-               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode)
-               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
-
-
-       if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
-               // Power down VPGs
-               for (i = 0; i < dc->res_pool->stream_enc_count; i++)
-                       if (dc->res_pool->stream_enc[i]->vpg)
-                               dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
-#if defined(CONFIG_DRM_AMD_DC_FP)
-               for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
-                       dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
-#endif
-       }
-
-}
-
-void dcn31_init_hw(struct dc *dc)
-{
-       struct abm **abms = dc->res_pool->multiple_abms;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       struct resource_pool *res_pool = dc->res_pool;
-       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-       int i;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       if (!dcb->funcs->is_accelerated_mode(dcb)) {
-               hws->funcs.bios_golden_init(dc);
-               if (hws->funcs.disable_vga)
-                       hws->funcs.disable_vga(dc->hwseq);
-       }
-       // Initialize the dccg
-       if (res_pool->dccg->funcs->dccg_init)
-               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       enable_memory_low_power(dc);
-
-       if (dc->ctx->dc_bios->fw_info_valid) {
-               res_pool->ref_clocks.xtalin_clock_inKhz =
-                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-               if (res_pool->dccg && res_pool->hubbub) {
-
-                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-               } else {
-                       // Not all ASICs have DCCG sw component
-                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-               }
-       } else
-               ASSERT_CRITICAL(false);
-
-       for (i = 0; i < dc->link_count; i++) {
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector).
-                */
-               struct dc_link *link = dc->links[i];
-
-               if (link->ep_type != DISPLAY_ENDPOINT_PHY)
-                       continue;
-
-               link->link_enc->funcs->hw_init(link->link_enc);
-
-               /* Check for enabled DIG to identify enabled display */
-               if (link->link_enc->funcs->is_dig_enabled &&
-                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
-                       link->link_status.link_active = true;
-                       if (link->link_enc->funcs->fec_is_active &&
-                                       link->link_enc->funcs->fec_is_active(link->link_enc))
-                               link->fec_state = dc_link_fec_enabled;
-               }
-       }
-
-       /* we want to turn off all dp displays before doing detection */
-       dc->link_srv->blank_all_dp_displays(dc);
-
-       if (hws->funcs.enable_power_gating_plane)
-               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
-
-       /* If taking control over from VBIOS, we may want to optimize our first
-        * mode set, so we need to skip powering down pipes until we know which
-        * pipes we want to use.
-        * Otherwise, if taking control is not possible, we need to power
-        * everything down.
-        */
-       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
-
-               // we want to turn off edp displays if odm is enabled and no seamless boot
-               if (!dc->caps.seamless_odm) {
-                       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-                               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-                               uint32_t num_opps, opp_id_src0, opp_id_src1;
-
-                               num_opps = 1;
-                               if (tg) {
-                                       if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) {
-                                               tg->funcs->get_optc_source(tg, &num_opps,
-                                                               &opp_id_src0, &opp_id_src1);
-                                       }
-                               }
-
-                               if (num_opps > 1) {
-                                       dc->link_srv->blank_all_edp_displays(dc);
-                                       break;
-                               }
-                       }
-               }
-
-               hws->funcs.init_pipes(dc, dc->current_state);
-               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
-                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
-                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
-       }
-
-       for (i = 0; i < res_pool->audio_count; i++) {
-               struct audio *audio = res_pool->audios[i];
-
-               audio->funcs->hw_init(audio);
-       }
-
-       for (i = 0; i < dc->link_count; i++) {
-               struct dc_link *link = dc->links[i];
-
-               if (link->panel_cntl)
-                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (abms[i] != NULL)
-                       abms[i]->funcs->abm_init(abms[i], backlight);
-       }
-
-       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-       // Set i2c to light sleep until engine is setup
-       if (dc->debug.enable_mem_low_power.bits.i2c)
-               REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
-
-       if (hws->funcs.setup_hpo_hw_control)
-               hws->funcs.setup_hpo_hw_control(hws, false);
-
-       if (!dc->debug.disable_clock_gate) {
-               /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
-               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-       }
-
-       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
-               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
-
-       if (dc->clk_mgr->funcs->notify_wm_ranges)
-               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
-
-       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
-               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
-
-       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
-               dc->res_pool->hubbub->funcs->force_pstate_change_control(
-                               dc->res_pool->hubbub, false, false);
-#if defined(CONFIG_DRM_AMD_DC_FP)
-       if (dc->res_pool->hubbub->funcs->init_crb)
-               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
-#endif
-
-       // Get DMCUB capabilities
-       dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
-       dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
-       dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
-}
-
-void dcn31_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_dsc_power_gate)
-               return;
-
-       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
-               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
-               power_on)
-               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
-                       hws->ctx->dc->res_pool->dccg, dsc_inst);
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_UPDATE(DOMAIN16_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN16_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DSC1 */
-               REG_UPDATE(DOMAIN17_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN17_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DSC2 */
-               REG_UPDATE(DOMAIN18_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN18_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-
-       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
-               if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
-                       hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
-                               hws->ctx->dc->res_pool->dccg, dsc_inst);
-       }
-
-}
-
-
-void dcn31_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable)
-{
-       bool force_on = true; /* disable power gating */
-       uint32_t org_ip_request_cntl = 0;
-
-       if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)
-               force_on = false;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-       /* DCHUBP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       /* DPP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       force_on = true; /* disable power gating */
-       if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
-               force_on = false;
-
-       /* DCS0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
-{
-       bool is_hdmi_tmds;
-       bool is_dp;
-
-       ASSERT(pipe_ctx->stream);
-
-       if (pipe_ctx->stream_res.stream_enc == NULL)
-               return;  /* this is not root pipe */
-
-       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
-       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
-
-       if (!is_hdmi_tmds && !is_dp)
-               return;
-
-       if (is_hdmi_tmds)
-               pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
-                       pipe_ctx->stream_res.stream_enc,
-                       &pipe_ctx->stream_res.encoder_info_frame);
-       else if (pipe_ctx->stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets(
-                               pipe_ctx->stream_res.hpo_dp_stream_enc,
-                               &pipe_ctx->stream_res.encoder_info_frame);
-               return;
-       } else {
-               if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)
-                       pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(
-                               pipe_ctx->stream_res.stream_enc,
-                               &pipe_ctx->stream_res.encoder_info_frame);
-
-               pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
-                       pipe_ctx->stream_res.stream_enc,
-                       &pipe_ctx->stream_res.encoder_info_frame);
-       }
-}
-void dcn31_z10_save_init(struct dc *dc)
-{
-       union dmub_rb_cmd cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
-       cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT;
-
-       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-}
-
-void dcn31_z10_restore(const struct dc *dc)
-{
-       union dmub_rb_cmd cmd;
-
-       /*
-        * DMUB notifies whether restore is required.
-        * Optimization to avoid sending commands when not required.
-        */
-       if (!dc_dmub_srv_is_restore_required(dc->ctx->dmub_srv))
-               return;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
-       cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_RESTORE;
-
-       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-}
-
-void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl;
-       if (hws->ctx->dc->debug.disable_hubp_power_gate)
-               return;
-
-       if (REG(DOMAIN0_PG_CONFIG) == 0)
-               return;
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (hubp_inst) {
-       case 0:
-               REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       case 1:
-               REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       case 2:
-               REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       case 3:
-               REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
-{
-       struct dcn_hubbub_phys_addr_config config;
-
-       config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
-       config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
-       config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
-       config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
-       config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
-       config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
-       config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
-       config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
-
-       if (pa_config->gart_config.base_addr_is_mc_addr) {
-               /* Convert from MC address to offset into FB */
-               config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr -
-                               pa_config->system_aperture.fb_base +
-                               pa_config->system_aperture.fb_offset;
-       } else
-               config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
-
-       return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
-}
-
-static void dcn31_reset_back_end_for_pipe(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct dc_state *context)
-{
-       struct dc_link *link;
-
-       DC_LOGGER_INIT(dc->ctx->logger);
-       if (pipe_ctx->stream_res.stream_enc == NULL) {
-               pipe_ctx->stream = NULL;
-               return;
-       }
-       ASSERT(!pipe_ctx->top_pipe);
-
-       dc->hwss.set_abm_immediate_disable(pipe_ctx);
-
-       pipe_ctx->stream_res.tg->funcs->set_dsc_config(
-                       pipe_ctx->stream_res.tg,
-                       OPTC_DSC_DISABLED, 0, 0);
-       pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
-       pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
-       if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
-               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
-       pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
-
-       if (pipe_ctx->stream_res.tg->funcs->set_drr)
-               pipe_ctx->stream_res.tg->funcs->set_drr(
-                               pipe_ctx->stream_res.tg, NULL);
-
-       link = pipe_ctx->stream->link;
-       /* DPMS may already disable or */
-       /* dpms_off status is incorrect due to fastboot
-        * feature. When system resume from S4 with second
-        * screen only, the dpms_off would be true but
-        * VBIOS lit up eDP, so check link status too.
-        */
-       if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
-               dc->link_srv->set_dpms_off(pipe_ctx);
-       else if (pipe_ctx->stream_res.audio)
-               dc->hwss.disable_audio_stream(pipe_ctx);
-
-       /* free acquired resources */
-       if (pipe_ctx->stream_res.audio) {
-               /*disable az_endpoint*/
-               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
-
-               /*free audio*/
-               if (dc->caps.dynamic_audio == true) {
-                       /*we have to dynamic arbitrate the audio endpoints*/
-                       /*we free the resource, need reset is_audio_acquired*/
-                       update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
-                                       pipe_ctx->stream_res.audio, false);
-                       pipe_ctx->stream_res.audio = NULL;
-               }
-       }
-
-       pipe_ctx->stream = NULL;
-       DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
-                                       pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
-}
-
-void dcn31_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       /* Reset Back End*/
-       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
-               struct pipe_ctx *pipe_ctx_old =
-                       &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (!pipe_ctx_old->stream)
-                       continue;
-
-               if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
-                       continue;
-
-               if (!pipe_ctx->stream ||
-                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
-                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
-
-                       dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
-                       if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
-                       if (old_clk)
-                               old_clk->funcs->cs_power_down(old_clk);
-               }
-       }
-
-       /* New dc_state in the process of being applied to hardware. */
-       link_enc_cfg_set_transient_mode(dc, dc->current_state, context);
-}
-
-void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
-{
-       if (hws->ctx->dc->debug.hpo_optimization)
-               REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h
deleted file mode 100644 (file)
index edfc01d..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-* 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 __DC_HWSS_DCN31_H__
-#define __DC_HWSS_DCN31_H__
-
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dcn31_init_hw(struct dc *dc);
-
-void dcn31_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on);
-
-void dcn31_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable);
-
-void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx);
-
-void dcn31_z10_restore(const struct dc *dc);
-void dcn31_z10_save_init(struct dc *dc);
-
-void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
-int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config);
-void dcn31_reset_hw_ctx_wrap(
-               struct dc *dc,
-               struct dc_state *context);
-bool dcn31_is_abm_supported(struct dc *dc,
-               struct dc_state *context, struct dc_stream_state *stream);
-void dcn31_init_pipes(struct dc *dc, struct dc_state *context);
-void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
-
-#endif /* __DC_HWSS_DCN31_H__ */
index 0848615..669f524 100644 (file)
@@ -23,8 +23,8 @@
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn21/dcn21_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
index 239d7ce..cdf005f 100644 (file)
@@ -48,7 +48,7 @@
 #include "dcn31/dcn31_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index 702c28c..72456de 100644 (file)
@@ -10,7 +10,7 @@
 #
 # Makefile for dcn314.
 
-DCN314 = dcn314_resource.o dcn314_hwseq.o dcn314_init.o \
+DCN314 = dcn314_resource.o dcn314_init.o \
                dcn314_dio_stream_encoder.o dcn314_dccg.o dcn314_optc.o
 
 AMD_DAL_DCN314 = $(addprefix $(AMDDALPATH)/dc/dcn314/,$(DCN314))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
deleted file mode 100644 (file)
index 5b19780..0000000
+++ /dev/null
@@ -1,497 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright 2022 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 "dm_services.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dccg.h"
-#include "dce/dce_hwseq.h"
-#include "clk_mgr.h"
-#include "reg_helper.h"
-#include "abm.h"
-#include "hubp.h"
-#include "dchubbub.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "mcif_wb.h"
-#include "dc_dmub_srv.h"
-#include "dcn314_hwseq.h"
-#include "link_hwss.h"
-#include "dpcd_defs.h"
-#include "dce/dmub_outbox.h"
-#include "link.h"
-#include "dcn10/dcn10_hw_sequencer.h"
-#include "inc/link_enc_cfg.h"
-#include "dcn30/dcn30_vpg.h"
-#include "dce/dce_i2c_hw.h"
-#include "dsc.h"
-#include "dcn20/dcn20_optc.h"
-#include "dcn30/dcn30_cm_common.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#define CTX \
-       hws->ctx
-#define REG(reg)\
-       hws->regs->reg
-#define DC_LOGGER \
-       stream->ctx->logger
-
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-               int opp_cnt)
-{
-       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-       int flow_ctrl_cnt;
-
-       if (opp_cnt >= 2)
-               hblank_halved = true;
-
-       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-                       stream->timing.h_border_left -
-                       stream->timing.h_border_right;
-
-       if (hblank_halved)
-               flow_ctrl_cnt /= 2;
-
-       /* ODM combine 4:1 case */
-       if (opp_cnt == 4)
-               flow_ctrl_cnt /= 2;
-
-       return flow_ctrl_cnt;
-}
-
-static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
-{
-       struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 1;
-
-       ASSERT(dsc);
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-               opp_cnt++;
-
-       if (enable) {
-               struct dsc_config dsc_cfg;
-               struct dsc_optc_config dsc_optc_cfg;
-               enum optc_dsc_mode optc_dsc_mode;
-
-               /* Enable DSC hw block */
-               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
-               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
-               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
-               dsc_cfg.color_depth = stream->timing.display_color_depth;
-               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
-               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
-               ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
-               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
-
-               dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
-               dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
-               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                       struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
-
-                       ASSERT(odm_dsc);
-                       odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
-                       odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
-               }
-               dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
-               dsc_cfg.pic_width *= opp_cnt;
-
-               optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
-
-               /* Enable DSC in OPTC */
-               DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
-               pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
-                                                       optc_dsc_mode,
-                                                       dsc_optc_cfg.bytes_per_pixel,
-                                                       dsc_optc_cfg.slice_width);
-       } else {
-               /* disable DSC in OPTC */
-               pipe_ctx->stream_res.tg->funcs->set_dsc_config(
-                               pipe_ctx->stream_res.tg,
-                               OPTC_DSC_DISABLED, 0, 0);
-
-               /* disable DSC block */
-               dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
-               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                       ASSERT(odm_pipe->stream_res.dsc);
-                       odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
-               }
-       }
-}
-
-// Given any pipe_ctx, return the total ODM combine factor, and optionally return
-// the OPPids which are used
-static unsigned int get_odm_config(struct pipe_ctx *pipe_ctx, unsigned int *opp_instances)
-{
-       unsigned int opp_count = 1;
-       struct pipe_ctx *odm_pipe;
-
-       // First get to the top pipe
-       for (odm_pipe = pipe_ctx; odm_pipe->prev_odm_pipe; odm_pipe = odm_pipe->prev_odm_pipe)
-               ;
-
-       // First pipe is always used
-       if (opp_instances)
-               opp_instances[0] = odm_pipe->stream_res.opp->inst;
-
-       // Find and count odm pipes, if any
-       for (odm_pipe = odm_pipe->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               if (opp_instances)
-                       opp_instances[opp_count] = odm_pipe->stream_res.opp->inst;
-               opp_count++;
-       }
-
-       return opp_count;
-}
-
-void dcn314_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 0;
-       int opp_inst[MAX_PIPES] = {0};
-       bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
-       struct mpc_dwb_flow_control flow_control;
-       struct mpc *mpc = dc->res_pool->mpc;
-       int i;
-
-       opp_cnt = get_odm_config(pipe_ctx, opp_inst);
-
-       if (opp_cnt > 1)
-               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
-                               pipe_ctx->stream_res.tg,
-                               opp_inst, opp_cnt,
-                               &pipe_ctx->stream->timing);
-       else
-               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
-
-       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-       flow_control.flow_ctrl_mode = 0;
-       flow_control.flow_ctrl_cnt0 = 0x80;
-       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
-       if (mpc->funcs->set_out_rate_control) {
-               for (i = 0; i < opp_cnt; ++i) {
-                       mpc->funcs->set_out_rate_control(
-                                       mpc, opp_inst[i],
-                                       true,
-                                       rate_control_2x_pclk,
-                                       &flow_control);
-               }
-       }
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
-                               odm_pipe->stream_res.opp,
-                               true);
-       }
-
-       if (pipe_ctx->stream_res.dsc) {
-               struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
-
-               update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
-
-               /* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
-               if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
-                               current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
-                       struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
-                       /* disconnect DSC block from stream */
-                       dsc->funcs->dsc_disconnect(dsc);
-               }
-       }
-}
-
-void dcn314_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_dsc_power_gate)
-               return;
-
-       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
-               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
-               power_on)
-               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
-                       hws->ctx->dc->res_pool->dccg, dsc_inst);
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_UPDATE(DOMAIN16_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN16_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DSC1 */
-               REG_UPDATE(DOMAIN17_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN17_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DSC2 */
-               REG_UPDATE(DOMAIN18_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN18_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DSC3 */
-               REG_UPDATE(DOMAIN19_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN19_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-
-       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
-               if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
-                       hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
-                               hws->ctx->dc->res_pool->dccg, dsc_inst);
-       }
-
-}
-
-void dcn314_enable_power_gating_plane(struct dce_hwseq *hws, bool enable)
-{
-       bool force_on = true; /* disable power gating */
-       uint32_t org_ip_request_cntl = 0;
-
-       if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)
-               force_on = false;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-       /* DCHUBP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       /* DPP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       force_on = true; /* disable power gating */
-       if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
-               force_on = false;
-
-       /* DCS0/1/2/3/4 */
-       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       unsigned int odm_combine_factor = 0;
-       bool two_pix_per_container = false;
-
-       two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
-       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
-
-       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               *k1_div = PIXEL_RATE_DIV_BY_1;
-               *k2_div = PIXEL_RATE_DIV_BY_1;
-       } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
-               *k1_div = PIXEL_RATE_DIV_BY_1;
-               if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-                       *k2_div = PIXEL_RATE_DIV_BY_2;
-               else
-                       *k2_div = PIXEL_RATE_DIV_BY_4;
-       } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
-               if (two_pix_per_container) {
-                       *k1_div = PIXEL_RATE_DIV_BY_1;
-                       *k2_div = PIXEL_RATE_DIV_BY_2;
-               } else {
-                       *k1_div = PIXEL_RATE_DIV_BY_1;
-                       *k2_div = PIXEL_RATE_DIV_BY_4;
-                       if (odm_combine_factor == 2)
-                               *k2_div = PIXEL_RATE_DIV_BY_2;
-               }
-       }
-
-       if ((*k1_div == PIXEL_RATE_DIV_NA) && (*k2_div == PIXEL_RATE_DIV_NA))
-               ASSERT(false);
-
-       return odm_combine_factor;
-}
-
-void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
-{
-       uint32_t pix_per_cycle = 1;
-       uint32_t odm_combine_factor = 1;
-
-       if (!pipe_ctx || !pipe_ctx->stream || !pipe_ctx->stream_res.stream_enc)
-               return;
-
-       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
-       if (optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing) || odm_combine_factor > 1)
-               pix_per_cycle = 2;
-
-       if (pipe_ctx->stream_res.stream_enc->funcs->set_input_mode)
-               pipe_ctx->stream_res.stream_enc->funcs->set_input_mode(pipe_ctx->stream_res.stream_enc,
-                               pix_per_cycle);
-}
-
-void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
-{
-       unsigned int i;
-       struct pipe_ctx *pipe = NULL;
-       bool otg_disabled[MAX_PIPES] = {false};
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               if (pipe->top_pipe || pipe->prev_odm_pipe)
-                       continue;
-
-               if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
-                       pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
-                       reset_sync_context_for_pipe(dc, context, i);
-                       otg_disabled[i] = true;
-               }
-       }
-
-       hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               if (otg_disabled[i])
-                       pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
-       }
-}
-
-void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on)
-{
-       if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
-               return;
-
-       if (hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control)
-               hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control(
-                       hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on);
-}
-
-static void apply_symclk_on_tx_off_wa(struct dc_link *link)
-{
-       /* There are use cases where SYMCLK is referenced by OTG. For instance
-        * for TMDS signal, OTG relies SYMCLK even if TX video output is off.
-        * However current link interface will power off PHY when disabling link
-        * output. This will turn off SYMCLK generated by PHY. The workaround is
-        * to identify such case where SYMCLK is still in use by OTG when we
-        * power off PHY. When this is detected, we will temporarily power PHY
-        * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
-        * program_pix_clk interface. When OTG is disabled, we will then power
-        * off PHY by calling disable link output again.
-        *
-        * In future dcn generations, we plan to rework transmitter control
-        * interface so that we could have an option to set SYMCLK ON TX OFF
-        * state in one step without this workaround
-        */
-
-       struct dc *dc = link->ctx->dc;
-       struct pipe_ctx *pipe_ctx = NULL;
-       uint8_t i;
-
-       if (link->phy_state.symclk_ref_cnts.otg > 0) {
-               for (i = 0; i < MAX_PIPES; i++) {
-                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-                       if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
-                               pipe_ctx->clock_source->funcs->program_pix_clk(
-                                               pipe_ctx->clock_source,
-                                               &pipe_ctx->stream_res.pix_clk_params,
-                                               dc->link_srv->dp_get_encoding_format(
-                                                               &pipe_ctx->link_config.dp_link_settings),
-                                               &pipe_ctx->pll_settings);
-                               link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
-                               break;
-                       }
-               }
-       }
-}
-
-void dcn314_disable_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal)
-{
-       struct dc *dc = link->ctx->dc;
-       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-
-       if (signal == SIGNAL_TYPE_EDP &&
-                       link->dc->hwss.edp_backlight_control &&
-                       !link->skip_implict_edp_power_control)
-               link->dc->hwss.edp_backlight_control(link, false);
-       else if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->lock_phy(dmcu);
-
-       link_hwss->disable_link_output(link, link_res, signal);
-       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
-       /*
-        * Add the logic to extract BOTH power up and power down sequences
-        * from enable/disable link output and only call edp panel control
-        * in enable_link_dp and disable_link_dp once.
-        */
-       if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->unlock_phy(dmcu);
-       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
-
-       apply_symclk_on_tx_off_wa(link);
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
deleted file mode 100644 (file)
index eafcc4e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright 2022 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_HWSS_DCN314_H__
-#define __DC_HWSS_DCN314_H__
-
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dcn314_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
-
-void dcn314_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
-
-void dcn314_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
-
-unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div);
-
-void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
-
-void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
-
-void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
-
-void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal);
-
-#endif /* __DC_HWSS_DCN314_H__ */
index 163dd56..ccb7e31 100644 (file)
@@ -24,8 +24,8 @@
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn21/dcn21_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
index 64a2692..2d7436f 100644 (file)
@@ -50,7 +50,7 @@
 #include "dcn314/dcn314_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index ed80443..c11dbb1 100644 (file)
@@ -47,7 +47,7 @@
 #include "dcn31/dcn31_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index 9133a1e..4220fe4 100644 (file)
@@ -47,7 +47,7 @@
 #include "dcn31/dcn31_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index e943b64..8bb2513 100644 (file)
@@ -10,7 +10,7 @@
 #
 # Makefile for dcn32.
 
-DCN32 = dcn32_resource.o dcn32_hubbub.o dcn32_hwseq.o dcn32_init.o \
+DCN32 = dcn32_resource.o dcn32_hubbub.o dcn32_init.o dcn32_dccg.o \
                dcn32_dccg.o dcn32_optc.o dcn32_mmhubbub.o dcn32_hubp.o dcn32_dpp.o \
                dcn32_dio_stream_encoder.o dcn32_dio_link_encoder.o dcn32_hpo_dp_link_encoder.o \
                dcn32_resource_helpers.o dcn32_mpc.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
deleted file mode 100644 (file)
index 45b557d..0000000
+++ /dev/null
@@ -1,1678 +0,0 @@
-/*
- * 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 "dm_services.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dccg.h"
-#include "dce/dce_hwseq.h"
-#include "dcn30/dcn30_cm_common.h"
-#include "reg_helper.h"
-#include "abm.h"
-#include "hubp.h"
-#include "dchubbub.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "mcif_wb.h"
-#include "dc_dmub_srv.h"
-#include "link_hwss.h"
-#include "dpcd_defs.h"
-#include "dcn32_hwseq.h"
-#include "clk_mgr.h"
-#include "dsc.h"
-#include "dcn20/dcn20_optc.h"
-#include "dce/dmub_hw_lock_mgr.h"
-#include "dcn32_resource.h"
-#include "link.h"
-
-#define DC_LOGGER_INIT(logger)
-
-#define CTX \
-       hws->ctx
-#define REG(reg)\
-       hws->regs->reg
-#define DC_LOGGER \
-       stream->ctx->logger
-
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-
-void dcn32_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_dsc_power_gate)
-               return;
-
-       if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support)
-               return;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_UPDATE(DOMAIN16_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN16_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DSC1 */
-               REG_UPDATE(DOMAIN17_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN17_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DSC2 */
-               REG_UPDATE(DOMAIN18_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN18_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DSC3 */
-               REG_UPDATE(DOMAIN19_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN19_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-
-void dcn32_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable)
-{
-       bool force_on = true; /* disable power gating */
-       uint32_t org_ip_request_cntl = 0;
-
-       if (enable)
-               force_on = false;
-
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       /* DCHUBP0/1/2/3 */
-       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       /* DCS0/1/2/3 */
-       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-
-       if (hws->ctx->dc->debug.disable_hubp_power_gate)
-               return;
-
-       if (REG(DOMAIN0_PG_CONFIG) == 0)
-               return;
-
-       switch (hubp_inst) {
-       case 0:
-               REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       case 1:
-               REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       case 2:
-               REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       case 3:
-               REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
-               REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-}
-
-static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
-{
-       int i;
-
-    /* First, check no-memory-request case */
-       for (i = 0; i < dc->current_state->stream_count; i++) {
-               if ((dc->current_state->stream_status[i].plane_count) &&
-                       (dc->current_state->streams[i]->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED))
-                       /* Fail eligibility on a visible stream */
-                       break;
-       }
-
-       if (i == dc->current_state->stream_count)
-               return true;
-
-       return false;
-}
-
-
-/* This function loops through every surface that needs to be cached in CAB for SS,
- * and calculates the total number of ways required to store all surfaces (primary,
- * meta, cursor).
- */
-static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
-{
-       int i;
-       uint8_t num_ways = 0;
-       uint32_t mall_ss_size_bytes = 0;
-
-       mall_ss_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_size_bytes;
-       // TODO add additional logic for PSR active stream exclusion optimization
-       // mall_ss_psr_active_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_psr_active_size_bytes;
-
-       // Include cursor size for CAB allocation
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[i];
-
-               if (!pipe->stream || !pipe->plane_state)
-                       continue;
-
-               mall_ss_size_bytes += dcn32_helper_calculate_mall_bytes_for_cursor(dc, pipe, false);
-       }
-
-       // Convert number of cache lines required to number of ways
-       if (dc->debug.force_mall_ss_num_ways > 0) {
-               num_ways = dc->debug.force_mall_ss_num_ways;
-       } else {
-               num_ways = dcn32_helper_mall_bytes_to_ways(dc, mall_ss_size_bytes);
-       }
-
-       return num_ways;
-}
-
-bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
-{
-       union dmub_rb_cmd cmd;
-       uint8_t ways, i;
-       int j;
-       bool mall_ss_unsupported = false;
-       struct dc_plane_state *plane = NULL;
-
-       if (!dc->ctx->dmub_srv)
-               return false;
-
-       for (i = 0; i < dc->current_state->stream_count; i++) {
-               /* MALL SS messaging is not supported with PSR at this time */
-               if (dc->current_state->streams[i] != NULL &&
-                               dc->current_state->streams[i]->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
-                       return false;
-       }
-
-       if (enable) {
-               if (dc->current_state) {
-
-                       /* 1. Check no memory request case for CAB.
-                        * If no memory request case, send CAB_ACTION NO_DF_REQ DMUB message
-                        */
-                       if (dcn32_check_no_memory_request_for_cab(dc)) {
-                               /* Enable no-memory-requests case */
-                               memset(&cmd, 0, sizeof(cmd));
-                               cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
-                               cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
-                               cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
-
-                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
-                               return true;
-                       }
-
-                       /* 2. Check if all surfaces can fit in CAB.
-                        * If surfaces can fit into CAB, send CAB_ACTION_ALLOW DMUB message
-                        * and configure HUBP's to fetch from MALL
-                        */
-                       ways = dcn32_calculate_cab_allocation(dc, dc->current_state);
-
-                       /* MALL not supported with Stereo3D or TMZ surface. If any plane is using stereo,
-                        * or TMZ surface, don't try to enter MALL.
-                        */
-                       for (i = 0; i < dc->current_state->stream_count; i++) {
-                               for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) {
-                                       plane = dc->current_state->stream_status[i].plane_states[j];
-
-                                       if (plane->address.type == PLN_ADDR_TYPE_GRPH_STEREO ||
-                                                       plane->address.tmz_surface) {
-                                               mall_ss_unsupported = true;
-                                               break;
-                                       }
-                               }
-                               if (mall_ss_unsupported)
-                                       break;
-                       }
-                       if (ways <= dc->caps.cache_num_ways && !mall_ss_unsupported) {
-                               memset(&cmd, 0, sizeof(cmd));
-                               cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
-                               cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
-                               cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
-                               cmd.cab.cab_alloc_ways = ways;
-
-                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
-                               return true;
-                       }
-
-               }
-               return false;
-       }
-
-       /* Disable CAB */
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
-       cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION;
-       cmd.cab.header.payload_bytes =
-                       sizeof(cmd.cab) - sizeof(cmd.cab.header);
-
-       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-
-       return true;
-}
-
-/* Send DMCUB message with SubVP pipe info
- * - For each pipe in context, populate payload with required SubVP information
- *   if the pipe is using SubVP for MCLK switch
- * - This function must be called while the DMUB HW lock is acquired by driver
- */
-void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context)
-{
-       int i;
-       bool enable_subvp = false;
-
-       if (!dc->ctx || !dc->ctx->dmub_srv)
-               return;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.paired_stream &&
-                               pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN) {
-                       // There is at least 1 SubVP pipe, so enable SubVP
-                       enable_subvp = true;
-                       break;
-               }
-       }
-       dc_dmub_setup_subvp_dmub_command(dc, context, enable_subvp);
-}
-
-/* Sub-Viewport DMUB lock needs to be acquired by driver whenever SubVP is active and:
- * 1. Any full update for any SubVP main pipe
- * 2. Any immediate flip for any SubVP pipe
- * 3. Any flip for DRR pipe
- * 4. If SubVP was previously in use (i.e. in old context)
- */
-void dcn32_subvp_pipe_control_lock(struct dc *dc,
-               struct dc_state *context,
-               bool lock,
-               bool should_lock_all_pipes,
-               struct pipe_ctx *top_pipe_to_program,
-               bool subvp_prev_use)
-{
-       unsigned int i = 0;
-       bool subvp_immediate_flip = false;
-       bool subvp_in_use = false;
-       struct pipe_ctx *pipe;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
-                       subvp_in_use = true;
-                       break;
-               }
-       }
-
-       if (top_pipe_to_program && top_pipe_to_program->stream && top_pipe_to_program->plane_state) {
-               if (top_pipe_to_program->stream->mall_stream_config.type == SUBVP_MAIN &&
-                               top_pipe_to_program->plane_state->flip_immediate)
-                       subvp_immediate_flip = true;
-       }
-
-       // Don't need to lock for DRR VSYNC flips -- FW will wait for DRR pending update cleared.
-       if ((subvp_in_use && (should_lock_all_pipes || subvp_immediate_flip)) || (!subvp_in_use && subvp_prev_use)) {
-               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
-
-               if (!lock) {
-                       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                               pipe = &context->res_ctx.pipe_ctx[i];
-                               if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN &&
-                                               should_lock_all_pipes)
-                                       pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VBLANK);
-                       }
-               }
-
-               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
-               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
-               hw_lock_cmd.bits.lock = lock;
-               hw_lock_cmd.bits.should_release = !lock;
-               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
-       }
-}
-
-void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params)
-{
-       struct dc *dc = params->subvp_pipe_control_lock_fast_params.dc;
-       bool lock = params->subvp_pipe_control_lock_fast_params.lock;
-       struct pipe_ctx *pipe_ctx = params->subvp_pipe_control_lock_fast_params.pipe_ctx;
-       bool subvp_immediate_flip = false;
-
-       if (pipe_ctx && pipe_ctx->stream && pipe_ctx->plane_state) {
-               if (pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN &&
-                               pipe_ctx->plane_state->flip_immediate)
-                       subvp_immediate_flip = true;
-       }
-
-       // Don't need to lock for DRR VSYNC flips -- FW will wait for DRR pending update cleared.
-       if (subvp_immediate_flip) {
-               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
-
-               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
-               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
-               hw_lock_cmd.bits.lock = lock;
-               hw_lock_cmd.bits.should_release = !lock;
-               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
-       }
-}
-
-bool dcn32_set_mpc_shaper_3dlut(
-       struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-       bool result = false;
-
-       const struct pwl_params *shaper_lut = NULL;
-       //get the shaper lut params
-       if (stream->func_shaper) {
-               if (stream->func_shaper->type == TF_TYPE_HWPWL)
-                       shaper_lut = &stream->func_shaper->pwl;
-               else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm_helper_translate_curve_to_hw_format(stream->ctx,
-                                       stream->func_shaper,
-                                       &dpp_base->shaper_params, true);
-                       shaper_lut = &dpp_base->shaper_params;
-               }
-       }
-
-       if (stream->lut3d_func &&
-               stream->lut3d_func->state.bits.initialized == 1) {
-
-               result = mpc->funcs->program_3dlut(mpc,
-                                                               &stream->lut3d_func->lut_3d,
-                                                               mpcc_id);
-
-               result = mpc->funcs->program_shaper(mpc,
-                                                               shaper_lut,
-                                                               mpcc_id);
-       }
-
-       return result;
-}
-
-bool dcn32_set_mcm_luts(
-       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-       bool result = true;
-       struct pwl_params *lut_params = NULL;
-
-       // 1D LUT
-       if (plane_state->blend_tf) {
-               if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
-                       lut_params = &plane_state->blend_tf->pwl;
-               else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                       plane_state->blend_tf,
-                                       &dpp_base->regamma_params, false);
-                       lut_params = &dpp_base->regamma_params;
-               }
-       }
-       result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
-
-       // Shaper
-       if (plane_state->in_shaper_func) {
-               if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL)
-                       lut_params = &plane_state->in_shaper_func->pwl;
-               else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       // TODO: dpp_base replace
-                       ASSERT(false);
-                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                       plane_state->in_shaper_func,
-                                       &dpp_base->shaper_params, true);
-                       lut_params = &dpp_base->shaper_params;
-               }
-       }
-
-       result = mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
-
-       // 3D
-       if (plane_state->lut3d_func && plane_state->lut3d_func->state.bits.initialized == 1)
-               result = mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func->lut_3d, mpcc_id);
-       else
-               result = mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
-
-       return result;
-}
-
-bool dcn32_set_input_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       struct mpc *mpc = dc->res_pool->mpc;
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-
-       enum dc_transfer_func_predefined tf;
-       bool result = true;
-       struct pwl_params *params = NULL;
-
-       if (mpc == NULL || plane_state == NULL)
-               return false;
-
-       tf = TRANSFER_FUNCTION_UNITY;
-
-       if (plane_state->in_transfer_func &&
-               plane_state->in_transfer_func->type == TF_TYPE_PREDEFINED)
-               tf = plane_state->in_transfer_func->tf;
-
-       dpp_base->funcs->dpp_set_pre_degam(dpp_base, tf);
-
-       if (plane_state->in_transfer_func) {
-               if (plane_state->in_transfer_func->type == TF_TYPE_HWPWL)
-                       params = &plane_state->in_transfer_func->pwl;
-               else if (plane_state->in_transfer_func->type == TF_TYPE_DISTRIBUTED_POINTS &&
-                       cm3_helper_translate_curve_to_hw_format(plane_state->in_transfer_func,
-                                       &dpp_base->degamma_params, false))
-                       params = &dpp_base->degamma_params;
-       }
-
-       dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
-
-       if (pipe_ctx->stream_res.opp &&
-                       pipe_ctx->stream_res.opp->ctx &&
-                       hws->funcs.set_mcm_luts)
-               result = hws->funcs.set_mcm_luts(pipe_ctx, plane_state);
-
-       return result;
-}
-
-bool dcn32_set_output_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream)
-{
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
-       struct pwl_params *params = NULL;
-       bool ret = false;
-
-       /* program OGAM or 3DLUT only for the top pipe*/
-       if (resource_is_pipe_type(pipe_ctx, OPP_HEAD)) {
-               /*program shaper and 3dlut in MPC*/
-               ret = dcn32_set_mpc_shaper_3dlut(pipe_ctx, stream);
-               if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
-                       if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
-                               params = &stream->out_transfer_func->pwl;
-                       else if (pipe_ctx->stream->out_transfer_func->type ==
-                                       TF_TYPE_DISTRIBUTED_POINTS &&
-                                       cm3_helper_translate_curve_to_hw_format(
-                                       stream->out_transfer_func,
-                                       &mpc->blender_params, false))
-                               params = &mpc->blender_params;
-                       /* there are no ROM LUTs in OUTGAM */
-                       if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
-                               BREAK_TO_DEBUGGER();
-               }
-       }
-
-       mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
-       return ret;
-}
-
-/* Program P-State force value according to if pipe is using SubVP / FPO or not:
- * 1. Reset P-State force on all pipes first
- * 2. For each main pipe, force P-State disallow (P-State allow moderated by DMUB)
- */
-void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context)
-{
-       int i;
-
-       /* Unforce p-state for each pipe if it is not FPO or SubVP.
-        * For FPO and SubVP, if it's already forced disallow, leave
-        * it as disallow.
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = pipe->plane_res.hubp;
-
-               if (!pipe->stream || !(pipe->stream->mall_stream_config.type == SUBVP_MAIN ||
-                   pipe->stream->fpo_in_use)) {
-                       if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
-                               hubp->funcs->hubp_update_force_pstate_disallow(hubp, false);
-               }
-
-               /* Today only FPO uses cursor P-State force. Only clear cursor P-State force
-                * if it's not FPO.
-                */
-               if (!pipe->stream || !pipe->stream->fpo_in_use) {
-                       if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow)
-                               hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, false);
-               }
-       }
-
-       /* Loop through each pipe -- for each subvp main pipe force p-state allow equal to false.
-        */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = pipe->plane_res.hubp;
-
-               if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
-                       if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
-                               hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
-               }
-
-               if (pipe->stream && pipe->stream->fpo_in_use) {
-                       if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
-                               hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
-                       /* For now only force cursor p-state disallow for FPO
-                        * Needs to be added for subvp once FW side gets updated
-                        */
-                       if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow)
-                               hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, true);
-               }
-       }
-}
-
-/* Update MALL_SEL register based on if pipe / plane
- * is a phantom pipe, main pipe, and if using MALL
- * for SS.
- */
-void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
-{
-       int i;
-       unsigned int num_ways = dcn32_calculate_cab_allocation(dc, context);
-       bool cache_cursor = false;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = pipe->plane_res.hubp;
-
-               if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
-                       int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
-
-                       switch (hubp->curs_attr.color_format) {
-                       case CURSOR_MODE_MONO:
-                               cursor_size /= 2;
-                               break;
-                       case CURSOR_MODE_COLOR_1BIT_AND:
-                       case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
-                       case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
-                               cursor_size *= 4;
-                               break;
-
-                       case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
-                       case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
-                       default:
-                               cursor_size *= 8;
-                               break;
-                       }
-
-                       if (cursor_size > 16384)
-                               cache_cursor = true;
-
-                       if (pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
-                                       hubp->funcs->hubp_update_mall_sel(hubp, 1, false);
-                       } else {
-                               // MALL not supported with Stereo3D
-                               hubp->funcs->hubp_update_mall_sel(hubp,
-                                       num_ways <= dc->caps.cache_num_ways &&
-                                       pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED &&
-                                       pipe->plane_state->address.type !=  PLN_ADDR_TYPE_GRPH_STEREO &&
-                                       !pipe->plane_state->address.tmz_surface ? 2 : 0,
-                                                       cache_cursor);
-                       }
-               }
-       }
-}
-
-/* Program the sub-viewport pipe configuration after the main / phantom pipes
- * have been programmed in hardware.
- * 1. Update force P-State for all the main pipes (disallow P-state)
- * 2. Update MALL_SEL register
- * 3. Program FORCE_ONE_ROW_FOR_FRAME for main subvp pipes
- */
-void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-
-       // Don't force p-state disallow -- can't block dummy p-state
-
-       // Update MALL_SEL register for each pipe
-       if (hws && hws->funcs.update_mall_sel)
-               hws->funcs.update_mall_sel(dc, context);
-
-       // Program FORCE_ONE_ROW_FOR_FRAME and CURSOR_REQ_MODE for main subvp pipes
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = pipe->plane_res.hubp;
-
-               if (pipe->stream && hubp && hubp->funcs->hubp_prepare_subvp_buffering) {
-                       /* TODO - remove setting CURSOR_REQ_MODE to 0 for legacy cases
-                        *      - need to investigate single pipe MPO + SubVP case to
-                        *        see if CURSOR_REQ_MODE will be back to 1 for SubVP
-                        *        when it should be 0 for MPO
-                        */
-                       if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
-                               hubp->funcs->hubp_prepare_subvp_buffering(hubp, true);
-                       }
-               }
-       }
-}
-
-static void dcn32_initialize_min_clocks(struct dc *dc)
-{
-       struct dc_clocks *clocks = &dc->current_state->bw_ctx.bw.dcn.clk;
-
-       clocks->dcfclk_deep_sleep_khz = DCN3_2_DCFCLK_DS_INIT_KHZ;
-       clocks->dcfclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz * 1000;
-       clocks->socclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].socclk_mhz * 1000;
-       clocks->dramclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].memclk_mhz * 1000;
-       clocks->dppclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dppclk_mhz * 1000;
-       clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
-       clocks->fclk_p_state_change_support = true;
-       clocks->p_state_change_support = true;
-       if (dc->debug.disable_boot_optimizations) {
-               clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000;
-       } else {
-               /* Even though DPG_EN = 1 for the connected display, it still requires the
-                * correct timing so we cannot set DISPCLK to min freq or it could cause
-                * audio corruption. Read current DISPCLK from DENTIST and request the same
-                * freq to ensure that the timing is valid and unchanged.
-                */
-               clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
-       }
-
-       dc->clk_mgr->funcs->update_clocks(
-                       dc->clk_mgr,
-                       dc->current_state,
-                       true);
-}
-
-void dcn32_init_hw(struct dc *dc)
-{
-       struct abm **abms = dc->res_pool->multiple_abms;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       struct resource_pool *res_pool = dc->res_pool;
-       int i;
-       int edp_num;
-       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       // Initialize the dccg
-       if (res_pool->dccg->funcs->dccg_init)
-               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       if (!dcb->funcs->is_accelerated_mode(dcb)) {
-               hws->funcs.bios_golden_init(dc);
-               hws->funcs.disable_vga(dc->hwseq);
-       }
-
-       // Set default OPTC memory power states
-       if (dc->debug.enable_mem_low_power.bits.optc) {
-               // Shutdown when unassigned and light sleep in VBLANK
-               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.vga) {
-               // Power down VGA memory
-               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
-       }
-
-       if (dc->ctx->dc_bios->fw_info_valid) {
-               res_pool->ref_clocks.xtalin_clock_inKhz =
-                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-               if (res_pool->dccg && res_pool->hubbub) {
-                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-               } else {
-                       // Not all ASICs have DCCG sw component
-                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-               }
-       } else
-               ASSERT_CRITICAL(false);
-
-       for (i = 0; i < dc->link_count; i++) {
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector).
-                */
-               struct dc_link *link = dc->links[i];
-
-               link->link_enc->funcs->hw_init(link->link_enc);
-
-               /* Check for enabled DIG to identify enabled display */
-               if (link->link_enc->funcs->is_dig_enabled &&
-                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
-                       link->link_status.link_active = true;
-                       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
-                       if (link->link_enc->funcs->fec_is_active &&
-                                       link->link_enc->funcs->fec_is_active(link->link_enc))
-                               link->fec_state = dc_link_fec_enabled;
-               }
-       }
-
-       /* enable_power_gating_plane before dsc_pg_control because
-        * FORCEON = 1 with hw default value on bootup, resume from s3
-        */
-       if (hws->funcs.enable_power_gating_plane)
-               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
-
-       /* we want to turn off all dp displays before doing detection */
-       dc->link_srv->blank_all_dp_displays(dc);
-
-       /* If taking control over from VBIOS, we may want to optimize our first
-        * mode set, so we need to skip powering down pipes until we know which
-        * pipes we want to use.
-        * Otherwise, if taking control is not possible, we need to power
-        * everything down.
-        */
-       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
-               /* Disable boot optimizations means power down everything including PHY, DIG,
-                * and OTG (i.e. the boot is not optimized because we do a full power down).
-                */
-               if (dc->hwss.enable_accelerated_mode && dc->debug.disable_boot_optimizations)
-                       dc->hwss.enable_accelerated_mode(dc, dc->current_state);
-               else
-                       hws->funcs.init_pipes(dc, dc->current_state);
-
-               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
-                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
-                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
-
-               dcn32_initialize_min_clocks(dc);
-
-               /* On HW init, allow idle optimizations after pipes have been turned off.
-                *
-                * In certain D3 cases (i.e. BOCO / BOMACO) it's possible that hardware state
-                * is reset (i.e. not in idle at the time hw init is called), but software state
-                * still has idle_optimizations = true, so we must disable idle optimizations first
-                * (i.e. set false), then re-enable (set true).
-                */
-               dc_allow_idle_optimizations(dc, false);
-               dc_allow_idle_optimizations(dc, true);
-       }
-
-       /* In headless boot cases, DIG may be turned
-        * on which causes HW/SW discrepancies.
-        * To avoid this, power down hardware on boot
-        * if DIG is turned on and seamless boot not enabled
-        */
-       if (!dc->config.seamless_boot_edp_requested) {
-               struct dc_link *edp_links[MAX_NUM_EDP];
-               struct dc_link *edp_link;
-
-               dc_get_edp_links(dc, edp_links, &edp_num);
-               if (edp_num) {
-                       for (i = 0; i < edp_num; i++) {
-                               edp_link = edp_links[i];
-                               if (edp_link->link_enc->funcs->is_dig_enabled &&
-                                               edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                                               dc->hwss.edp_backlight_control &&
-                                               dc->hwss.power_down &&
-                                               dc->hwss.edp_power_control) {
-                                       dc->hwss.edp_backlight_control(edp_link, false);
-                                       dc->hwss.power_down(dc);
-                                       dc->hwss.edp_power_control(edp_link, false);
-                               }
-                       }
-               } else {
-                       for (i = 0; i < dc->link_count; i++) {
-                               struct dc_link *link = dc->links[i];
-
-                               if (link->link_enc->funcs->is_dig_enabled &&
-                                               link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
-                                               dc->hwss.power_down) {
-                                       dc->hwss.power_down(dc);
-                                       break;
-                               }
-
-                       }
-               }
-       }
-
-       for (i = 0; i < res_pool->audio_count; i++) {
-               struct audio *audio = res_pool->audios[i];
-
-               audio->funcs->hw_init(audio);
-       }
-
-       for (i = 0; i < dc->link_count; i++) {
-               struct dc_link *link = dc->links[i];
-
-               if (link->panel_cntl)
-                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (abms[i] != NULL && abms[i]->funcs != NULL)
-                       abms[i]->funcs->abm_init(abms[i], backlight);
-       }
-
-       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-       if (!dc->debug.disable_clock_gate) {
-               /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
-               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-       }
-
-       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
-               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
-
-       if (dc->clk_mgr->funcs->notify_wm_ranges)
-               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
-
-       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
-               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
-
-       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
-               dc->res_pool->hubbub->funcs->force_pstate_change_control(
-                               dc->res_pool->hubbub, false, false);
-
-       if (dc->res_pool->hubbub->funcs->init_crb)
-               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
-
-       if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0)
-               dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->ctx->dc_bios->vram_info.num_chans, dc->config.sdpif_request_limit_words_per_umc);
-
-       // Get DMCUB capabilities
-       if (dc->ctx->dmub_srv) {
-               dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
-               dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
-               dc->caps.dmub_caps.subvp_psr = dc->ctx->dmub_srv->dmub->feature_caps.subvp_psr_support;
-               dc->caps.dmub_caps.gecc_enable = dc->ctx->dmub_srv->dmub->feature_caps.gecc_enable;
-               dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
-       }
-}
-
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-               int opp_cnt)
-{
-       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-       int flow_ctrl_cnt;
-
-       if (opp_cnt >= 2)
-               hblank_halved = true;
-
-       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-                       stream->timing.h_border_left -
-                       stream->timing.h_border_right;
-
-       if (hblank_halved)
-               flow_ctrl_cnt /= 2;
-
-       /* ODM combine 4:1 case */
-       if (opp_cnt == 4)
-               flow_ctrl_cnt /= 2;
-
-       return flow_ctrl_cnt;
-}
-
-static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
-{
-       struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 1;
-
-       ASSERT(dsc);
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-               opp_cnt++;
-
-       if (enable) {
-               struct dsc_config dsc_cfg;
-               struct dsc_optc_config dsc_optc_cfg;
-               enum optc_dsc_mode optc_dsc_mode;
-
-               /* Enable DSC hw block */
-               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
-               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
-               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
-               dsc_cfg.color_depth = stream->timing.display_color_depth;
-               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
-               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
-               ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
-               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
-
-               dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
-               dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
-               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                       struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
-
-                       ASSERT(odm_dsc);
-                       odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
-                       odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
-               }
-               dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
-               dsc_cfg.pic_width *= opp_cnt;
-
-               optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
-
-               /* Enable DSC in OPTC */
-               DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
-               pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
-                                                       optc_dsc_mode,
-                                                       dsc_optc_cfg.bytes_per_pixel,
-                                                       dsc_optc_cfg.slice_width);
-       } else {
-               /* disable DSC in OPTC */
-               pipe_ctx->stream_res.tg->funcs->set_dsc_config(
-                               pipe_ctx->stream_res.tg,
-                               OPTC_DSC_DISABLED, 0, 0);
-
-               /* disable DSC block */
-               dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
-               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                       ASSERT(odm_pipe->stream_res.dsc);
-                       odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
-               }
-       }
-}
-
-/*
-* Given any pipe_ctx, return the total ODM combine factor, and optionally return
-* the OPPids which are used
-* */
-static unsigned int get_odm_config(struct pipe_ctx *pipe_ctx, unsigned int *opp_instances)
-{
-       unsigned int opp_count = 1;
-       struct pipe_ctx *odm_pipe;
-
-       /* First get to the top pipe */
-       for (odm_pipe = pipe_ctx; odm_pipe->prev_odm_pipe; odm_pipe = odm_pipe->prev_odm_pipe)
-               ;
-
-       /* First pipe is always used */
-       if (opp_instances)
-               opp_instances[0] = odm_pipe->stream_res.opp->inst;
-
-       /* Find and count odm pipes, if any */
-       for (odm_pipe = odm_pipe->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               if (opp_instances)
-                       opp_instances[opp_count] = odm_pipe->stream_res.opp->inst;
-               opp_count++;
-       }
-
-       return opp_count;
-}
-
-void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 0;
-       int opp_inst[MAX_PIPES] = {0};
-       bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
-       struct mpc_dwb_flow_control flow_control;
-       struct mpc *mpc = dc->res_pool->mpc;
-       int i;
-
-       opp_cnt = get_odm_config(pipe_ctx, opp_inst);
-
-       if (opp_cnt > 1)
-               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
-                               pipe_ctx->stream_res.tg,
-                               opp_inst, opp_cnt,
-                               &pipe_ctx->stream->timing);
-       else
-               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
-
-       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-       flow_control.flow_ctrl_mode = 0;
-       flow_control.flow_ctrl_cnt0 = 0x80;
-       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
-       if (mpc->funcs->set_out_rate_control) {
-               for (i = 0; i < opp_cnt; ++i) {
-                       mpc->funcs->set_out_rate_control(
-                                       mpc, opp_inst[i],
-                                       true,
-                                       rate_control_2x_pclk,
-                                       &flow_control);
-               }
-       }
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
-                               odm_pipe->stream_res.opp,
-                               true);
-       }
-
-       if (pipe_ctx->stream_res.dsc) {
-               struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
-
-               update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
-
-               /* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
-               if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
-                               current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
-                       struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
-                       /* disconnect DSC block from stream */
-                       dsc->funcs->dsc_disconnect(dsc);
-               }
-       }
-}
-
-unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div)
-{
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       unsigned int odm_combine_factor = 0;
-       bool two_pix_per_container = false;
-
-       two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
-       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
-
-       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               *k1_div = PIXEL_RATE_DIV_BY_1;
-               *k2_div = PIXEL_RATE_DIV_BY_1;
-       } else if (dc_is_hdmi_tmds_signal(stream->signal) || dc_is_dvi_signal(stream->signal)) {
-               *k1_div = PIXEL_RATE_DIV_BY_1;
-               if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
-                       *k2_div = PIXEL_RATE_DIV_BY_2;
-               else
-                       *k2_div = PIXEL_RATE_DIV_BY_4;
-       } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) {
-               if (two_pix_per_container) {
-                       *k1_div = PIXEL_RATE_DIV_BY_1;
-                       *k2_div = PIXEL_RATE_DIV_BY_2;
-               } else {
-                       *k1_div = PIXEL_RATE_DIV_BY_1;
-                       *k2_div = PIXEL_RATE_DIV_BY_4;
-                       if ((odm_combine_factor == 2) || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx))
-                               *k2_div = PIXEL_RATE_DIV_BY_2;
-               }
-       }
-
-       if ((*k1_div == PIXEL_RATE_DIV_NA) && (*k2_div == PIXEL_RATE_DIV_NA))
-               ASSERT(false);
-
-       return odm_combine_factor;
-}
-
-void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
-{
-       uint32_t pix_per_cycle = 1;
-       uint32_t odm_combine_factor = 1;
-
-       if (!pipe_ctx || !pipe_ctx->stream || !pipe_ctx->stream_res.stream_enc)
-               return;
-
-       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
-       if (optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing) || odm_combine_factor > 1
-               || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx))
-               pix_per_cycle = 2;
-
-       if (pipe_ctx->stream_res.stream_enc->funcs->set_input_mode)
-               pipe_ctx->stream_res.stream_enc->funcs->set_input_mode(pipe_ctx->stream_res.stream_enc,
-                               pix_per_cycle);
-}
-
-void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
-{
-       unsigned int i;
-       struct pipe_ctx *pipe = NULL;
-       bool otg_disabled[MAX_PIPES] = {false};
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               if (!resource_is_pipe_type(pipe, OTG_MASTER))
-                       continue;
-
-               if ((pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))
-                       && pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
-                       pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
-                       reset_sync_context_for_pipe(dc, context, i);
-                       otg_disabled[i] = true;
-               }
-       }
-
-       hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               if (otg_disabled[i])
-                       pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
-       }
-}
-
-void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings)
-{
-       struct encoder_unblank_param params = {0};
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct dc_link *link = stream->link;
-       struct dce_hwseq *hws = link->dc->hwseq;
-       struct pipe_ctx *odm_pipe;
-       uint32_t pix_per_cycle = 1;
-
-       params.opp_cnt = 1;
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-               params.opp_cnt++;
-
-       /* only 3 items below are used by unblank */
-       params.timing = pipe_ctx->stream->timing;
-
-       params.link_settings.link_rate = link_settings->link_rate;
-
-       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-               /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
-               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
-                               pipe_ctx->stream_res.hpo_dp_stream_enc,
-                               pipe_ctx->stream_res.tg->inst);
-       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1
-                       || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx)) {
-                       params.timing.pix_clk_100hz /= 2;
-                       pix_per_cycle = 2;
-               }
-               pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine(
-                               pipe_ctx->stream_res.stream_enc, pix_per_cycle > 1);
-               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
-       }
-
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP)
-               hws->funcs.edp_backlight_control(link, true);
-}
-
-bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
-{
-       struct dc *dc = pipe_ctx->stream->ctx->dc;
-
-       if (!is_h_timing_divisible_by_2(pipe_ctx->stream))
-               return false;
-
-       if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) &&
-               dc->debug.enable_dp_dig_pixel_rate_div_policy)
-               return true;
-       return false;
-}
-
-static void apply_symclk_on_tx_off_wa(struct dc_link *link)
-{
-       /* There are use cases where SYMCLK is referenced by OTG. For instance
-        * for TMDS signal, OTG relies SYMCLK even if TX video output is off.
-        * However current link interface will power off PHY when disabling link
-        * output. This will turn off SYMCLK generated by PHY. The workaround is
-        * to identify such case where SYMCLK is still in use by OTG when we
-        * power off PHY. When this is detected, we will temporarily power PHY
-        * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
-        * program_pix_clk interface. When OTG is disabled, we will then power
-        * off PHY by calling disable link output again.
-        *
-        * In future dcn generations, we plan to rework transmitter control
-        * interface so that we could have an option to set SYMCLK ON TX OFF
-        * state in one step without this workaround
-        */
-
-       struct dc *dc = link->ctx->dc;
-       struct pipe_ctx *pipe_ctx = NULL;
-       uint8_t i;
-
-       if (link->phy_state.symclk_ref_cnts.otg > 0) {
-               for (i = 0; i < MAX_PIPES; i++) {
-                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-                       if (resource_is_pipe_type(pipe_ctx, OPP_HEAD) && pipe_ctx->stream->link == link) {
-                               pipe_ctx->clock_source->funcs->program_pix_clk(
-                                               pipe_ctx->clock_source,
-                                               &pipe_ctx->stream_res.pix_clk_params,
-                                               dc->link_srv->dp_get_encoding_format(
-                                                               &pipe_ctx->link_config.dp_link_settings),
-                                               &pipe_ctx->pll_settings);
-                               link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
-                               break;
-                       }
-               }
-       }
-}
-
-void dcn32_disable_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal)
-{
-       struct dc *dc = link->ctx->dc;
-       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-
-       if (signal == SIGNAL_TYPE_EDP &&
-                       link->dc->hwss.edp_backlight_control &&
-                       !link->skip_implict_edp_power_control)
-               link->dc->hwss.edp_backlight_control(link, false);
-       else if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->lock_phy(dmcu);
-
-       link_hwss->disable_link_output(link, link_res, signal);
-       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
-
-       if (signal == SIGNAL_TYPE_EDP &&
-                       link->dc->hwss.edp_backlight_control &&
-                       !link->skip_implict_edp_power_control)
-               link->dc->hwss.edp_power_control(link, false);
-       else if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->unlock_phy(dmcu);
-
-       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
-
-       apply_symclk_on_tx_off_wa(link);
-}
-
-/* For SubVP the main pipe can have a viewport position change
- * without a full update. In this case we must also update the
- * viewport positions for the phantom pipe accordingly.
- */
-void dcn32_update_phantom_vp_position(struct dc *dc,
-               struct dc_state *context,
-               struct pipe_ctx *phantom_pipe)
-{
-       uint32_t i;
-       struct dc_plane_state *phantom_plane = phantom_pipe->plane_state;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN &&
-                               pipe->stream->mall_stream_config.paired_stream == phantom_pipe->stream) {
-                       if (pipe->plane_state && pipe->plane_state->update_flags.bits.position_change) {
-
-                               phantom_plane->src_rect.x = pipe->plane_state->src_rect.x;
-                               phantom_plane->src_rect.y = pipe->plane_state->src_rect.y;
-                               phantom_plane->clip_rect.x = pipe->plane_state->clip_rect.x;
-                               phantom_plane->dst_rect.x = pipe->plane_state->dst_rect.x;
-                               phantom_plane->dst_rect.y = pipe->plane_state->dst_rect.y;
-
-                               phantom_pipe->plane_state->update_flags.bits.position_change = 1;
-                               resource_build_scaling_params(phantom_pipe);
-                               return;
-                       }
-               }
-       }
-}
-
-/* Treat the phantom pipe as if it needs to be fully enabled.
- * If the pipe was previously in use but not phantom, it would
- * have been disabled earlier in the sequence so we need to run
- * the full enable sequence.
- */
-void dcn32_apply_update_flags_for_phantom(struct pipe_ctx *phantom_pipe)
-{
-       phantom_pipe->update_flags.raw = 0;
-       if (phantom_pipe->stream && phantom_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
-               if (resource_is_pipe_type(phantom_pipe, DPP_PIPE)) {
-                       phantom_pipe->update_flags.bits.enable = 1;
-                       phantom_pipe->update_flags.bits.mpcc = 1;
-                       phantom_pipe->update_flags.bits.dppclk = 1;
-                       phantom_pipe->update_flags.bits.hubp_interdependent = 1;
-                       phantom_pipe->update_flags.bits.hubp_rq_dlg_ttu = 1;
-                       phantom_pipe->update_flags.bits.gamut_remap = 1;
-                       phantom_pipe->update_flags.bits.scaler = 1;
-                       phantom_pipe->update_flags.bits.viewport = 1;
-                       phantom_pipe->update_flags.bits.det_size = 1;
-                       if (resource_is_pipe_type(phantom_pipe, OTG_MASTER)) {
-                               phantom_pipe->update_flags.bits.odm = 1;
-                               phantom_pipe->update_flags.bits.global_sync = 1;
-                       }
-               }
-       }
-}
-
-bool dcn32_dsc_pg_status(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst)
-{
-       uint32_t pwr_status = 0;
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_GET(DOMAIN16_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
-               break;
-       case 1: /* DSC1 */
-
-               REG_GET(DOMAIN17_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
-               break;
-       case 2: /* DSC2 */
-               REG_GET(DOMAIN18_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
-               break;
-       case 3: /* DSC3 */
-               REG_GET(DOMAIN19_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       return pwr_status == 0;
-}
-
-void dcn32_update_dsc_pg(struct dc *dc,
-               struct dc_state *context,
-               bool safe_to_disable)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       int i;
-
-       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
-               struct display_stream_compressor *dsc = dc->res_pool->dscs[i];
-               bool is_dsc_ungated = hws->funcs.dsc_pg_status(hws, dsc->inst);
-
-               if (context->res_ctx.is_dsc_acquired[i]) {
-                       if (!is_dsc_ungated) {
-                               hws->funcs.dsc_pg_control(hws, dsc->inst, true);
-                       }
-               } else if (safe_to_disable) {
-                       if (is_dsc_ungated) {
-                               hws->funcs.dsc_pg_control(hws, dsc->inst, false);
-                       }
-               }
-       }
-}
-
-void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context)
-{
-       unsigned int i;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               /* If an active, non-phantom pipe is being transitioned into a phantom
-                * pipe, wait for the double buffer update to complete first before we do
-                * ANY phantom pipe programming.
-                */
-               if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM &&
-                               old_pipe->stream && old_pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
-                       old_pipe->stream_res.tg->funcs->wait_for_state(
-                                       old_pipe->stream_res.tg,
-                                       CRTC_STATE_VBLANK);
-                       old_pipe->stream_res.tg->funcs->wait_for_state(
-                                       old_pipe->stream_res.tg,
-                                       CRTC_STATE_VACTIVE);
-               }
-       }
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
-                       // If old context or new context has phantom pipes, apply
-                       // the phantom timings now. We can't change the phantom
-                       // pipe configuration safely without driver acquiring
-                       // the DMCUB lock first.
-                       dc->hwss.apply_ctx_to_hw(dc, context);
-                       break;
-               }
-       }
-}
-
-/* Blank pixel data during initialization */
-void dcn32_init_blank(
-               struct dc *dc,
-               struct timing_generator *tg)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-       struct output_pixel_processor *opp = NULL;
-       struct output_pixel_processor *bottom_opp = NULL;
-       uint32_t num_opps, opp_id_src0, opp_id_src1;
-       uint32_t otg_active_width, otg_active_height;
-       uint32_t i;
-
-       /* program opp dpg blank color */
-       color_space = COLOR_SPACE_SRGB;
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       /* get the OTG active size */
-       tg->funcs->get_otg_active_size(tg,
-                       &otg_active_width,
-                       &otg_active_height);
-
-       /* get the OPTC source */
-       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-
-       if (opp_id_src0 >= dc->res_pool->res_cap->num_opp) {
-               ASSERT(false);
-               return;
-       }
-
-       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-               if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
-                       opp = dc->res_pool->opps[i];
-                       break;
-               }
-       }
-
-       if (num_opps == 2) {
-               otg_active_width = otg_active_width / 2;
-
-               if (opp_id_src1 >= dc->res_pool->res_cap->num_opp) {
-                       ASSERT(false);
-                       return;
-               }
-               for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-                       if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src1) {
-                               bottom_opp = dc->res_pool->opps[i];
-                               break;
-                       }
-               }
-       }
-
-       if (opp && opp->funcs->opp_set_disp_pattern_generator)
-               opp->funcs->opp_set_disp_pattern_generator(
-                               opp,
-                               CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-                               CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-                               COLOR_DEPTH_UNDEFINED,
-                               &black_color,
-                               otg_active_width,
-                               otg_active_height,
-                               0);
-
-       if (num_opps == 2) {
-               if (bottom_opp && bottom_opp->funcs->opp_set_disp_pattern_generator) {
-                       bottom_opp->funcs->opp_set_disp_pattern_generator(
-                                       bottom_opp,
-                                       CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-                                       CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-                                       COLOR_DEPTH_UNDEFINED,
-                                       &black_color,
-                                       otg_active_width,
-                                       otg_active_height,
-                                       0);
-                       hws->funcs.wait_for_blank_complete(bottom_opp);
-               }
-       }
-
-       if (opp)
-               hws->funcs.wait_for_blank_complete(opp);
-}
-
-void dcn32_blank_phantom(struct dc *dc,
-               struct timing_generator *tg,
-               int width,
-               int height)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-       struct output_pixel_processor *opp = NULL;
-       uint32_t num_opps, opp_id_src0, opp_id_src1;
-       uint32_t otg_active_width, otg_active_height;
-       uint32_t i;
-
-       /* program opp dpg blank color */
-       color_space = COLOR_SPACE_SRGB;
-       color_space_to_black_color(dc, color_space, &black_color);
-
-       otg_active_width = width;
-       otg_active_height = height;
-
-       /* get the OPTC source */
-       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-       ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
-
-       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-               if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
-                       opp = dc->res_pool->opps[i];
-                       break;
-               }
-       }
-
-       if (opp && opp->funcs->opp_set_disp_pattern_generator)
-               opp->funcs->opp_set_disp_pattern_generator(
-                               opp,
-                               CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-                               CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-                               COLOR_DEPTH_UNDEFINED,
-                               &black_color,
-                               otg_active_width,
-                               otg_active_height,
-                               0);
-
-       if (tg->funcs->is_tg_enabled(tg))
-               hws->funcs.wait_for_blank_complete(opp);
-}
-
-bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
-               const struct dc_state *cur_ctx,
-               const struct dc_state *new_ctx)
-{
-       int i;
-       const struct pipe_ctx *cur_pipe, *new_pipe;
-       bool is_seamless = true;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               cur_pipe = &cur_ctx->res_ctx.pipe_ctx[i];
-               new_pipe = &new_ctx->res_ctx.pipe_ctx[i];
-
-               if (resource_is_pipe_type(cur_pipe, FREE_PIPE) ||
-                               resource_is_pipe_type(new_pipe, FREE_PIPE))
-                       /* adding or removing free pipes is always seamless */
-                       continue;
-               else if (resource_is_pipe_type(cur_pipe, OTG_MASTER)) {
-                       if (resource_is_pipe_type(new_pipe, OTG_MASTER))
-                               if (cur_pipe->stream->stream_id == new_pipe->stream->stream_id)
-                               /* OTG master with the same stream is seamless */
-                                       continue;
-               } else if (resource_is_pipe_type(cur_pipe, OPP_HEAD)) {
-                       if (resource_is_pipe_type(new_pipe, OPP_HEAD)) {
-                               if (cur_pipe->stream_res.tg == new_pipe->stream_res.tg)
-                                       /*
-                                        * OPP heads sharing the same timing
-                                        * generator is seamless
-                                        */
-                                       continue;
-                       }
-               } else if (resource_is_pipe_type(cur_pipe, DPP_PIPE)) {
-                       if (resource_is_pipe_type(new_pipe, DPP_PIPE)) {
-                               if (cur_pipe->stream_res.opp == new_pipe->stream_res.opp)
-                                       /*
-                                        * DPP pipes sharing the same OPP head is
-                                        * seamless
-                                        */
-                                       continue;
-                       }
-               }
-
-               /*
-                * This pipe's transition doesn't fall under any seamless
-                * conditions
-                */
-               is_seamless = false;
-               break;
-       }
-
-       return is_seamless;
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
deleted file mode 100644 (file)
index 9992e40..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-* 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 __DC_HWSS_DCN32_H__
-#define __DC_HWSS_DCN32_H__
-
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dcn32_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on);
-
-void dcn32_enable_power_gating_plane(
-       struct dce_hwseq *hws,
-       bool enable);
-
-void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
-
-bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable);
-
-void dcn32_cab_for_ss_control(struct dc *dc, bool enable);
-
-void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context);
-
-bool dcn32_set_mcm_luts(struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state);
-
-bool dcn32_set_input_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state);
-
-bool dcn32_set_mpc_shaper_3dlut(
-       struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream);
-
-bool dcn32_set_output_transfer_func(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream);
-
-void dcn32_init_hw(struct dc *dc);
-
-void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context);
-
-void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context);
-
-void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context);
-
-void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
-
-unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div);
-
-void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
-
-void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
-
-void dcn32_subvp_pipe_control_lock(struct dc *dc,
-               struct dc_state *context,
-               bool lock,
-               bool should_lock_all_pipes,
-               struct pipe_ctx *top_pipe_to_program,
-               bool subvp_prev_use);
-
-void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params);
-
-void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
-               struct dc_link_settings *link_settings);
-
-bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx);
-
-void dcn32_disable_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal);
-
-void dcn32_update_phantom_vp_position(struct dc *dc,
-               struct dc_state *context,
-               struct pipe_ctx *phantom_pipe);
-
-void dcn32_apply_update_flags_for_phantom(struct pipe_ctx *phantom_pipe);
-
-bool dcn32_dsc_pg_status(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst);
-
-void dcn32_update_dsc_pg(struct dc *dc,
-               struct dc_state *context,
-               bool safe_to_disable);
-
-void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context);
-
-void dcn32_init_blank(
-               struct dc *dc,
-               struct timing_generator *tg);
-
-void dcn32_blank_phantom(struct dc *dc,
-               struct timing_generator *tg,
-               int width,
-               int height);
-
-bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
-               const struct dc_state *cur_ctx,
-               const struct dc_state *new_ctx);
-
-#endif /* __DC_HWSS_DCN32_H__ */
index 6e7f6df..90f061e 100644 (file)
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn21/dcn21_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
 #include "dcn31/dcn31_hwseq.h"
-#include "dcn32_hwseq.h"
+#include "dcn32/dcn32_hwseq.h"
 #include "dcn32_init.h"
 
 static const struct hw_sequencer_funcs dcn32_funcs = {
index 4eda12e..81b0588 100644 (file)
@@ -47,7 +47,7 @@
 #include "dcn32/dcn32_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index 2cb6369..44caf67 100644 (file)
@@ -50,7 +50,7 @@
 #include "dcn32/dcn32_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn30/dcn30_opp.h"
 #include "dcn20/dcn20_dsc.h"
 #include "dcn30/dcn30_vpg.h"
index c01d4ab..20d0eef 100644 (file)
@@ -10,7 +10,7 @@
 #
 # Makefile for DCN35.
 
-DCN35 = dcn35_resource.o dcn35_hwseq.o dcn35_init.o dcn35_dio_stream_encoder.o \
+DCN35 = dcn35_resource.o dcn35_init.o dcn35_dio_stream_encoder.o \
        dcn35_dio_link_encoder.o dcn35_dccg.o dcn35_optc.o \
        dcn35_dsc.o dcn35_hubp.o dcn35_hubbub.o \
        dcn35_mmhubbub.o dcn35_opp.o dcn35_dpp.o dcn35_pg_cntl.o dcn35_dwb.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
deleted file mode 100644 (file)
index 2be2a2f..0000000
+++ /dev/null
@@ -1,1205 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright 2023 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.
- *
- */
-
-#include "dm_services.h"
-#include "dm_helpers.h"
-#include "core_types.h"
-#include "resource.h"
-#include "dccg.h"
-#include "dce/dce_hwseq.h"
-#include "clk_mgr.h"
-#include "reg_helper.h"
-#include "abm.h"
-#include "hubp.h"
-#include "dchubbub.h"
-#include "timing_generator.h"
-#include "opp.h"
-#include "ipp.h"
-#include "mpc.h"
-#include "mcif_wb.h"
-#include "dc_dmub_srv.h"
-#include "dcn35_hwseq.h"
-#include "dcn35/dcn35_dccg.h"
-#include "link_hwss.h"
-#include "dpcd_defs.h"
-#include "dce/dmub_outbox.h"
-#include "link.h"
-#include "dcn10/dcn10_hw_sequencer.h"
-#include "inc/link_enc_cfg.h"
-#include "dcn30/dcn30_vpg.h"
-#include "dce/dce_i2c_hw.h"
-#include "dsc.h"
-#include "dcn20/dcn20_optc.h"
-#include "dcn30/dcn30_cm_common.h"
-#include "dcn31/dcn31_hwseq.h"
-#include "dcn20/dcn20_hwseq.h"
-
-#define DC_LOGGER_INIT(logger) \
-       struct dal_logger *dc_logger = logger
-
-#define CTX \
-       hws->ctx
-#define REG(reg)\
-       hws->regs->reg
-#define DC_LOGGER \
-       dc_logger
-
-
-#undef FN
-#define FN(reg_name, field_name) \
-       hws->shifts->field_name, hws->masks->field_name
-#if 0
-static void enable_memory_low_power(struct dc *dc)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       int i;
-
-       if (dc->debug.enable_mem_low_power.bits.dmcu) {
-               // Force ERAM to shutdown if DMCU is not enabled
-               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
-                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
-               }
-       }
-       /*dcn35 has default MEM_PWR enabled, make sure wake them up*/
-       // Set default OPTC memory power states
-       if (dc->debug.enable_mem_low_power.bits.optc) {
-               // Shutdown when unassigned and light sleep in VBLANK
-               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.vga) {
-               // Power down VGA memory
-               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.mpc &&
-               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode)
-               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
-
-       if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
-               // Power down VPGs
-               for (i = 0; i < dc->res_pool->stream_enc_count; i++)
-                       dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
-#if defined(CONFIG_DRM_AMD_DC_DP2_0)
-               for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
-                       dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
-#endif
-       }
-
-}
-#endif
-
-void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable)
-{
-       REG_UPDATE_3(DMU_CLK_CNTL,
-               RBBMIF_FGCG_REP_DIS, !enable,
-               IHC_FGCG_REP_DIS, !enable,
-               LONO_FGCG_REP_DIS, !enable
-       );
-}
-
-void dcn35_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
-{
-       REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
-}
-
-void dcn35_init_hw(struct dc *dc)
-{
-       struct abm **abms = dc->res_pool->multiple_abms;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct dc_bios *dcb = dc->ctx->dc_bios;
-       struct resource_pool *res_pool = dc->res_pool;
-       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-       int i;
-
-       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
-               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
-
-       REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-       REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0x3F000000);
-       REG_WRITE(DCCG_GATE_DISABLE_CNTL5, 0x1f7c3fcf);
-
-       //dcn35_set_dmu_fgcg(hws, dc->debug.enable_fine_grain_clock_gating.bits.dmu);
-
-       if (!dcb->funcs->is_accelerated_mode(dcb)) {
-               /*this calls into dmubfw to do the init*/
-               hws->funcs.bios_golden_init(dc);
-       }
-       // Initialize the dccg
-       if (res_pool->dccg->funcs->dccg_init)
-               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-
-       //enable_memory_low_power(dc);
-
-       if (dc->ctx->dc_bios->fw_info_valid) {
-               res_pool->ref_clocks.xtalin_clock_inKhz =
-                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-               if (res_pool->dccg && res_pool->hubbub) {
-
-                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                               &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                               res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                               &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-               } else {
-                       // Not all ASICs have DCCG sw component
-                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                               res_pool->ref_clocks.xtalin_clock_inKhz;
-                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                               res_pool->ref_clocks.xtalin_clock_inKhz;
-               }
-       } else
-               ASSERT_CRITICAL(false);
-
-       for (i = 0; i < dc->link_count; i++) {
-               /* Power up AND update implementation according to the
-                * required signal (which may be different from the
-                * default signal on connector).
-                */
-               struct dc_link *link = dc->links[i];
-
-               if (link->ep_type != DISPLAY_ENDPOINT_PHY)
-                       continue;
-
-               link->link_enc->funcs->hw_init(link->link_enc);
-
-               /* Check for enabled DIG to identify enabled display */
-               if (link->link_enc->funcs->is_dig_enabled &&
-                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
-                       link->link_status.link_active = true;
-                       if (link->link_enc->funcs->fec_is_active &&
-                                       link->link_enc->funcs->fec_is_active(link->link_enc))
-                               link->fec_state = dc_link_fec_enabled;
-               }
-       }
-
-       /* we want to turn off all dp displays before doing detection */
-       dc->link_srv->blank_all_dp_displays(dc);
-/*
-       if (hws->funcs.enable_power_gating_plane)
-               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
-*/
-       if (res_pool->hubbub->funcs->dchubbub_init)
-               res_pool->hubbub->funcs->dchubbub_init(dc->res_pool->hubbub);
-       /* If taking control over from VBIOS, we may want to optimize our first
-        * mode set, so we need to skip powering down pipes until we know which
-        * pipes we want to use.
-        * Otherwise, if taking control is not possible, we need to power
-        * everything down.
-        */
-       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
-
-               // we want to turn off edp displays if odm is enabled and no seamless boot
-               if (!dc->caps.seamless_odm) {
-                       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-                               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-                               uint32_t num_opps, opp_id_src0, opp_id_src1;
-
-                               num_opps = 1;
-                               if (tg) {
-                                       if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) {
-                                               tg->funcs->get_optc_source(tg, &num_opps,
-                                                               &opp_id_src0, &opp_id_src1);
-                                       }
-                               }
-
-                               if (num_opps > 1) {
-                                       dc->link_srv->blank_all_edp_displays(dc);
-                                       break;
-                               }
-                       }
-               }
-
-               hws->funcs.init_pipes(dc, dc->current_state);
-               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
-                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
-                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
-       }
-
-       for (i = 0; i < res_pool->audio_count; i++) {
-               struct audio *audio = res_pool->audios[i];
-
-               audio->funcs->hw_init(audio);
-       }
-
-       for (i = 0; i < dc->link_count; i++) {
-               struct dc_link *link = dc->links[i];
-
-               if (link->panel_cntl)
-                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
-       }
-       if (dc->ctx->dmub_srv) {
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (abms[i] != NULL && abms[i]->funcs != NULL)
-                       abms[i]->funcs->abm_init(abms[i], backlight);
-               }
-       }
-
-       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
-       // Set i2c to light sleep until engine is setup
-       if (dc->debug.enable_mem_low_power.bits.i2c)
-               REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 0);
-
-       if (hws->funcs.setup_hpo_hw_control)
-               hws->funcs.setup_hpo_hw_control(hws, false);
-
-       if (!dc->debug.disable_clock_gate) {
-               /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
-       }
-
-       if (dc->debug.disable_mem_low_power) {
-               REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
-       }
-       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
-               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
-
-       if (dc->clk_mgr->funcs->notify_wm_ranges)
-               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
-
-       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
-               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
-
-
-
-       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
-               dc->res_pool->hubbub->funcs->force_pstate_change_control(
-                               dc->res_pool->hubbub, false, false);
-
-       if (dc->res_pool->hubbub->funcs->init_crb)
-               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
-
-       if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0)
-               dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->ctx->dc_bios->vram_info.num_chans, dc->config.sdpif_request_limit_words_per_umc);
-       // Get DMCUB capabilities
-       if (dc->ctx->dmub_srv) {
-               dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
-               dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
-               dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
-       }
-
-       if (dc->res_pool->pg_cntl) {
-               if (dc->res_pool->pg_cntl->funcs->init_pg_status)
-                       dc->res_pool->pg_cntl->funcs->init_pg_status(dc->res_pool->pg_cntl);
-       }
-}
-
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-               int opp_cnt)
-{
-       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-       int flow_ctrl_cnt;
-
-       if (opp_cnt >= 2)
-               hblank_halved = true;
-
-       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-                       stream->timing.h_border_left -
-                       stream->timing.h_border_right;
-
-       if (hblank_halved)
-               flow_ctrl_cnt /= 2;
-
-       /* ODM combine 4:1 case */
-       if (opp_cnt == 4)
-               flow_ctrl_cnt /= 2;
-
-       return flow_ctrl_cnt;
-}
-
-static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
-{
-       struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
-       struct dc_stream_state *stream = pipe_ctx->stream;
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 1;
-
-       DC_LOGGER_INIT(stream->ctx->logger);
-
-       ASSERT(dsc);
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-               opp_cnt++;
-
-       if (enable) {
-               struct dsc_config dsc_cfg;
-               struct dsc_optc_config dsc_optc_cfg;
-               enum optc_dsc_mode optc_dsc_mode;
-
-               /* Enable DSC hw block */
-               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
-               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
-               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
-               dsc_cfg.color_depth = stream->timing.display_color_depth;
-               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
-               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
-               ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
-               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
-
-               dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
-               dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
-               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                       struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
-
-                       ASSERT(odm_dsc);
-                       odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
-                       odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
-               }
-               dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
-               dsc_cfg.pic_width *= opp_cnt;
-
-               optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
-
-               /* Enable DSC in OPTC */
-               DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
-               pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
-                                                       optc_dsc_mode,
-                                                       dsc_optc_cfg.bytes_per_pixel,
-                                                       dsc_optc_cfg.slice_width);
-       } else {
-               /* disable DSC in OPTC */
-               pipe_ctx->stream_res.tg->funcs->set_dsc_config(
-                               pipe_ctx->stream_res.tg,
-                               OPTC_DSC_DISABLED, 0, 0);
-
-               /* disable DSC block */
-               dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
-               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                       ASSERT(odm_pipe->stream_res.dsc);
-                       odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
-               }
-       }
-}
-
-// Given any pipe_ctx, return the total ODM combine factor, and optionally return
-// the OPPids which are used
-static unsigned int get_odm_config(struct pipe_ctx *pipe_ctx, unsigned int *opp_instances)
-{
-       unsigned int opp_count = 1;
-       struct pipe_ctx *odm_pipe;
-
-       // First get to the top pipe
-       for (odm_pipe = pipe_ctx; odm_pipe->prev_odm_pipe; odm_pipe = odm_pipe->prev_odm_pipe)
-               ;
-
-       // First pipe is always used
-       if (opp_instances)
-               opp_instances[0] = odm_pipe->stream_res.opp->inst;
-
-       // Find and count odm pipes, if any
-       for (odm_pipe = odm_pipe->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               if (opp_instances)
-                       opp_instances[opp_count] = odm_pipe->stream_res.opp->inst;
-               opp_count++;
-       }
-
-       return opp_count;
-}
-
-void dcn35_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *odm_pipe;
-       int opp_cnt = 0;
-       int opp_inst[MAX_PIPES] = {0};
-       bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
-       struct mpc_dwb_flow_control flow_control;
-       struct mpc *mpc = dc->res_pool->mpc;
-       int i;
-
-       opp_cnt = get_odm_config(pipe_ctx, opp_inst);
-
-       if (opp_cnt > 1)
-               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
-                               pipe_ctx->stream_res.tg,
-                               opp_inst, opp_cnt,
-                               &pipe_ctx->stream->timing);
-       else
-               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
-                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
-
-       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-       flow_control.flow_ctrl_mode = 0;
-       flow_control.flow_ctrl_cnt0 = 0x80;
-       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
-       if (mpc->funcs->set_out_rate_control) {
-               for (i = 0; i < opp_cnt; ++i) {
-                       mpc->funcs->set_out_rate_control(
-                                       mpc, opp_inst[i],
-                                       true,
-                                       rate_control_2x_pclk,
-                                       &flow_control);
-               }
-       }
-
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
-                               odm_pipe->stream_res.opp,
-                               true);
-       }
-
-       if (pipe_ctx->stream_res.dsc) {
-               struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
-
-               update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
-
-               /* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
-               if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
-                               current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
-                       struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
-                       /* disconnect DSC block from stream */
-                       dsc->funcs->dsc_disconnect(dsc);
-               }
-       }
-}
-
-void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on)
-{
-       if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
-               return;
-
-       if (hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control) {
-               hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control(
-                       hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on);
-       }
-}
-
-void dcn35_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on)
-{
-       uint32_t power_gate = power_on ? 0 : 1;
-       uint32_t pwr_status = power_on ? 0 : 2;
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_dsc_power_gate)
-               return;
-       if (hws->ctx->dc->debug.ignore_pg)
-               return;
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-
-       switch (dsc_inst) {
-       case 0: /* DSC0 */
-               REG_UPDATE(DOMAIN16_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN16_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 1: /* DSC1 */
-               REG_UPDATE(DOMAIN17_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN17_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 2: /* DSC2 */
-               REG_UPDATE(DOMAIN18_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN18_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       case 3: /* DSC3 */
-               REG_UPDATE(DOMAIN19_PG_CONFIG,
-                               DOMAIN_POWER_GATE, power_gate);
-
-               REG_WAIT(DOMAIN19_PG_STATUS,
-                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
-                               1, 1000);
-               break;
-       default:
-               BREAK_TO_DEBUGGER();
-               break;
-       }
-
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
-}
-
-void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable)
-{
-       bool force_on = true; /* disable power gating */
-       uint32_t org_ip_request_cntl = 0;
-
-       if (hws->ctx->dc->debug.disable_hubp_power_gate)
-               return;
-       if (hws->ctx->dc->debug.ignore_pg)
-               return;
-       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
-       if (org_ip_request_cntl == 0)
-               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
-       /* DCHUBP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       /* DPP0/1/2/3/4/5 */
-       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-       force_on = true; /* disable power gating */
-       if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
-               force_on = false;
-
-       /* DCS0/1/2/3/4 */
-       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-       REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
-
-}
-
-/* In headless boot cases, DIG may be turned
- * on which causes HW/SW discrepancies.
- * To avoid this, power down hardware on boot
- * if DIG is turned on
- */
-void dcn35_power_down_on_boot(struct dc *dc)
-{
-       struct dc_link *edp_links[MAX_NUM_EDP];
-       struct dc_link *edp_link = NULL;
-       int edp_num;
-       int i = 0;
-
-       dc_get_edp_links(dc, edp_links, &edp_num);
-       if (edp_num)
-               edp_link = edp_links[0];
-
-       if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
-                       edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                       dc->hwseq->funcs.edp_backlight_control &&
-                       dc->hwss.power_down &&
-                       dc->hwss.edp_power_control) {
-               dc->hwseq->funcs.edp_backlight_control(edp_link, false);
-               dc->hwss.power_down(dc);
-               dc->hwss.edp_power_control(edp_link, false);
-       } else {
-               for (i = 0; i < dc->link_count; i++) {
-                       struct dc_link *link = dc->links[i];
-
-                       if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
-                                       link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
-                                       dc->hwss.power_down) {
-                               dc->hwss.power_down(dc);
-                               break;
-                       }
-
-               }
-       }
-
-       /*
-        * Call update_clocks with empty context
-        * to send DISPLAY_OFF
-        * Otherwise DISPLAY_OFF may not be asserted
-        */
-       if (dc->clk_mgr->funcs->set_low_power_state)
-               dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
-
-       if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER) {
-               if (!dc->idle_optimizations_allowed) {
-                       dc_dmub_srv_notify_idle(dc, true);
-                       dc->idle_optimizations_allowed = true;
-               }
-       }
-}
-
-bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
-{
-       struct dc_link *edp_links[MAX_NUM_EDP];
-       int edp_num;
-       if (dc->debug.dmcub_emulation)
-               return true;
-
-       if (enable) {
-               dc_get_edp_links(dc, edp_links, &edp_num);
-               if (edp_num == 0 || edp_num > 1)
-                       return false;
-       }
-
-       // TODO: review other cases when idle optimization is allowed
-
-       if (!enable)
-               dc_dmub_srv_exit_low_power_state(dc);
-       else
-               dc_dmub_srv_notify_idle(dc, enable);
-
-       return true;
-}
-
-void dcn35_z10_restore(const struct dc *dc)
-{
-       if (dc->debug.disable_z10)
-               return;
-
-       dc_dmub_srv_exit_low_power_state(dc);
-
-       dcn31_z10_restore(dc);
-}
-
-void dcn35_init_pipes(struct dc *dc, struct dc_state *context)
-{
-       int i;
-       struct dce_hwseq *hws = dc->hwseq;
-       struct hubbub *hubbub = dc->res_pool->hubbub;
-       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
-       bool can_apply_seamless_boot = false;
-
-       for (i = 0; i < context->stream_count; i++) {
-               if (context->streams[i]->apply_seamless_boot_optimization) {
-                       can_apply_seamless_boot = true;
-                       break;
-               }
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* There is assumption that pipe_ctx is not mapping irregularly
-                * to non-preferred front end. If pipe_ctx->stream is not NULL,
-                * we will use the pipe, so don't disable
-                */
-               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
-                       continue;
-
-               /* Blank controller using driver code instead of
-                * command table.
-                */
-               if (tg->funcs->is_tg_enabled(tg)) {
-                       if (hws->funcs.init_blank != NULL) {
-                               hws->funcs.init_blank(dc, tg);
-                               tg->funcs->lock(tg);
-                       } else {
-                               tg->funcs->lock(tg);
-                               tg->funcs->set_blank(tg, true);
-                               hwss_wait_for_blank_complete(tg);
-                       }
-               }
-       }
-
-       /* Reset det size */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               struct hubp *hubp = dc->res_pool->hubps[i];
-
-               /* Do not need to reset for seamless boot */
-               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
-                       continue;
-
-               if (hubbub && hubp) {
-                       if (hubbub->funcs->program_det_size)
-                               hubbub->funcs->program_det_size(hubbub, hubp->inst, 0);
-               }
-       }
-
-       /* num_opp will be equal to number of mpcc */
-       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* Cannot reset the MPC mux if seamless boot */
-               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
-                       continue;
-
-               dc->res_pool->mpc->funcs->mpc_init_single_inst(
-                               dc->res_pool->mpc, i);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-               struct hubp *hubp = dc->res_pool->hubps[i];
-               struct dpp *dpp = dc->res_pool->dpps[i];
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               /* There is assumption that pipe_ctx is not mapping irregularly
-                * to non-preferred front end. If pipe_ctx->stream is not NULL,
-                * we will use the pipe, so don't disable
-                */
-               if (can_apply_seamless_boot &&
-                       pipe_ctx->stream != NULL &&
-                       pipe_ctx->stream_res.tg->funcs->is_tg_enabled(
-                               pipe_ctx->stream_res.tg)) {
-                       // Enable double buffering for OTG_BLANK no matter if
-                       // seamless boot is enabled or not to suppress global sync
-                       // signals when OTG blanked. This is to prevent pipe from
-                       // requesting data while in PSR.
-                       tg->funcs->tg_init(tg);
-                       hubp->power_gated = true;
-                       continue;
-               }
-
-               /* Disable on the current state so the new one isn't cleared. */
-               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-
-               dpp->funcs->dpp_reset(dpp);
-
-               pipe_ctx->stream_res.tg = tg;
-               pipe_ctx->pipe_idx = i;
-
-               pipe_ctx->plane_res.hubp = hubp;
-               pipe_ctx->plane_res.dpp = dpp;
-               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
-               hubp->mpcc_id = dpp->inst;
-               hubp->opp_id = OPP_ID_INVALID;
-               hubp->power_gated = false;
-
-               dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
-               dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
-               dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
-               pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
-
-               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
-
-               if (tg->funcs->is_tg_enabled(tg))
-                       tg->funcs->unlock(tg);
-
-               dc->hwss.disable_plane(dc, pipe_ctx);
-
-               pipe_ctx->stream_res.tg = NULL;
-               pipe_ctx->plane_res.hubp = NULL;
-
-               if (tg->funcs->is_tg_enabled(tg)) {
-                       if (tg->funcs->init_odm)
-                               tg->funcs->init_odm(tg);
-               }
-
-               tg->funcs->tg_init(tg);
-       }
-
-       if (pg_cntl != NULL) {
-               if (pg_cntl->funcs->dsc_pg_control != NULL) {
-                       uint32_t num_opps = 0;
-                       uint32_t opp_id_src0 = OPP_ID_INVALID;
-                       uint32_t opp_id_src1 = OPP_ID_INVALID;
-
-                       // Step 1: To find out which OPTC is running & OPTC DSC is ON
-                       // We can't use res_pool->res_cap->num_timing_generator to check
-                       // Because it records display pipes default setting built in driver,
-                       // not display pipes of the current chip.
-                       // Some ASICs would be fused display pipes less than the default setting.
-                       // In dcnxx_resource_construct function, driver would obatin real information.
-                       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
-                               uint32_t optc_dsc_state = 0;
-                               struct timing_generator *tg = dc->res_pool->timing_generators[i];
-
-                               if (tg->funcs->is_tg_enabled(tg)) {
-                                       if (tg->funcs->get_dsc_status)
-                                               tg->funcs->get_dsc_status(tg, &optc_dsc_state);
-                                       // Only one OPTC with DSC is ON, so if we got one result,
-                                       // we would exit this block. non-zero value is DSC enabled
-                                       if (optc_dsc_state != 0) {
-                                               tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-                                               break;
-                                       }
-                               }
-                       }
-
-                       // Step 2: To power down DSC but skip DSC  of running OPTC
-                       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
-                               struct dcn_dsc_state s  = {0};
-
-                               dc->res_pool->dscs[i]->funcs->dsc_read_state(dc->res_pool->dscs[i], &s);
-
-                               if ((s.dsc_opp_source == opp_id_src0 || s.dsc_opp_source == opp_id_src1) &&
-                                       s.dsc_clock_en && s.dsc_fw_en)
-                                       continue;
-
-                               pg_cntl->funcs->dsc_pg_control(pg_cntl, dc->res_pool->dscs[i]->inst, false);
-                       }
-               }
-       }
-}
-
-void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                              struct dc_state *context)
-{
-       /* enable DCFCLK current DCHUB */
-       pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
-
-       /* initialize HUBP on power up */
-       pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp);
-
-       /* make sure OPP_PIPE_CLOCK_EN = 1 */
-       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
-                       pipe_ctx->stream_res.opp,
-                       true);
-       /*to do: insert PG here*/
-       if (dc->vm_pa_config.valid) {
-               struct vm_system_aperture_param apt;
-
-               apt.sys_default.quad_part = 0;
-
-               apt.sys_low.quad_part = dc->vm_pa_config.system_aperture.start_addr;
-               apt.sys_high.quad_part = dc->vm_pa_config.system_aperture.end_addr;
-
-               // Program system aperture settings
-               pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
-       }
-
-       if (!pipe_ctx->top_pipe
-               && pipe_ctx->plane_state
-               && pipe_ctx->plane_state->flip_int_enabled
-               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
-               pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
-}
-
-/* disable HW used by plane.
- * note:  cannot disable until disconnect is complete
- */
-void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       struct dpp *dpp = pipe_ctx->plane_res.dpp;
-
-       dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
-
-       /* In flip immediate with pipe splitting case GSL is used for
-        * synchronization so we must disable it when the plane is disabled.
-        */
-       if (pipe_ctx->stream_res.gsl_group != 0)
-               dcn20_setup_gsl_group_as_lock(dc, pipe_ctx, false);
-/*
-       if (hubp->funcs->hubp_update_mall_sel)
-               hubp->funcs->hubp_update_mall_sel(hubp, 0, false);
-*/
-       dc->hwss.set_flip_control_gsl(pipe_ctx, false);
-
-       hubp->funcs->hubp_clk_cntl(hubp, false);
-
-       dpp->funcs->dpp_dppclk_control(dpp, false, false);
-/*to do, need to support both case*/
-       hubp->power_gated = true;
-
-       dpp->funcs->dpp_reset(dpp);
-
-       pipe_ctx->stream = NULL;
-       memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
-       memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
-       pipe_ctx->top_pipe = NULL;
-       pipe_ctx->bottom_pipe = NULL;
-       pipe_ctx->plane_state = NULL;
-}
-
-void dcn35_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       struct dce_hwseq *hws = dc->hwseq;
-       bool is_phantom = pipe_ctx->plane_state && pipe_ctx->plane_state->is_phantom;
-       struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL;
-
-       DC_LOGGER_INIT(dc->ctx->logger);
-
-       if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
-               return;
-
-       if (hws->funcs.plane_atomic_disable)
-               hws->funcs.plane_atomic_disable(dc, pipe_ctx);
-
-       /* Turn back off the phantom OTG after the phantom plane is fully disabled
-        */
-       if (is_phantom)
-               if (tg && tg->funcs->disable_phantom_crtc)
-                       tg->funcs->disable_phantom_crtc(tg);
-
-       DC_LOG_DC("Power down front end %d\n",
-                                       pipe_ctx->pipe_idx);
-}
-
-void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
-       struct pg_block_update *update_state)
-{
-       bool hpo_frl_stream_enc_acquired = false;
-       bool hpo_dp_stream_enc_acquired = false;
-       int i = 0, j = 0;
-
-       memset(update_state, 0, sizeof(struct pg_block_update));
-
-       for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) {
-               if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] &&
-                               dc->res_pool->hpo_dp_stream_enc[i]) {
-                       hpo_dp_stream_enc_acquired = true;
-                       break;
-               }
-       }
-
-       if (!hpo_frl_stream_enc_acquired && !hpo_dp_stream_enc_acquired)
-               update_state->pg_res_update[PG_HPO] = true;
-
-       update_state->pg_res_update[PG_DWB] = true;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
-               for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++)
-                       update_state->pg_pipe_res_update[j][i] = true;
-
-               if (!pipe_ctx)
-                       continue;
-
-               if (pipe_ctx->plane_res.hubp)
-                       update_state->pg_pipe_res_update[PG_HUBP][pipe_ctx->plane_res.hubp->inst] = false;
-
-               if (pipe_ctx->plane_res.dpp)
-                       update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->plane_res.hubp->inst] = false;
-
-               if ((pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp) &&
-                       pipe_ctx->plane_res.mpcc_inst >= 0)
-                       update_state->pg_pipe_res_update[PG_MPCC][pipe_ctx->plane_res.mpcc_inst] = false;
-
-               if (pipe_ctx->stream_res.dsc)
-                       update_state->pg_pipe_res_update[PG_DSC][pipe_ctx->stream_res.dsc->inst] = false;
-
-               if (pipe_ctx->stream_res.opp)
-                       update_state->pg_pipe_res_update[PG_OPP][pipe_ctx->stream_res.opp->inst] = false;
-
-               if (pipe_ctx->stream_res.tg)
-                       update_state->pg_pipe_res_update[PG_OPTC][pipe_ctx->stream_res.tg->inst] = false;
-       }
-}
-
-void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
-       struct pg_block_update *update_state)
-{
-       bool hpo_frl_stream_enc_acquired = false;
-       bool hpo_dp_stream_enc_acquired = false;
-       int i = 0, j = 0;
-
-       memset(update_state, 0, sizeof(struct pg_block_update));
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *cur_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (cur_pipe == NULL || new_pipe == NULL)
-                       continue;
-
-               if ((!cur_pipe->plane_state && new_pipe->plane_state) ||
-                       (!cur_pipe->stream && new_pipe->stream)) {
-                       // New pipe addition
-                       for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) {
-                               if (j == PG_HUBP && new_pipe->plane_res.hubp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.hubp->inst] = true;
-
-                               if (j == PG_DPP && new_pipe->plane_res.dpp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.dpp->inst] = true;
-
-                               if (j == PG_MPCC && new_pipe->plane_res.dpp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.mpcc_inst] = true;
-
-                               if (j == PG_DSC && new_pipe->stream_res.dsc)
-                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.dsc->inst] = true;
-
-                               if (j == PG_OPP && new_pipe->stream_res.opp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.opp->inst] = true;
-
-                               if (j == PG_OPTC && new_pipe->stream_res.tg)
-                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.tg->inst] = true;
-                       }
-               } else if (cur_pipe->plane_state == new_pipe->plane_state ||
-                               cur_pipe == new_pipe) {
-                       //unchanged pipes
-                       for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) {
-                               if (j == PG_HUBP &&
-                                       cur_pipe->plane_res.hubp != new_pipe->plane_res.hubp &&
-                                       new_pipe->plane_res.hubp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.hubp->inst] = true;
-
-                               if (j == PG_DPP &&
-                                       cur_pipe->plane_res.dpp != new_pipe->plane_res.dpp &&
-                                       new_pipe->plane_res.dpp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.dpp->inst] = true;
-
-                               if (j == PG_OPP &&
-                                       cur_pipe->stream_res.opp != new_pipe->stream_res.opp &&
-                                       new_pipe->stream_res.opp)
-                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.opp->inst] = true;
-
-                               if (j == PG_DSC &&
-                                       cur_pipe->stream_res.dsc != new_pipe->stream_res.dsc &&
-                                       new_pipe->stream_res.dsc)
-                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.dsc->inst] = true;
-
-                               if (j == PG_OPTC &&
-                                       cur_pipe->stream_res.tg != new_pipe->stream_res.tg &&
-                                       new_pipe->stream_res.tg)
-                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.tg->inst] = true;
-                       }
-               }
-       }
-
-       for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) {
-               if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] &&
-                               dc->res_pool->hpo_dp_stream_enc[i]) {
-                       hpo_dp_stream_enc_acquired = true;
-                       break;
-               }
-       }
-
-       if (hpo_frl_stream_enc_acquired || hpo_dp_stream_enc_acquired)
-               update_state->pg_res_update[PG_HPO] = true;
-
-}
-
-void dcn35_block_power_control(struct dc *dc,
-       struct pg_block_update *update_state, bool power_on)
-{
-       int i = 0;
-       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
-
-       if (!pg_cntl)
-               return;
-       if (dc->debug.ignore_pg)
-               return;
-       if (update_state->pg_res_update[PG_HPO]) {
-               if (pg_cntl->funcs->hpo_pg_control)
-                       pg_cntl->funcs->hpo_pg_control(pg_cntl, power_on);
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
-                       update_state->pg_pipe_res_update[PG_DPP][i]) {
-                       if (pg_cntl->funcs->hubp_dpp_pg_control)
-                               pg_cntl->funcs->hubp_dpp_pg_control(pg_cntl, i, power_on);
-               }
-
-               if (update_state->pg_pipe_res_update[PG_DSC][i]) {
-                       if (pg_cntl->funcs->dsc_pg_control)
-                               pg_cntl->funcs->dsc_pg_control(pg_cntl, i, power_on);
-               }
-
-               if (update_state->pg_pipe_res_update[PG_MPCC][i]) {
-                       if (pg_cntl->funcs->mpcc_pg_control)
-                               pg_cntl->funcs->mpcc_pg_control(pg_cntl, i, power_on);
-               }
-
-               if (update_state->pg_pipe_res_update[PG_OPP][i]) {
-                       if (pg_cntl->funcs->opp_pg_control)
-                               pg_cntl->funcs->opp_pg_control(pg_cntl, i, power_on);
-               }
-
-               if (update_state->pg_pipe_res_update[PG_OPTC][i]) {
-                       if (pg_cntl->funcs->optc_pg_control)
-                               pg_cntl->funcs->optc_pg_control(pg_cntl, i, power_on);
-               }
-       }
-
-       if (update_state->pg_res_update[PG_DWB]) {
-               if (pg_cntl->funcs->dwb_pg_control)
-                       pg_cntl->funcs->dwb_pg_control(pg_cntl, power_on);
-       }
-
-       if (pg_cntl->funcs->plane_otg_pg_control)
-               pg_cntl->funcs->plane_otg_pg_control(pg_cntl, power_on);
-}
-
-void dcn35_root_clock_control(struct dc *dc,
-       struct pg_block_update *update_state, bool power_on)
-{
-       int i = 0;
-       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
-
-       if (!pg_cntl)
-               return;
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
-                       update_state->pg_pipe_res_update[PG_DPP][i]) {
-                       if (dc->hwseq->funcs.dpp_root_clock_control)
-                               dc->hwseq->funcs.dpp_root_clock_control(dc->hwseq, i, power_on);
-               }
-
-               if (update_state->pg_pipe_res_update[PG_DSC][i]) {
-                       if (power_on) {
-                               if (dc->res_pool->dccg->funcs->enable_dsc)
-                                       dc->res_pool->dccg->funcs->enable_dsc(dc->res_pool->dccg, i);
-                       } else {
-                               if (dc->res_pool->dccg->funcs->disable_dsc)
-                                       dc->res_pool->dccg->funcs->disable_dsc(dc->res_pool->dccg, i);
-                       }
-               }
-       }
-}
-
-void dcn35_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct pg_block_update pg_update_state;
-
-       if (dc->hwss.calc_blocks_to_ungate) {
-               dc->hwss.calc_blocks_to_ungate(dc, context, &pg_update_state);
-
-               if (dc->hwss.root_clock_control)
-                       dc->hwss.root_clock_control(dc, &pg_update_state, true);
-
-               if (dc->hwss.block_power_control)
-                       dc->hwss.block_power_control(dc, &pg_update_state, true);
-       }
-
-       dcn20_prepare_bandwidth(dc, context);
-}
-
-void dcn35_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context)
-{
-       struct pg_block_update pg_update_state;
-
-       dcn20_optimize_bandwidth(dc, context);
-
-       if (dc->hwss.calc_blocks_to_gate) {
-               dc->hwss.calc_blocks_to_gate(dc, context, &pg_update_state);
-
-               if (dc->hwss.block_power_control)
-                       dc->hwss.block_power_control(dc, &pg_update_state, false);
-
-               if (dc->hwss.root_clock_control)
-                       dc->hwss.root_clock_control(dc, &pg_update_state, false);
-       }
-}
-
-void dcn35_set_idle_state(const struct dc *dc, bool allow_idle)
-{
-       // TODO: Find a more suitable communcation
-       if (dc->clk_mgr->funcs->set_idle_state)
-               dc->clk_mgr->funcs->set_idle_state(dc->clk_mgr, allow_idle);
-}
-
-uint32_t dcn35_get_idle_state(const struct dc *dc)
-{
-       // TODO: Find a more suitable communcation
-       if (dc->clk_mgr->funcs->get_idle_state)
-               return dc->clk_mgr->funcs->get_idle_state(dc->clk_mgr);
-
-       return 0;
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.h
deleted file mode 100644 (file)
index 14bbdb0..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright 2023 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.
- *
- */
-
-#ifndef __DC_HWSS_DCN35_H__
-#define __DC_HWSS_DCN35_H__
-
-#include "hw_sequencer_private.h"
-
-struct dc;
-
-void dcn35_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
-
-void dcn35_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
-
-void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
-
-void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
-
-void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable);
-
-void dcn35_init_hw(struct dc *dc);
-
-void dcn35_disable_link_output(struct dc_link *link,
-               const struct link_resource *link_res,
-               enum signal_type signal);
-
-void dcn35_power_down_on_boot(struct dc *dc);
-
-bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable);
-
-void dcn35_z10_restore(const struct dc *dc);
-
-void dcn35_init_pipes(struct dc *dc, struct dc_state *context);
-void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                              struct dc_state *context);
-void dcn35_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
-
-void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
-       struct pg_block_update *update_state);
-void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
-       struct pg_block_update *update_state);
-void dcn35_block_power_control(struct dc *dc,
-       struct pg_block_update *update_state, bool power_on);
-void dcn35_root_clock_control(struct dc *dc,
-       struct pg_block_update *update_state, bool power_on);
-
-void dcn35_prepare_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-
-void dcn35_optimize_bandwidth(
-               struct dc *dc,
-               struct dc_state *context);
-
-void dcn35_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
-void dcn35_dsc_pg_control(
-               struct dce_hwseq *hws,
-               unsigned int dsc_inst,
-               bool power_on);
-
-void dcn35_set_idle_state(const struct dc *dc, bool allow_idle);
-uint32_t dcn35_get_idle_state(const struct dc *dc);
-#endif /* __DC_HWSS_DCN35_H__ */
index ae828d5..534223d 100644 (file)
@@ -22,8 +22,8 @@
  *
  */
 
-#include "dce110/dce110_hw_sequencer.h"
-#include "dcn10/dcn10_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn10/dcn10_hwseq.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn21/dcn21_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
index afc1425..99d55b9 100644 (file)
@@ -49,7 +49,7 @@
 #include "dcn35/dcn35_optc.h"
 #include "dcn20/dcn20_hwseq.h"
 #include "dcn30/dcn30_hwseq.h"
-#include "dce110/dce110_hw_sequencer.h"
+#include "dce110/dce110_hwseq.h"
 #include "dcn35/dcn35_opp.h"
 #include "dcn35/dcn35_dsc.h"
 #include "dcn30/dcn30_vpg.h"
@@ -75,7 +75,7 @@
 #include "dcn35/dcn35_pg_cntl.h"
 #include "dcn10/dcn10_resource.h"
 #include "dcn31/dcn31_panel_cntl.h"
-#include "dcn35_hwseq.h"
+#include "dcn35/dcn35_hwseq.h"
 #include "dcn35_dio_link_encoder.h"
 #include "dml/dcn31/dcn31_fpu.h" /*todo*/
 #include "dml/dcn35/dcn35_fpu.h"
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/Makefile b/drivers/gpu/drm/amd/display/dc/hwss/Makefile
new file mode 100644 (file)
index 0000000..bccd46b
--- /dev/null
@@ -0,0 +1,183 @@
+
+# Copyright 2022 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.
+#
+# Makefile for the 'hwss' sub-component of DAL.
+#
+
+
+###############################################################################
+#  DCE
+###############################################################################
+
+HWSS_DCE = dce_hwseq.o
+
+AMD_DAL_HWSS_DCE = $(addprefix $(AMDDALPATH)/dc/hwss/dce/,$(HWSS_DCE))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCE)
+
+###############################################################################
+
+HWSS_DCE100 = dce100_hwseq.o
+
+AMD_DAL_HWSS_DCE100 = $(addprefix $(AMDDALPATH)/dc/hwss/dce100/,$(HWSS_DCE100))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCE100)
+
+###############################################################################
+
+HWSS_DCE110 = dce110_hwseq.o
+
+AMD_DAL_HWSS_DCE110 = $(addprefix $(AMDDALPATH)/dc/hwss/dce110/,$(HWSS_DCE110))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCE110)
+
+###############################################################################
+
+HWSS_DCE112 = dce112_hwseq.o
+
+AMD_DAL_HWSS_DCE112 = $(addprefix $(AMDDALPATH)/dc/hwss/dce112/,$(HWSS_DCE112))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCE112)
+
+###############################################################################
+
+HWSS_DCE120 = dce120_hwseq.o
+
+AMD_DAL_HWSS_DCE120 = $(addprefix $(AMDDALPATH)/dc/hwss/dce120/,$(HWSS_DCE120))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCE120)
+
+###############################################################################
+
+HWSS_DCE80 = dce80_hwseq.o
+
+AMD_DAL_HWSS_DCE80 = $(addprefix $(AMDDALPATH)/dc/hwss/dce80/,$(HWSS_DCE80))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCE80)
+
+ifdef CONFIG_DRM_AMD_DC_FP
+###############################################################################
+# DCN
+###############################################################################
+
+HWSS_DCN10 = dcn10_hwseq.o
+
+AMD_DAL_HWSS_DCN10 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn10/,$(HWSS_DCN10))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN10)
+
+###############################################################################
+
+HWSS_DCN20 = dcn20_hwseq.o
+
+AMD_DAL_HWSS_DCN20 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn20/,$(HWSS_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN20)
+
+###############################################################################
+
+HWSS_DCN201 = dcn201_hwseq.o
+
+AMD_DAL_HWSS_DCN201 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn201/,$(HWSS_DCN201))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN201)
+
+###############################################################################
+
+HWSS_DCN21 = dcn21_hwseq.o
+
+AMD_DAL_HWSS_DCN21 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn21/,$(HWSS_DCN21))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN21)
+
+###############################################################################
+
+###############################################################################
+
+###############################################################################
+
+HWSS_DCN30 = dcn30_hwseq.o
+
+AMD_DAL_HWSS_DCN30 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn30/,$(HWSS_DCN30))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN30)
+
+###############################################################################
+
+HWSS_DCN301 = dcn301_hwseq.o
+
+AMD_DAL_HWSS_DCN301 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn301/,$(HWSS_DCN301))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN301)
+
+###############################################################################
+
+HWSS_DCN302 = dcn302_hwseq.o
+
+AMD_DAL_HWSS_DCN302 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn302/,$(HWSS_DCN302))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN302)
+
+###############################################################################
+
+HWSS_DCN303 = dcn303_hwseq.o
+
+AMD_DAL_HWSS_DCN303 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn303/,$(HWSS_DCN303))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN303)
+
+###############################################################################
+
+HWSS_DCN31 = dcn31_hwseq.o
+
+AMD_DAL_HWSS_DCN31 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn31/,$(HWSS_DCN31))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN31)
+
+###############################################################################
+
+HWSS_DCN314 = dcn314_hwseq.o
+
+AMD_DAL_HWSS_DCN314 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn314/,$(HWSS_DCN314))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN314)
+
+###############################################################################
+
+HWSS_DCN32 = dcn32_hwseq.o
+
+AMD_DAL_HWSS_DCN32 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn32/,$(HWSS_DCN32))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN32)
+
+###############################################################################
+
+HWSS_DCN35 = dcn35_hwseq.o
+
+AMD_DAL_HWSS_DCN35 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn35/,$(HWSS_DCN35))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN35)
+
+###############################################################################
+
+###############################################################################
+
+endif
\ No newline at end of file
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c
new file mode 100644 (file)
index 0000000..4202fad
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * 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"
+#include "hw_sequencer_private.h"
+#include "core_types.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);
+}
+
+void dce_pipe_control_lock(struct dc *dc,
+               struct pipe_ctx *pipe,
+               bool lock)
+{
+       uint32_t lock_val = lock ? 1 : 0;
+       uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* Not lock pipe when blank */
+       if (lock && pipe->stream_res.tg->funcs->is_blanked &&
+           pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
+               return;
+
+       val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
+                       BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
+                       BLND_SCL_V_UPDATE_LOCK, &scl,
+                       BLND_BLND_V_UPDATE_LOCK, &blnd,
+                       BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
+
+       dcp_grph = lock_val;
+       scl = lock_val;
+       blnd = lock_val;
+       update_lock_mode = lock_val;
+
+       REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
+                       BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
+                       BLND_SCL_V_UPDATE_LOCK, scl);
+
+       if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
+               REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
+                               BLND_BLND_V_UPDATE_LOCK, blnd,
+                               BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
+
+       if (hws->wa.blnd_crtc_trigger) {
+               if (!lock) {
+                       uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
+                       REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
+               }
+       }
+}
+
+#if defined(CONFIG_DRM_AMD_DC_SI)
+void dce60_pipe_control_lock(struct dc *dc,
+               struct pipe_ctx *pipe,
+               bool lock)
+{
+       /* DCE6 has no BLND_V_UPDATE_LOCK register */
+}
+#endif
+
+void dce_set_blender_mode(struct dce_hwseq *hws,
+       unsigned int blnd_inst,
+       enum blnd_mode mode)
+{
+       uint32_t feedthrough = 1;
+       uint32_t blnd_mode = 0;
+       uint32_t multiplied_mode = 0;
+       uint32_t alpha_mode = 2;
+
+       switch (mode) {
+       case BLND_MODE_OTHER_PIPE:
+               feedthrough = 0;
+               blnd_mode = 1;
+               alpha_mode = 0;
+               break;
+       case BLND_MODE_BLENDING:
+               feedthrough = 0;
+               blnd_mode = 2;
+               alpha_mode = 0;
+               multiplied_mode = 1;
+               break;
+       case BLND_MODE_CURRENT_PIPE:
+       default:
+               if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
+                               blnd_inst == 0)
+                       feedthrough = 0;
+               break;
+       }
+
+       REG_UPDATE(BLND_CONTROL[blnd_inst],
+               BLND_MODE, blnd_mode);
+
+       if (hws->masks->BLND_ALPHA_MODE != 0) {
+               REG_UPDATE_3(BLND_CONTROL[blnd_inst],
+                       BLND_FEEDTHROUGH_EN, feedthrough,
+                       BLND_ALPHA_MODE, alpha_mode,
+                       BLND_MULTIPLIED_MODE, multiplied_mode);
+       }
+}
+
+
+static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
+{
+       if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
+               REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
+                               DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
+}
+
+static void dce_underlay_clock_enable(struct dce_hwseq *hws)
+{
+       /* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
+       if (REG(DCFEV_CLOCK_CONTROL))
+               REG_UPDATE(DCFEV_CLOCK_CONTROL,
+                               DCFEV_CLOCK_ENABLE, 1);
+}
+
+static void enable_hw_base_light_sleep(void)
+{
+       /* TODO: implement */
+}
+
+static void disable_sw_manual_control_light_sleep(void)
+{
+       /* TODO: implement */
+}
+
+void dce_clock_gating_power_up(struct dce_hwseq *hws,
+               bool enable)
+{
+       if (enable) {
+               enable_hw_base_light_sleep();
+               disable_sw_manual_control_light_sleep();
+       } else {
+               dce_disable_sram_shut_down(hws);
+               dce_underlay_clock_enable(hws);
+       }
+}
+
+void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
+               struct clock_source *clk_src,
+               unsigned int tg_inst)
+{
+       if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO || clk_src->dp_clk_src) {
+               REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
+                               DP_DTO0_ENABLE, 1);
+
+       } else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
+               uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
+
+               REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
+                               PHYPLL_PIXEL_RATE_SOURCE, rate_source,
+                               PIXEL_RATE_PLL_SOURCE, 0);
+
+               REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
+                               DP_DTO0_ENABLE, 0);
+
+       } else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
+               uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
+
+               REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
+                               PIXEL_RATE_SOURCE, rate_source,
+                               DP_DTO0_ENABLE, 0);
+
+               if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
+                       REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
+                                       PIXEL_RATE_PLL_SOURCE, 1);
+       } else {
+               DC_ERR("Unknown clock source. clk_src id: %d, TG_inst: %d",
+                      clk_src->id, tg_inst);
+       }
+}
+
+/* Only use LUT for 8 bit formats */
+bool dce_use_lut(enum surface_pixel_format format)
+{
+       switch (format) {
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
+               return true;
+       default:
+               return false;
+       }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h
new file mode 100644 (file)
index 0000000..2fefdf4
--- /dev/null
@@ -0,0 +1,1241 @@
+/*
+ * 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 "dc_types.h"
+
+#define HWSEQ_DCEF_REG_LIST_DCE8() \
+       .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_DCEF_REG_LIST() \
+       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), \
+       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL)
+
+#define HWSEQ_BLND_REG_LIST() \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 0), \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 1), \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 2), \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 3), \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 4), \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 5), \
+       SRII(BLND_CONTROL, BLND, 0), \
+       SRII(BLND_CONTROL, BLND, 1), \
+       SRII(BLND_CONTROL, BLND, 2), \
+       SRII(BLND_CONTROL, BLND, 3), \
+       SRII(BLND_CONTROL, BLND, 4), \
+       SRII(BLND_CONTROL, BLND, 5)
+
+#define HSWEQ_DCN_PIXEL_RATE_REG_LIST(blk, inst) \
+       SRII(PIXEL_RATE_CNTL, blk, inst), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, inst)
+
+#define HWSEQ_PIXEL_RATE_REG_LIST(blk) \
+       SRII(PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PIXEL_RATE_CNTL, blk, 1), \
+       SRII(PIXEL_RATE_CNTL, blk, 2), \
+       SRII(PIXEL_RATE_CNTL, blk, 3), \
+       SRII(PIXEL_RATE_CNTL, blk, 4), \
+       SRII(PIXEL_RATE_CNTL, blk, 5)
+
+#define HWSEQ_PIXEL_RATE_REG_LIST_201(blk) \
+       SRII(PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PIXEL_RATE_CNTL, blk, 1)
+
+#define HWSEQ_PHYPLL_REG_LIST(blk) \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5)
+
+#define HWSEQ_PIXEL_RATE_REG_LIST_3(blk) \
+       SRII(PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PIXEL_RATE_CNTL, blk, 1),\
+       SRII(PIXEL_RATE_CNTL, blk, 2),\
+       SRII(PIXEL_RATE_CNTL, blk, 3), \
+       SRII(PIXEL_RATE_CNTL, blk, 4), \
+       SRII(PIXEL_RATE_CNTL, blk, 5)
+
+#define HWSEQ_PHYPLL_REG_LIST_3(blk) \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5)
+
+#define HWSEQ_PIXEL_RATE_REG_LIST_302(blk) \
+       SRII(PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PIXEL_RATE_CNTL, blk, 1),\
+       SRII(PIXEL_RATE_CNTL, blk, 2),\
+       SRII(PIXEL_RATE_CNTL, blk, 3), \
+       SRII(PIXEL_RATE_CNTL, blk, 4)
+
+#define HWSEQ_PHYPLL_REG_LIST_302(blk) \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4)
+
+#define HWSEQ_PIXEL_RATE_REG_LIST_303(blk) \
+       SRII(PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PIXEL_RATE_CNTL, blk, 1)
+
+#define HWSEQ_PHYPLL_REG_LIST_303(blk) \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1)
+
+
+#define HWSEQ_PHYPLL_REG_LIST_201(blk) \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
+       SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1)
+
+#define HWSEQ_DCE11_REG_LIST_BASE() \
+       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
+       SR(DCFEV_CLOCK_CONTROL), \
+       SRII(DCFE_CLOCK_CONTROL, DCFE, 0), \
+       SRII(DCFE_CLOCK_CONTROL, DCFE, 1), \
+       SRII(CRTC_H_BLANK_START_END, CRTC, 0),\
+       SRII(CRTC_H_BLANK_START_END, CRTC, 1),\
+       SRII(BLND_V_UPDATE_LOCK, BLND, 0),\
+       SRII(BLND_V_UPDATE_LOCK, BLND, 1),\
+       SRII(BLND_CONTROL, BLND, 0),\
+       SRII(BLND_CONTROL, BLND, 1),\
+       SR(BLNDV_CONTROL),\
+       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+
+#if defined(CONFIG_DRM_AMD_DC_SI)
+#define HWSEQ_DCE6_REG_LIST() \
+       HWSEQ_DCEF_REG_LIST_DCE8(), \
+       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+#endif
+
+#define HWSEQ_DCE8_REG_LIST() \
+       HWSEQ_DCEF_REG_LIST_DCE8(), \
+       HWSEQ_BLND_REG_LIST(), \
+       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+
+#define HWSEQ_DCE10_REG_LIST() \
+       HWSEQ_DCEF_REG_LIST(), \
+       HWSEQ_BLND_REG_LIST(), \
+       HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+
+#define HWSEQ_ST_REG_LIST() \
+       HWSEQ_DCE11_REG_LIST_BASE(), \
+       .DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
+       .CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
+       .BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
+       .BLND_CONTROL[2] = mmBLNDV_CONTROL
+
+#define HWSEQ_CZ_REG_LIST() \
+       HWSEQ_DCE11_REG_LIST_BASE(), \
+       SRII(DCFE_CLOCK_CONTROL, DCFE, 2), \
+       SRII(CRTC_H_BLANK_START_END, CRTC, 2), \
+       SRII(BLND_V_UPDATE_LOCK, BLND, 2), \
+       SRII(BLND_CONTROL, BLND, 2), \
+       .DCFE_CLOCK_CONTROL[3] = mmDCFEV_CLOCK_CONTROL, \
+       .CRTC_H_BLANK_START_END[3] = mmCRTCV_H_BLANK_START_END, \
+       .BLND_V_UPDATE_LOCK[3] = mmBLNDV_V_UPDATE_LOCK, \
+       .BLND_CONTROL[3] = mmBLNDV_CONTROL
+
+#define HWSEQ_DCE120_REG_LIST() \
+       HWSEQ_DCE10_REG_LIST(), \
+       HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
+       HWSEQ_PHYPLL_REG_LIST(CRTC), \
+       SR(DCHUB_FB_LOCATION),\
+       SR(DCHUB_AGP_BASE),\
+       SR(DCHUB_AGP_BOT),\
+       SR(DCHUB_AGP_TOP)
+
+#define HWSEQ_VG20_REG_LIST() \
+       HWSEQ_DCE120_REG_LIST(),\
+       MMHUB_SR(MC_VM_XGMI_LFB_CNTL)
+
+#define HWSEQ_DCE112_REG_LIST() \
+       HWSEQ_DCE10_REG_LIST(), \
+       HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
+       HWSEQ_PHYPLL_REG_LIST(CRTC)
+
+#define HWSEQ_DCN_REG_LIST()\
+       SR(REFCLK_CNTL), \
+       SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
+       SR(DIO_MEM_PWR_CTRL), \
+       SR(DCCG_GATE_DISABLE_CNTL), \
+       SR(DCCG_GATE_DISABLE_CNTL2), \
+       SR(DCFCLK_CNTL),\
+       SR(DCFCLK_CNTL), \
+       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL)
+
+
+#define MMHUB_DCN_REG_LIST()\
+       /* todo:  get these from GVM instead of reading registers ourselves */\
+       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
+       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
+       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32),\
+       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32),\
+       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32),\
+       MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32),\
+       MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32),\
+       MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32),\
+       MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB),\
+       MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB),\
+       MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
+       MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
+
+
+#define HWSEQ_DCN1_REG_LIST()\
+       HWSEQ_DCN_REG_LIST(), \
+       MMHUB_DCN_REG_LIST(), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
+       SR(DCHUBBUB_SDPIF_FB_BASE),\
+       SR(DCHUBBUB_SDPIF_FB_OFFSET),\
+       SR(DCHUBBUB_SDPIF_AGP_BASE),\
+       SR(DCHUBBUB_SDPIF_AGP_BOT),\
+       SR(DCHUBBUB_SDPIF_AGP_TOP),\
+       SR(DOMAIN0_PG_CONFIG), \
+       SR(DOMAIN1_PG_CONFIG), \
+       SR(DOMAIN2_PG_CONFIG), \
+       SR(DOMAIN3_PG_CONFIG), \
+       SR(DOMAIN4_PG_CONFIG), \
+       SR(DOMAIN5_PG_CONFIG), \
+       SR(DOMAIN6_PG_CONFIG), \
+       SR(DOMAIN7_PG_CONFIG), \
+       SR(DOMAIN0_PG_STATUS), \
+       SR(DOMAIN1_PG_STATUS), \
+       SR(DOMAIN2_PG_STATUS), \
+       SR(DOMAIN3_PG_STATUS), \
+       SR(DOMAIN4_PG_STATUS), \
+       SR(DOMAIN5_PG_STATUS), \
+       SR(DOMAIN6_PG_STATUS), \
+       SR(DOMAIN7_PG_STATUS), \
+       SR(D1VGA_CONTROL), \
+       SR(D2VGA_CONTROL), \
+       SR(D3VGA_CONTROL), \
+       SR(D4VGA_CONTROL), \
+       SR(VGA_TEST_CONTROL), \
+       SR(DC_IP_REQUEST_CNTL)
+
+#define HWSEQ_DCN2_REG_LIST()\
+       HWSEQ_DCN_REG_LIST(), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 4), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 5), \
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(DOMAIN0_PG_CONFIG), \
+       SR(DOMAIN1_PG_CONFIG), \
+       SR(DOMAIN2_PG_CONFIG), \
+       SR(DOMAIN3_PG_CONFIG), \
+       SR(DOMAIN4_PG_CONFIG), \
+       SR(DOMAIN5_PG_CONFIG), \
+       SR(DOMAIN6_PG_CONFIG), \
+       SR(DOMAIN7_PG_CONFIG), \
+       SR(DOMAIN8_PG_CONFIG), \
+       SR(DOMAIN9_PG_CONFIG), \
+/*     SR(DOMAIN10_PG_CONFIG), Navi1x HUBP5 not powergate-able*/\
+/*     SR(DOMAIN11_PG_CONFIG), Navi1x DPP5 is not powergate-able */\
+       SR(DOMAIN16_PG_CONFIG), \
+       SR(DOMAIN17_PG_CONFIG), \
+       SR(DOMAIN18_PG_CONFIG), \
+       SR(DOMAIN19_PG_CONFIG), \
+       SR(DOMAIN20_PG_CONFIG), \
+       SR(DOMAIN21_PG_CONFIG), \
+       SR(DOMAIN0_PG_STATUS), \
+       SR(DOMAIN1_PG_STATUS), \
+       SR(DOMAIN2_PG_STATUS), \
+       SR(DOMAIN3_PG_STATUS), \
+       SR(DOMAIN4_PG_STATUS), \
+       SR(DOMAIN5_PG_STATUS), \
+       SR(DOMAIN6_PG_STATUS), \
+       SR(DOMAIN7_PG_STATUS), \
+       SR(DOMAIN8_PG_STATUS), \
+       SR(DOMAIN9_PG_STATUS), \
+       SR(DOMAIN10_PG_STATUS), \
+       SR(DOMAIN11_PG_STATUS), \
+       SR(DOMAIN16_PG_STATUS), \
+       SR(DOMAIN17_PG_STATUS), \
+       SR(DOMAIN18_PG_STATUS), \
+       SR(DOMAIN19_PG_STATUS), \
+       SR(DOMAIN20_PG_STATUS), \
+       SR(DOMAIN21_PG_STATUS), \
+       SR(D1VGA_CONTROL), \
+       SR(D2VGA_CONTROL), \
+       SR(D3VGA_CONTROL), \
+       SR(D4VGA_CONTROL), \
+       SR(D5VGA_CONTROL), \
+       SR(D6VGA_CONTROL), \
+       SR(DC_IP_REQUEST_CNTL)
+
+#define HWSEQ_DCN21_REG_LIST()\
+       HWSEQ_DCN_REG_LIST(), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
+       MMHUB_DCN_REG_LIST(), \
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(DOMAIN0_PG_CONFIG), \
+       SR(DOMAIN1_PG_CONFIG), \
+       SR(DOMAIN2_PG_CONFIG), \
+       SR(DOMAIN3_PG_CONFIG), \
+       SR(DOMAIN4_PG_CONFIG), \
+       SR(DOMAIN5_PG_CONFIG), \
+       SR(DOMAIN6_PG_CONFIG), \
+       SR(DOMAIN7_PG_CONFIG), \
+       SR(DOMAIN16_PG_CONFIG), \
+       SR(DOMAIN17_PG_CONFIG), \
+       SR(DOMAIN18_PG_CONFIG), \
+       SR(DOMAIN0_PG_STATUS), \
+       SR(DOMAIN1_PG_STATUS), \
+       SR(DOMAIN2_PG_STATUS), \
+       SR(DOMAIN3_PG_STATUS), \
+       SR(DOMAIN4_PG_STATUS), \
+       SR(DOMAIN5_PG_STATUS), \
+       SR(DOMAIN6_PG_STATUS), \
+       SR(DOMAIN7_PG_STATUS), \
+       SR(DOMAIN16_PG_STATUS), \
+       SR(DOMAIN17_PG_STATUS), \
+       SR(DOMAIN18_PG_STATUS), \
+       SR(D1VGA_CONTROL), \
+       SR(D2VGA_CONTROL), \
+       SR(D3VGA_CONTROL), \
+       SR(D4VGA_CONTROL), \
+       SR(D5VGA_CONTROL), \
+       SR(D6VGA_CONTROL), \
+       SR(DC_IP_REQUEST_CNTL)
+
+#define HWSEQ_DCN201_REG_LIST()\
+       HWSEQ_DCN_REG_LIST(), \
+       HWSEQ_PIXEL_RATE_REG_LIST_201(OTG), \
+       HWSEQ_PHYPLL_REG_LIST_201(OTG), \
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(AZALIA_AUDIO_DTO), \
+       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
+       MMHUB_SR(MC_VM_FB_LOCATION_BASE), \
+       MMHUB_SR(MC_VM_FB_LOCATION_TOP), \
+       MMHUB_SR(MC_VM_FB_OFFSET)
+
+#define HWSEQ_DCN30_REG_LIST()\
+       HWSEQ_DCN2_REG_LIST(),\
+       HWSEQ_DCN_REG_LIST(), \
+       HWSEQ_PIXEL_RATE_REG_LIST_3(OTG), \
+       HWSEQ_PHYPLL_REG_LIST_3(OTG), \
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(AZALIA_AUDIO_DTO), \
+       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
+       SR(HPO_TOP_CLOCK_CONTROL), \
+       SR(ODM_MEM_PWR_CTRL3), \
+       SR(DMU_MEM_PWR_CNTL), \
+       SR(MMHUBBUB_MEM_PWR_CNTL)
+
+#define HWSEQ_DCN301_REG_LIST()\
+       SR(REFCLK_CNTL), \
+       SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
+       SR(DIO_MEM_PWR_CTRL), \
+       SR(DCCG_GATE_DISABLE_CNTL), \
+       SR(DCCG_GATE_DISABLE_CNTL2), \
+       SR(DCFCLK_CNTL),\
+       SR(DCFCLK_CNTL), \
+       SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
+       SRII(PIXEL_RATE_CNTL, OTG, 0), \
+       SRII(PIXEL_RATE_CNTL, OTG, 1),\
+       SRII(PIXEL_RATE_CNTL, OTG, 2),\
+       SRII(PIXEL_RATE_CNTL, OTG, 3),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
+       SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(DOMAIN0_PG_CONFIG), \
+       SR(DOMAIN1_PG_CONFIG), \
+       SR(DOMAIN2_PG_CONFIG), \
+       SR(DOMAIN3_PG_CONFIG), \
+       SR(DOMAIN4_PG_CONFIG), \
+       SR(DOMAIN5_PG_CONFIG), \
+       SR(DOMAIN6_PG_CONFIG), \
+       SR(DOMAIN7_PG_CONFIG), \
+       SR(DOMAIN16_PG_CONFIG), \
+       SR(DOMAIN17_PG_CONFIG), \
+       SR(DOMAIN18_PG_CONFIG), \
+       SR(DOMAIN0_PG_STATUS), \
+       SR(DOMAIN1_PG_STATUS), \
+       SR(DOMAIN2_PG_STATUS), \
+       SR(DOMAIN3_PG_STATUS), \
+       SR(DOMAIN4_PG_STATUS), \
+       SR(DOMAIN5_PG_STATUS), \
+       SR(DOMAIN6_PG_STATUS), \
+       SR(DOMAIN7_PG_STATUS), \
+       SR(DOMAIN16_PG_STATUS), \
+       SR(DOMAIN17_PG_STATUS), \
+       SR(DOMAIN18_PG_STATUS), \
+       SR(D1VGA_CONTROL), \
+       SR(D2VGA_CONTROL), \
+       SR(D3VGA_CONTROL), \
+       SR(D4VGA_CONTROL), \
+       SR(D5VGA_CONTROL), \
+       SR(D6VGA_CONTROL), \
+       SR(DC_IP_REQUEST_CNTL), \
+       SR(AZALIA_AUDIO_DTO), \
+       SR(AZALIA_CONTROLLER_CLOCK_GATING)
+
+#define HWSEQ_DCN302_REG_LIST()\
+       HWSEQ_DCN_REG_LIST(), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 4), \
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(DOMAIN0_PG_CONFIG), \
+       SR(DOMAIN1_PG_CONFIG), \
+       SR(DOMAIN2_PG_CONFIG), \
+       SR(DOMAIN3_PG_CONFIG), \
+       SR(DOMAIN4_PG_CONFIG), \
+       SR(DOMAIN5_PG_CONFIG), \
+       SR(DOMAIN6_PG_CONFIG), \
+       SR(DOMAIN7_PG_CONFIG), \
+       SR(DOMAIN8_PG_CONFIG), \
+       SR(DOMAIN9_PG_CONFIG), \
+       SR(DOMAIN16_PG_CONFIG), \
+       SR(DOMAIN17_PG_CONFIG), \
+       SR(DOMAIN18_PG_CONFIG), \
+       SR(DOMAIN19_PG_CONFIG), \
+       SR(DOMAIN20_PG_CONFIG), \
+       SR(DOMAIN0_PG_STATUS), \
+       SR(DOMAIN1_PG_STATUS), \
+       SR(DOMAIN2_PG_STATUS), \
+       SR(DOMAIN3_PG_STATUS), \
+       SR(DOMAIN4_PG_STATUS), \
+       SR(DOMAIN5_PG_STATUS), \
+       SR(DOMAIN6_PG_STATUS), \
+       SR(DOMAIN7_PG_STATUS), \
+       SR(DOMAIN8_PG_STATUS), \
+       SR(DOMAIN9_PG_STATUS), \
+       SR(DOMAIN16_PG_STATUS), \
+       SR(DOMAIN17_PG_STATUS), \
+       SR(DOMAIN18_PG_STATUS), \
+       SR(DOMAIN19_PG_STATUS), \
+       SR(DOMAIN20_PG_STATUS), \
+       SR(D1VGA_CONTROL), \
+       SR(D2VGA_CONTROL), \
+       SR(D3VGA_CONTROL), \
+       SR(D4VGA_CONTROL), \
+       SR(D5VGA_CONTROL), \
+       SR(D6VGA_CONTROL), \
+       SR(DC_IP_REQUEST_CNTL), \
+       HWSEQ_PIXEL_RATE_REG_LIST_302(OTG), \
+       HWSEQ_PHYPLL_REG_LIST_302(OTG), \
+       SR(AZALIA_AUDIO_DTO), \
+       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
+       SR(HPO_TOP_CLOCK_CONTROL)
+
+#define HWSEQ_DCN303_REG_LIST() \
+       HWSEQ_DCN_REG_LIST(), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
+       HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
+       SR(MICROSECOND_TIME_BASE_DIV), \
+       SR(MILLISECOND_TIME_BASE_DIV), \
+       SR(DISPCLK_FREQ_CHANGE_CNTL), \
+       SR(RBBMIF_TIMEOUT_DIS), \
+       SR(RBBMIF_TIMEOUT_DIS_2), \
+       SR(DCHUBBUB_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_CTRL), \
+       SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+       SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+       SR(MPC_CRC_CTRL), \
+       SR(MPC_CRC_RESULT_GB), \
+       SR(MPC_CRC_RESULT_C), \
+       SR(MPC_CRC_RESULT_AR), \
+       SR(D1VGA_CONTROL), \
+       SR(D2VGA_CONTROL), \
+       SR(D3VGA_CONTROL), \
+       SR(D4VGA_CONTROL), \
+       SR(D5VGA_CONTROL), \
+       SR(D6VGA_CONTROL), \
+       HWSEQ_PIXEL_RATE_REG_LIST_303(OTG), \
+       HWSEQ_PHYPLL_REG_LIST_303(OTG), \
+       SR(AZALIA_AUDIO_DTO), \
+       SR(AZALIA_CONTROLLER_CLOCK_GATING), \
+       SR(HPO_TOP_CLOCK_CONTROL)
+
+struct dce_hwseq_registers {
+       uint32_t DCFE_CLOCK_CONTROL[6];
+       uint32_t DCFEV_CLOCK_CONTROL;
+       uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
+       uint32_t BLND_V_UPDATE_LOCK[6];
+       uint32_t BLND_CONTROL[6];
+       uint32_t BLNDV_CONTROL;
+       uint32_t CRTC_H_BLANK_START_END[6];
+       uint32_t PIXEL_RATE_CNTL[6];
+       uint32_t PHYPLL_PIXEL_RATE_CNTL[6];
+       /*DCHUB*/
+       uint32_t DCHUB_FB_LOCATION;
+       uint32_t DCHUB_AGP_BASE;
+       uint32_t DCHUB_AGP_BOT;
+       uint32_t DCHUB_AGP_TOP;
+
+       uint32_t REFCLK_CNTL;
+
+       uint32_t DCHUBBUB_GLOBAL_TIMER_CNTL;
+       uint32_t DCHUBBUB_SDPIF_FB_BASE;
+       uint32_t DCHUBBUB_SDPIF_FB_OFFSET;
+       uint32_t DCHUBBUB_SDPIF_AGP_BASE;
+       uint32_t DCHUBBUB_SDPIF_AGP_BOT;
+       uint32_t DCHUBBUB_SDPIF_AGP_TOP;
+       uint32_t DC_IP_REQUEST_CNTL;
+       uint32_t DOMAIN0_PG_CONFIG;
+       uint32_t DOMAIN1_PG_CONFIG;
+       uint32_t DOMAIN2_PG_CONFIG;
+       uint32_t DOMAIN3_PG_CONFIG;
+       uint32_t DOMAIN4_PG_CONFIG;
+       uint32_t DOMAIN5_PG_CONFIG;
+       uint32_t DOMAIN6_PG_CONFIG;
+       uint32_t DOMAIN7_PG_CONFIG;
+       uint32_t DOMAIN8_PG_CONFIG;
+       uint32_t DOMAIN9_PG_CONFIG;
+       uint32_t DOMAIN10_PG_CONFIG;
+       uint32_t DOMAIN11_PG_CONFIG;
+       uint32_t DOMAIN16_PG_CONFIG;
+       uint32_t DOMAIN17_PG_CONFIG;
+       uint32_t DOMAIN18_PG_CONFIG;
+       uint32_t DOMAIN19_PG_CONFIG;
+       uint32_t DOMAIN20_PG_CONFIG;
+       uint32_t DOMAIN21_PG_CONFIG;
+       uint32_t DOMAIN0_PG_STATUS;
+       uint32_t DOMAIN1_PG_STATUS;
+       uint32_t DOMAIN2_PG_STATUS;
+       uint32_t DOMAIN3_PG_STATUS;
+       uint32_t DOMAIN4_PG_STATUS;
+       uint32_t DOMAIN5_PG_STATUS;
+       uint32_t DOMAIN6_PG_STATUS;
+       uint32_t DOMAIN7_PG_STATUS;
+       uint32_t DOMAIN8_PG_STATUS;
+       uint32_t DOMAIN9_PG_STATUS;
+       uint32_t DOMAIN10_PG_STATUS;
+       uint32_t DOMAIN11_PG_STATUS;
+       uint32_t DOMAIN16_PG_STATUS;
+       uint32_t DOMAIN17_PG_STATUS;
+       uint32_t DOMAIN18_PG_STATUS;
+       uint32_t DOMAIN19_PG_STATUS;
+       uint32_t DOMAIN20_PG_STATUS;
+       uint32_t DOMAIN21_PG_STATUS;
+       uint32_t DIO_MEM_PWR_CTRL;
+       uint32_t DCCG_GATE_DISABLE_CNTL;
+       uint32_t DCCG_GATE_DISABLE_CNTL2;
+       uint32_t DCFCLK_CNTL;
+       uint32_t MICROSECOND_TIME_BASE_DIV;
+       uint32_t MILLISECOND_TIME_BASE_DIV;
+       uint32_t DISPCLK_FREQ_CHANGE_CNTL;
+       uint32_t RBBMIF_TIMEOUT_DIS;
+       uint32_t RBBMIF_TIMEOUT_DIS_2;
+       uint32_t DCHUBBUB_CRC_CTRL;
+       uint32_t DPP_TOP0_DPP_CRC_CTRL;
+       uint32_t DPP_TOP0_DPP_CRC_VAL_R_G;
+       uint32_t DPP_TOP0_DPP_CRC_VAL_B_A;
+       uint32_t MPC_CRC_CTRL;
+       uint32_t MPC_CRC_RESULT_GB;
+       uint32_t MPC_CRC_RESULT_C;
+       uint32_t MPC_CRC_RESULT_AR;
+       uint32_t D1VGA_CONTROL;
+       uint32_t D2VGA_CONTROL;
+       uint32_t D3VGA_CONTROL;
+       uint32_t D4VGA_CONTROL;
+       uint32_t D5VGA_CONTROL;
+       uint32_t D6VGA_CONTROL;
+       uint32_t VGA_TEST_CONTROL;
+       /* MMHUB registers. read only. temporary hack */
+       uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32;
+       uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
+       uint32_t VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32;
+       uint32_t VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32;
+       uint32_t VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32;
+       uint32_t VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32;
+       uint32_t VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32;
+       uint32_t VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32;
+       uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;
+       uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;
+       uint32_t MC_VM_SYSTEM_APERTURE_LOW_ADDR;
+       uint32_t MC_VM_SYSTEM_APERTURE_HIGH_ADDR;
+       uint32_t MC_VM_XGMI_LFB_CNTL;
+       uint32_t AZALIA_AUDIO_DTO;
+       uint32_t AZALIA_CONTROLLER_CLOCK_GATING;
+       /* MMHUB VM */
+       uint32_t MC_VM_FB_LOCATION_BASE;
+       uint32_t MC_VM_FB_LOCATION_TOP;
+       uint32_t MC_VM_FB_OFFSET;
+       uint32_t MMHUBBUB_MEM_PWR_CNTL;
+       uint32_t HPO_TOP_CLOCK_CONTROL;
+       uint32_t ODM_MEM_PWR_CTRL3;
+       uint32_t DMU_MEM_PWR_CNTL;
+       uint32_t DCHUBBUB_ARB_HOSTVM_CNTL;
+       uint32_t HPO_TOP_HW_CONTROL;
+       uint32_t DMU_CLK_CNTL;
+       uint32_t DCCG_GATE_DISABLE_CNTL5;
+};
+ /* set field name */
+#define HWS_SF(blk_name, reg_name, field_name, post_fix)\
+       .field_name = blk_name ## reg_name ## __ ## field_name ## post_fix
+
+#define HWS_SF1(blk_name, reg_name, field_name, post_fix)\
+       .field_name = blk_name ## reg_name ## __ ## blk_name ## field_name ## post_fix
+
+
+#define HWSEQ_DCEF_MASK_SH_LIST(mask_sh, blk)\
+       HWS_SF(blk, CLOCK_CONTROL, DCFE_CLOCK_ENABLE, mask_sh),\
+       SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
+
+#define HWSEQ_BLND_MASK_SH_LIST(mask_sh, blk)\
+       HWS_SF(blk, V_UPDATE_LOCK, BLND_DCP_GRPH_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(blk, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(blk, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(blk, V_UPDATE_LOCK, BLND_BLND_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(blk, V_UPDATE_LOCK, BLND_V_UPDATE_LOCK_MODE, mask_sh),\
+       HWS_SF(blk, CONTROL, BLND_FEEDTHROUGH_EN, mask_sh),\
+       HWS_SF(blk, CONTROL, BLND_ALPHA_MODE, mask_sh),\
+       HWS_SF(blk, CONTROL, BLND_MODE, mask_sh),\
+       HWS_SF(blk, CONTROL, BLND_MULTIPLIED_MODE, mask_sh)
+
+#define HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, blk)\
+       HWS_SF1(blk, PIXEL_RATE_CNTL, PIXEL_RATE_SOURCE, mask_sh),\
+       HWS_SF(blk, PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh)
+
+#define HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, blk)\
+       HWS_SF1(blk, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh),\
+       HWS_SF1(blk, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh)
+
+#if defined(CONFIG_DRM_AMD_DC_SI)
+#define HWSEQ_DCE6_MASK_SH_LIST(mask_sh)\
+       .DCFE_CLOCK_ENABLE = CRTC_DCFE_CLOCK_CONTROL__CRTC_DCFE_CLOCK_ENABLE ## mask_sh, \
+       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
+#endif
+
+#define HWSEQ_DCE8_MASK_SH_LIST(mask_sh)\
+       .DCFE_CLOCK_ENABLE = CRTC_DCFE_CLOCK_CONTROL__CRTC_DCFE_CLOCK_ENABLE ## mask_sh, \
+       HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
+       HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
+       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
+
+#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
+       HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
+       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
+
+#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
+       SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
+       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
+
+#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
+       HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
+
+#define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\
+       SF(DCHUB_FB_LOCATION, FB_TOP, mask_sh),\
+       SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\
+       SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\
+       SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\
+       SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh)
+
+#define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\
+       HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\
+       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\
+       HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\
+       HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)
+
+#define HWSEQ_VG20_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCE12_MASK_SH_LIST(mask_sh),\
+       HWS_SF(, MC_VM_XGMI_LFB_CNTL, PF_LFB_REGION, mask_sh),\
+       HWS_SF(, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION, mask_sh)
+
+#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
+       HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
+       HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
+       HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh), \
+       HWS_SF(, DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
+
+#define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh), \
+       HWS_SF(, DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh), \
+       HWS_SF(, DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh), \
+       HWS_SF(, DCHUBBUB_SDPIF_AGP_BASE, SDPIF_AGP_BASE, mask_sh), \
+       HWS_SF(, DCHUBBUB_SDPIF_AGP_BOT, SDPIF_AGP_BOT, mask_sh), \
+       HWS_SF(, DCHUBBUB_SDPIF_AGP_TOP, SDPIF_AGP_TOP, mask_sh), \
+       /* todo:  get these from GVM instead of reading registers ourselves */\
+       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
+       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
+       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, LOGICAL_PAGE_NUMBER_HI4, mask_sh),\
+       HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, LOGICAL_PAGE_NUMBER_LO32, mask_sh),\
+       HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, PHYSICAL_PAGE_ADDR_HI4, mask_sh),\
+       HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
+       HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
+       HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
+       HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+       HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\
+       HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh)
+
+#define HWSEQ_DCN2_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN10_PG_CONFIG, DOMAIN10_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN10_PG_CONFIG, DOMAIN10_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN11_PG_CONFIG, DOMAIN11_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN11_PG_CONFIG, DOMAIN11_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN21_PG_CONFIG, DOMAIN21_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN8_PG_STATUS, DOMAIN8_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN9_PG_STATUS, DOMAIN9_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN10_PG_STATUS, DOMAIN10_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN11_PG_STATUS, DOMAIN11_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN21_PG_STATUS, DOMAIN21_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh)
+
+#define HWSEQ_DCN21_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+       HWS_SF(, MMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
+       HWS_SF(, MMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh)
+
+#define HWSEQ_DCN201_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh)
+
+#define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
+       HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh), \
+       HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
+       HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
+       HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \
+       HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh)
+
+#define HWSEQ_DCN301_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+       HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_BLON, mask_sh),\
+       HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON, mask_sh),\
+       HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON_OVRD, mask_sh),\
+       HWS_SF(, PANEL_PWRSEQ0_STATE, PANEL_PWRSEQ_TARGET_STATE_R, mask_sh),\
+       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh)
+
+#define HWSEQ_DCN302_MASK_SH_LIST(mask_sh)\
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, mask_sh), \
+       HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_GATE, mask_sh), \
+       HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN8_PG_STATUS, DOMAIN8_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN9_PG_STATUS, DOMAIN9_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \
+       HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
+       HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh)
+
+#define HWSEQ_DCN303_MASK_SH_LIST(mask_sh) \
+       HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+       HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
+       HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh)
+
+#define HWSEQ_REG_FIELD_LIST(type) \
+       type DCFE_CLOCK_ENABLE; \
+       type DCFEV_CLOCK_ENABLE; \
+       type DC_MEM_GLOBAL_PWR_REQ_DIS; \
+       type BLND_DCP_GRPH_V_UPDATE_LOCK; \
+       type BLND_SCL_V_UPDATE_LOCK; \
+       type BLND_DCP_GRPH_SURF_V_UPDATE_LOCK; \
+       type BLND_BLND_V_UPDATE_LOCK; \
+       type BLND_V_UPDATE_LOCK_MODE; \
+       type BLND_FEEDTHROUGH_EN; \
+       type BLND_ALPHA_MODE; \
+       type BLND_MODE; \
+       type BLND_MULTIPLIED_MODE; \
+       type DP_DTO0_ENABLE; \
+       type PIXEL_RATE_SOURCE; \
+       type PHYPLL_PIXEL_RATE_SOURCE; \
+       type PIXEL_RATE_PLL_SOURCE; \
+       /* todo:  get these from GVM instead of reading registers ourselves */\
+       type PAGE_DIRECTORY_ENTRY_HI32;\
+       type PAGE_DIRECTORY_ENTRY_LO32;\
+       type LOGICAL_PAGE_NUMBER_HI4;\
+       type LOGICAL_PAGE_NUMBER_LO32;\
+       type PHYSICAL_PAGE_ADDR_HI4;\
+       type PHYSICAL_PAGE_ADDR_LO32;\
+       type PHYSICAL_PAGE_NUMBER_MSB;\
+       type PHYSICAL_PAGE_NUMBER_LSB;\
+       type LOGICAL_ADDR; \
+       type PF_LFB_REGION;\
+       type PF_MAX_REGION;\
+       type ENABLE_L1_TLB;\
+       type SYSTEM_ACCESS_MODE;
+
+#define HWSEQ_DCN_REG_FIELD_LIST(type) \
+       type HUBP_VTG_SEL; \
+       type HUBP_CLOCK_ENABLE; \
+       type DPP_CLOCK_ENABLE; \
+       type SDPIF_FB_BASE;\
+       type SDPIF_FB_OFFSET;\
+       type SDPIF_AGP_BASE;\
+       type SDPIF_AGP_BOT;\
+       type SDPIF_AGP_TOP;\
+       type FB_TOP;\
+       type FB_BASE;\
+       type FB_OFFSET;\
+       type AGP_BASE;\
+       type AGP_BOT;\
+       type AGP_TOP;\
+       type DCHUBBUB_GLOBAL_TIMER_ENABLE; \
+       type OPP_PIPE_CLOCK_EN;\
+       type IP_REQUEST_EN; \
+       type DOMAIN0_POWER_FORCEON; \
+       type DOMAIN0_POWER_GATE; \
+       type DOMAIN1_POWER_FORCEON; \
+       type DOMAIN1_POWER_GATE; \
+       type DOMAIN2_POWER_FORCEON; \
+       type DOMAIN2_POWER_GATE; \
+       type DOMAIN3_POWER_FORCEON; \
+       type DOMAIN3_POWER_GATE; \
+       type DOMAIN4_POWER_FORCEON; \
+       type DOMAIN4_POWER_GATE; \
+       type DOMAIN5_POWER_FORCEON; \
+       type DOMAIN5_POWER_GATE; \
+       type DOMAIN6_POWER_FORCEON; \
+       type DOMAIN6_POWER_GATE; \
+       type DOMAIN7_POWER_FORCEON; \
+       type DOMAIN7_POWER_GATE; \
+       type DOMAIN8_POWER_FORCEON; \
+       type DOMAIN8_POWER_GATE; \
+       type DOMAIN9_POWER_FORCEON; \
+       type DOMAIN9_POWER_GATE; \
+       type DOMAIN10_POWER_FORCEON; \
+       type DOMAIN10_POWER_GATE; \
+       type DOMAIN11_POWER_FORCEON; \
+       type DOMAIN11_POWER_GATE; \
+       type DOMAIN16_POWER_FORCEON; \
+       type DOMAIN16_POWER_GATE; \
+       type DOMAIN17_POWER_FORCEON; \
+       type DOMAIN17_POWER_GATE; \
+       type DOMAIN18_POWER_FORCEON; \
+       type DOMAIN18_POWER_GATE; \
+       type DOMAIN19_POWER_FORCEON; \
+       type DOMAIN19_POWER_GATE; \
+       type DOMAIN20_POWER_FORCEON; \
+       type DOMAIN20_POWER_GATE; \
+       type DOMAIN21_POWER_FORCEON; \
+       type DOMAIN21_POWER_GATE; \
+       type DOMAIN0_PGFSM_PWR_STATUS; \
+       type DOMAIN1_PGFSM_PWR_STATUS; \
+       type DOMAIN2_PGFSM_PWR_STATUS; \
+       type DOMAIN3_PGFSM_PWR_STATUS; \
+       type DOMAIN4_PGFSM_PWR_STATUS; \
+       type DOMAIN5_PGFSM_PWR_STATUS; \
+       type DOMAIN6_PGFSM_PWR_STATUS; \
+       type DOMAIN7_PGFSM_PWR_STATUS; \
+       type DOMAIN8_PGFSM_PWR_STATUS; \
+       type DOMAIN9_PGFSM_PWR_STATUS; \
+       type DOMAIN10_PGFSM_PWR_STATUS; \
+       type DOMAIN11_PGFSM_PWR_STATUS; \
+       type DOMAIN16_PGFSM_PWR_STATUS; \
+       type DOMAIN17_PGFSM_PWR_STATUS; \
+       type DOMAIN18_PGFSM_PWR_STATUS; \
+       type DOMAIN19_PGFSM_PWR_STATUS; \
+       type DOMAIN20_PGFSM_PWR_STATUS; \
+       type DOMAIN21_PGFSM_PWR_STATUS; \
+       type DCFCLK_GATE_DIS; \
+       type DCHUBBUB_GLOBAL_TIMER_REFDIV; \
+       type VGA_TEST_ENABLE; \
+       type VGA_TEST_RENDER_START; \
+       type D1VGA_MODE_ENABLE; \
+       type D2VGA_MODE_ENABLE; \
+       type D3VGA_MODE_ENABLE; \
+       type D4VGA_MODE_ENABLE; \
+       type AZALIA_AUDIO_DTO_MODULE; \
+       type ODM_MEM_UNASSIGNED_PWR_MODE; \
+       type ODM_MEM_VBLANK_PWR_MODE; \
+       type DMCU_ERAM_MEM_PWR_FORCE; \
+       type VGA_MEM_PWR_FORCE;
+
+#define HWSEQ_DCN3_REG_FIELD_LIST(type) \
+       type HPO_HDMISTREAMCLK_GATE_DIS;
+
+#define HWSEQ_DCN301_REG_FIELD_LIST(type) \
+       type PANEL_BLON;\
+       type PANEL_DIGON;\
+       type PANEL_DIGON_OVRD;\
+       type PANEL_PWRSEQ_TARGET_STATE_R;
+
+#define HWSEQ_DCN31_REG_FIELD_LIST(type) \
+       type DOMAIN_POWER_FORCEON;\
+       type DOMAIN_POWER_GATE;\
+       type DOMAIN_PGFSM_PWR_STATUS;\
+       type HPO_HDMISTREAMCLK_G_GATE_DIS;\
+       type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;\
+       type I2C_LIGHT_SLEEP_FORCE;\
+       type HPO_IO_EN;
+
+#define HWSEQ_DCN35_REG_FIELD_LIST(type) \
+       type DISPCLK_R_DMU_GATE_DIS;\
+       type DISPCLK_G_RBBMIF_GATE_DIS;\
+       type RBBMIF_FGCG_REP_DIS;\
+       type IHC_FGCG_REP_DIS;\
+       type DPREFCLK_ALLOW_DS_CLKSTOP;\
+       type DISPCLK_ALLOW_DS_CLKSTOP;\
+       type DPPCLK_ALLOW_DS_CLKSTOP;\
+       type DTBCLK_ALLOW_DS_CLKSTOP;\
+       type DCFCLK_ALLOW_DS_CLKSTOP;\
+       type DPIACLK_ALLOW_DS_CLKSTOP;\
+       type LONO_FGCG_REP_DIS;\
+       type LONO_DISPCLK_GATE_DISABLE;\
+       type LONO_SOCCLK_GATE_DISABLE;\
+       type LONO_DMCUBCLK_GATE_DISABLE;
+
+struct dce_hwseq_shift {
+       HWSEQ_REG_FIELD_LIST(uint8_t)
+       HWSEQ_DCN_REG_FIELD_LIST(uint8_t)
+       HWSEQ_DCN3_REG_FIELD_LIST(uint8_t)
+       HWSEQ_DCN301_REG_FIELD_LIST(uint8_t)
+       HWSEQ_DCN31_REG_FIELD_LIST(uint8_t)
+       HWSEQ_DCN35_REG_FIELD_LIST(uint8_t)
+};
+
+struct dce_hwseq_mask {
+       HWSEQ_REG_FIELD_LIST(uint32_t)
+       HWSEQ_DCN_REG_FIELD_LIST(uint32_t)
+       HWSEQ_DCN3_REG_FIELD_LIST(uint32_t)
+       HWSEQ_DCN301_REG_FIELD_LIST(uint32_t)
+       HWSEQ_DCN31_REG_FIELD_LIST(uint32_t)
+       HWSEQ_DCN35_REG_FIELD_LIST(uint32_t)
+};
+
+
+enum blnd_mode {
+       BLND_MODE_CURRENT_PIPE = 0,/* Data from current pipe only */
+       BLND_MODE_OTHER_PIPE, /* Data from other pipe only */
+       BLND_MODE_BLENDING,/* Alpha blending - blend 'current' and 'other' */
+};
+
+struct dce_hwseq;
+struct pipe_ctx;
+struct clock_source;
+
+void dce_enable_fe_clock(struct dce_hwseq *hwss,
+               unsigned int inst, bool enable);
+
+void dce_pipe_control_lock(struct dc *dc,
+               struct pipe_ctx *pipe,
+               bool lock);
+
+void dce_set_blender_mode(struct dce_hwseq *hws,
+       unsigned int blnd_inst, enum blnd_mode mode);
+
+#if defined(CONFIG_DRM_AMD_DC_SI)
+void dce60_pipe_control_lock(struct dc *dc,
+               struct pipe_ctx *pipe,
+               bool lock);
+#endif
+
+void dce_clock_gating_power_up(struct dce_hwseq *hws,
+               bool enable);
+
+void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
+               struct clock_source *clk_src,
+               unsigned int tg_inst);
+
+bool dce_use_lut(enum surface_pixel_format format);
+#endif   /*__DCE_HWSEQ_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c
new file mode 100644 (file)
index 0000000..f1f1479
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2015 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 "dm_services.h"
+#include "dc.h"
+#include "core_types.h"
+#include "clk_mgr.h"
+#include "dce100_hwseq.h"
+#include "resource.h"
+
+#include "dce110/dce110_hwseq.h"
+
+/* include DCE10 register header files */
+#include "dce/dce_10_0_d.h"
+#include "dce/dce_10_0_sh_mask.h"
+
+struct dce100_hw_seq_reg_offsets {
+       uint32_t blnd;
+       uint32_t crtc;
+};
+
+static const struct dce100_hw_seq_reg_offsets reg_offsets[] = {
+{
+       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+}
+};
+
+#define HW_REG_CRTC(reg, id)\
+       (reg + reg_offsets[id].crtc)
+
+/*******************************************************************************
+ * Private definitions
+ ******************************************************************************/
+/***************************PIPE_CONTROL***********************************/
+
+bool dce100_enable_display_power_gating(
+       struct dc *dc,
+       uint8_t controller_id,
+       struct dc_bios *dcb,
+       enum pipe_gating_control power_gating)
+{
+       enum bp_result bp_result = BP_RESULT_OK;
+       enum bp_pipe_control_action cntl;
+       struct dc_context *ctx = dc->ctx;
+
+       if (power_gating == PIPE_GATING_CONTROL_INIT)
+               cntl = ASIC_PIPE_INIT;
+       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
+               cntl = ASIC_PIPE_ENABLE;
+       else
+               cntl = ASIC_PIPE_DISABLE;
+
+       if (!(power_gating == PIPE_GATING_CONTROL_INIT && controller_id != 0)){
+
+               bp_result = dcb->funcs->enable_disp_power_gating(
+                                               dcb, controller_id + 1, cntl);
+
+               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
+                * by default when command table is called
+                */
+               dm_write_reg(ctx,
+                       HW_REG_CRTC(mmMASTER_UPDATE_MODE, controller_id),
+                       0);
+       }
+
+       if (bp_result == BP_RESULT_OK)
+               return true;
+       else
+               return false;
+}
+
+void dce100_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       false);
+}
+
+void dce100_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       true);
+}
+
+/**************************************************************************/
+
+void dce100_hw_sequencer_construct(struct dc *dc)
+{
+       dce110_hw_sequencer_construct(dc);
+
+       dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
+       dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
+       dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h
new file mode 100644 (file)
index 0000000..34518da
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+* 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_HWSS_DCE100_H__
+#define __DC_HWSS_DCE100_H__
+
+#include "core_types.h"
+#include "hw_sequencer_private.h"
+
+struct dc;
+struct dc_state;
+
+void dce100_hw_sequencer_construct(struct dc *dc);
+
+void dce100_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+
+void dce100_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+
+bool dce100_enable_display_power_gating(struct dc *dc, uint8_t controller_id,
+                                       struct dc_bios *dcb,
+                                       enum pipe_gating_control power_gating);
+
+#endif /* __DC_HWSS_DCE100_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
new file mode 100644 (file)
index 0000000..74602a5
--- /dev/null
@@ -0,0 +1,3201 @@
+/*
+ * Copyright 2015 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 "dm_services.h"
+#include "dc.h"
+#include "dc_bios_types.h"
+#include "core_types.h"
+#include "core_status.h"
+#include "resource.h"
+#include "dm_helpers.h"
+#include "dce110_hwseq.h"
+#include "dce110/dce110_timing_generator.h"
+#include "dce/dce_hwseq.h"
+#include "gpio_service_interface.h"
+
+#include "dce110/dce110_compressor.h"
+
+#include "bios/bios_parser_helper.h"
+#include "timing_generator.h"
+#include "mem_input.h"
+#include "opp.h"
+#include "ipp.h"
+#include "transform.h"
+#include "stream_encoder.h"
+#include "link_encoder.h"
+#include "link_enc_cfg.h"
+#include "link_hwss.h"
+#include "link.h"
+#include "dccg.h"
+#include "clock_source.h"
+#include "clk_mgr.h"
+#include "abm.h"
+#include "audio.h"
+#include "reg_helper.h"
+#include "panel_cntl.h"
+#include "dpcd_defs.h"
+/* include DCE11 register header files */
+#include "dce/dce_11_0_d.h"
+#include "dce/dce_11_0_sh_mask.h"
+#include "custom_float.h"
+
+#include "atomfirmware.h"
+
+#include "dcn10/dcn10_hwseq.h"
+
+#include "dce110_hwseq.h"
+
+#define GAMMA_HW_POINTS_NUM 256
+
+/*
+ * All values are in milliseconds;
+ * For eDP, after power-up/power/down,
+ * 300/500 msec max. delay from LCDVCC to black video generation
+ */
+#define PANEL_POWER_UP_TIMEOUT 300
+#define PANEL_POWER_DOWN_TIMEOUT 500
+#define HPD_CHECK_INTERVAL 10
+#define OLED_POST_T7_DELAY 100
+#define OLED_PRE_T11_DELAY 150
+
+#define CTX \
+       hws->ctx
+
+#define DC_LOGGER \
+       ctx->logger
+#define DC_LOGGER_INIT() \
+       struct dc_context *ctx = dc->ctx
+
+#define REG(reg)\
+       hws->regs->reg
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+
+struct dce110_hw_seq_reg_offsets {
+       uint32_t crtc;
+};
+
+static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
+{
+       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+}
+};
+
+#define HW_REG_BLND(reg, id)\
+       (reg + reg_offsets[id].blnd)
+
+#define HW_REG_CRTC(reg, id)\
+       (reg + reg_offsets[id].crtc)
+
+#define MAX_WATERMARK 0xFFFF
+#define SAFE_NBP_MARK 0x7FFF
+
+/*******************************************************************************
+ * Private definitions
+ ******************************************************************************/
+/***************************PIPE_CONTROL***********************************/
+static void dce110_init_pte(struct dc_context *ctx)
+{
+       uint32_t addr;
+       uint32_t value = 0;
+       uint32_t chunk_int = 0;
+       uint32_t chunk_mul = 0;
+
+       addr = mmUNP_DVMM_PTE_CONTROL;
+       value = dm_read_reg(ctx, addr);
+
+       set_reg_field_value(
+               value,
+               0,
+               DVMM_PTE_CONTROL,
+               DVMM_USE_SINGLE_PTE);
+
+       set_reg_field_value(
+               value,
+               1,
+               DVMM_PTE_CONTROL,
+               DVMM_PTE_BUFFER_MODE0);
+
+       set_reg_field_value(
+               value,
+               1,
+               DVMM_PTE_CONTROL,
+               DVMM_PTE_BUFFER_MODE1);
+
+       dm_write_reg(ctx, addr, value);
+
+       addr = mmDVMM_PTE_REQ;
+       value = dm_read_reg(ctx, addr);
+
+       chunk_int = get_reg_field_value(
+               value,
+               DVMM_PTE_REQ,
+               HFLIP_PTEREQ_PER_CHUNK_INT);
+
+       chunk_mul = get_reg_field_value(
+               value,
+               DVMM_PTE_REQ,
+               HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
+
+       if (chunk_int != 0x4 || chunk_mul != 0x4) {
+
+               set_reg_field_value(
+                       value,
+                       255,
+                       DVMM_PTE_REQ,
+                       MAX_PTEREQ_TO_ISSUE);
+
+               set_reg_field_value(
+                       value,
+                       4,
+                       DVMM_PTE_REQ,
+                       HFLIP_PTEREQ_PER_CHUNK_INT);
+
+               set_reg_field_value(
+                       value,
+                       4,
+                       DVMM_PTE_REQ,
+                       HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
+
+               dm_write_reg(ctx, addr, value);
+       }
+}
+/**************************************************************************/
+
+static void enable_display_pipe_clock_gating(
+       struct dc_context *ctx,
+       bool clock_gating)
+{
+       /*TODO*/
+}
+
+static bool dce110_enable_display_power_gating(
+       struct dc *dc,
+       uint8_t controller_id,
+       struct dc_bios *dcb,
+       enum pipe_gating_control power_gating)
+{
+       enum bp_result bp_result = BP_RESULT_OK;
+       enum bp_pipe_control_action cntl;
+       struct dc_context *ctx = dc->ctx;
+       unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
+
+       if (power_gating == PIPE_GATING_CONTROL_INIT)
+               cntl = ASIC_PIPE_INIT;
+       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
+               cntl = ASIC_PIPE_ENABLE;
+       else
+               cntl = ASIC_PIPE_DISABLE;
+
+       if (controller_id == underlay_idx)
+               controller_id = CONTROLLER_ID_UNDERLAY0 - 1;
+
+       if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
+
+               bp_result = dcb->funcs->enable_disp_power_gating(
+                                               dcb, controller_id + 1, cntl);
+
+               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
+                * by default when command table is called
+                *
+                * Bios parser accepts controller_id = 6 as indicative of
+                * underlay pipe in dce110. But we do not support more
+                * than 3.
+                */
+               if (controller_id < CONTROLLER_ID_MAX - 1)
+                       dm_write_reg(ctx,
+                               HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
+                               0);
+       }
+
+       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
+               dce110_init_pte(ctx);
+
+       if (bp_result == BP_RESULT_OK)
+               return true;
+       else
+               return false;
+}
+
+static void build_prescale_params(struct ipp_prescale_params *prescale_params,
+               const struct dc_plane_state *plane_state)
+{
+       prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
+
+       switch (plane_state->format) {
+       case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+               prescale_params->scale = 0x2082;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
+               prescale_params->scale = 0x2020;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
+               prescale_params->scale = 0x2008;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
+               prescale_params->scale = 0x2000;
+               break;
+       default:
+               ASSERT(false);
+               break;
+       }
+}
+
+static bool
+dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                              const struct dc_plane_state *plane_state)
+{
+       struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+       const struct dc_transfer_func *tf = NULL;
+       struct ipp_prescale_params prescale_params = { 0 };
+       bool result = true;
+
+       if (ipp == NULL)
+               return false;
+
+       if (plane_state->in_transfer_func)
+               tf = plane_state->in_transfer_func;
+
+       build_prescale_params(&prescale_params, plane_state);
+       ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
+
+       if (plane_state->gamma_correction &&
+                       !plane_state->gamma_correction->is_identity &&
+                       dce_use_lut(plane_state->format))
+               ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
+
+       if (tf == NULL) {
+               /* Default case if no input transfer function specified */
+               ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
+       } else if (tf->type == TF_TYPE_PREDEFINED) {
+               switch (tf->tf) {
+               case TRANSFER_FUNCTION_SRGB:
+                       ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
+                       break;
+               case TRANSFER_FUNCTION_BT709:
+                       ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC);
+                       break;
+               case TRANSFER_FUNCTION_LINEAR:
+                       ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
+                       break;
+               case TRANSFER_FUNCTION_PQ:
+               default:
+                       result = false;
+                       break;
+               }
+       } else if (tf->type == TF_TYPE_BYPASS) {
+               ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
+       } else {
+               /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
+               result = false;
+       }
+
+       return result;
+}
+
+static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted,
+                                   struct curve_points *arr_points,
+                                   uint32_t hw_points_num)
+{
+       struct custom_float_format fmt;
+
+       struct pwl_result_data *rgb = rgb_resulted;
+
+       uint32_t i = 0;
+
+       fmt.exponenta_bits = 6;
+       fmt.mantissa_bits = 12;
+       fmt.sign = true;
+
+       if (!convert_to_custom_float_format(arr_points[0].x, &fmt,
+                                           &arr_points[0].custom_float_x)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(arr_points[0].offset, &fmt,
+                                           &arr_points[0].custom_float_offset)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(arr_points[0].slope, &fmt,
+                                           &arr_points[0].custom_float_slope)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       fmt.mantissa_bits = 10;
+       fmt.sign = false;
+
+       if (!convert_to_custom_float_format(arr_points[1].x, &fmt,
+                                           &arr_points[1].custom_float_x)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
+                                           &arr_points[1].custom_float_y)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(arr_points[1].slope, &fmt,
+                                           &arr_points[1].custom_float_slope)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       fmt.mantissa_bits = 12;
+       fmt.sign = true;
+
+       while (i != hw_points_num) {
+               if (!convert_to_custom_float_format(rgb->red, &fmt,
+                                                   &rgb->red_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(rgb->green, &fmt,
+                                                   &rgb->green_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(rgb->blue, &fmt,
+                                                   &rgb->blue_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
+                                                   &rgb->delta_red_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
+                                                   &rgb->delta_green_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
+                                                   &rgb->delta_blue_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               ++rgb;
+               ++i;
+       }
+
+       return true;
+}
+
+#define MAX_LOW_POINT      25
+#define NUMBER_REGIONS     16
+#define NUMBER_SW_SEGMENTS 16
+
+static bool
+dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
+                                     struct pwl_params *regamma_params)
+{
+       struct curve_points *arr_points;
+       struct pwl_result_data *rgb_resulted;
+       struct pwl_result_data *rgb;
+       struct pwl_result_data *rgb_plus_1;
+       struct fixed31_32 y_r;
+       struct fixed31_32 y_g;
+       struct fixed31_32 y_b;
+       struct fixed31_32 y1_min;
+       struct fixed31_32 y3_max;
+
+       int32_t region_start, region_end;
+       uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points;
+
+       if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS)
+               return false;
+
+       arr_points = regamma_params->arr_points;
+       rgb_resulted = regamma_params->rgb_resulted;
+       hw_points = 0;
+
+       memset(regamma_params, 0, sizeof(struct pwl_params));
+
+       if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+               /* 16 segments
+                * segments are from 2^-11 to 2^5
+                */
+               region_start = -11;
+               region_end = region_start + NUMBER_REGIONS;
+
+               for (i = 0; i < NUMBER_REGIONS; i++)
+                       seg_distr[i] = 4;
+
+       } else {
+               /* 10 segments
+                * segment is from 2^-10 to 2^1
+                * We include an extra segment for range [2^0, 2^1). This is to
+                * ensure that colors with normalized values of 1 don't miss the
+                * LUT.
+                */
+               region_start = -10;
+               region_end = 1;
+
+               seg_distr[0] = 4;
+               seg_distr[1] = 4;
+               seg_distr[2] = 4;
+               seg_distr[3] = 4;
+               seg_distr[4] = 4;
+               seg_distr[5] = 4;
+               seg_distr[6] = 4;
+               seg_distr[7] = 4;
+               seg_distr[8] = 4;
+               seg_distr[9] = 4;
+               seg_distr[10] = 0;
+               seg_distr[11] = -1;
+               seg_distr[12] = -1;
+               seg_distr[13] = -1;
+               seg_distr[14] = -1;
+               seg_distr[15] = -1;
+       }
+
+       for (k = 0; k < 16; k++) {
+               if (seg_distr[k] != -1)
+                       hw_points += (1 << seg_distr[k]);
+       }
+
+       j = 0;
+       for (k = 0; k < (region_end - region_start); k++) {
+               increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+               start_index = (region_start + k + MAX_LOW_POINT) *
+                               NUMBER_SW_SEGMENTS;
+               for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+                               i += increment) {
+                       if (j == hw_points - 1)
+                               break;
+                       rgb_resulted[j].red = output_tf->tf_pts.red[i];
+                       rgb_resulted[j].green = output_tf->tf_pts.green[i];
+                       rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+                       j++;
+               }
+       }
+
+       /* last point */
+       start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
+       rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
+       rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
+       rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
+
+       arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
+                                            dc_fixpt_from_int(region_start));
+       arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
+                                            dc_fixpt_from_int(region_end));
+
+       y_r = rgb_resulted[0].red;
+       y_g = rgb_resulted[0].green;
+       y_b = rgb_resulted[0].blue;
+
+       y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
+
+       arr_points[0].y = y1_min;
+       arr_points[0].slope = dc_fixpt_div(arr_points[0].y,
+                                                arr_points[0].x);
+
+       y_r = rgb_resulted[hw_points - 1].red;
+       y_g = rgb_resulted[hw_points - 1].green;
+       y_b = rgb_resulted[hw_points - 1].blue;
+
+       /* see comment above, m_arrPoints[1].y should be the Y value for the
+        * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
+        */
+       y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
+
+       arr_points[1].y = y3_max;
+
+       arr_points[1].slope = dc_fixpt_zero;
+
+       if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+               /* for PQ, we want to have a straight line from last HW X point,
+                * and the slope to be such that we hit 1.0 at 10000 nits.
+                */
+               const struct fixed31_32 end_value = dc_fixpt_from_int(125);
+
+               arr_points[1].slope = dc_fixpt_div(
+                               dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
+                               dc_fixpt_sub(end_value, arr_points[1].x));
+       }
+
+       regamma_params->hw_points_num = hw_points;
+
+       k = 0;
+       for (i = 1; i < 16; i++) {
+               if (seg_distr[k] != -1) {
+                       regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
+                       regamma_params->arr_curve_points[i].offset =
+                                       regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
+               }
+               k++;
+       }
+
+       if (seg_distr[k] != -1)
+               regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
+
+       rgb = rgb_resulted;
+       rgb_plus_1 = rgb_resulted + 1;
+
+       i = 1;
+
+       while (i != hw_points + 1) {
+               if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
+                       rgb_plus_1->red = rgb->red;
+               if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
+                       rgb_plus_1->green = rgb->green;
+               if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
+                       rgb_plus_1->blue = rgb->blue;
+
+               rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
+               rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
+               rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
+
+               ++rgb_plus_1;
+               ++rgb;
+               ++i;
+       }
+
+       convert_to_custom_float(rgb_resulted, arr_points, hw_points);
+
+       return true;
+}
+
+static bool
+dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream)
+{
+       struct transform *xfm = pipe_ctx->plane_res.xfm;
+
+       xfm->funcs->opp_power_on_regamma_lut(xfm, true);
+       xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
+
+       if (stream->out_transfer_func &&
+           stream->out_transfer_func->type == TF_TYPE_PREDEFINED &&
+           stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) {
+               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
+       } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func,
+                                                        &xfm->regamma_params)) {
+               xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
+               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
+       } else {
+               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
+       }
+
+       xfm->funcs->opp_power_on_regamma_lut(xfm, false);
+
+       return true;
+}
+
+void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
+{
+       bool is_hdmi_tmds;
+       bool is_dp;
+
+       ASSERT(pipe_ctx->stream);
+
+       if (pipe_ctx->stream_res.stream_enc == NULL)
+               return;  /* this is not root pipe */
+
+       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
+       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
+
+       if (!is_hdmi_tmds && !is_dp)
+               return;
+
+       if (is_hdmi_tmds)
+               pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
+                       pipe_ctx->stream_res.stream_enc,
+                       &pipe_ctx->stream_res.encoder_info_frame);
+       else {
+               if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)
+                       pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(
+                               pipe_ctx->stream_res.stream_enc,
+                               &pipe_ctx->stream_res.encoder_info_frame);
+
+               pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
+                       pipe_ctx->stream_res.stream_enc,
+                       &pipe_ctx->stream_res.encoder_info_frame);
+       }
+}
+
+void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
+{
+       enum dc_lane_count lane_count =
+               pipe_ctx->stream->link->cur_link_settings.lane_count;
+       struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+       struct dc_link *link = pipe_ctx->stream->link;
+       const struct dc *dc = link->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+       uint32_t active_total_with_borders;
+       uint32_t early_control = 0;
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+       link_hwss->setup_stream_encoder(pipe_ctx);
+
+       dc->hwss.update_info_frame(pipe_ctx);
+
+       /* enable early control to avoid corruption on DP monitor*/
+       active_total_with_borders =
+                       timing->h_addressable
+                               + timing->h_border_left
+                               + timing->h_border_right;
+
+       if (lane_count != 0)
+               early_control = active_total_with_borders % lane_count;
+
+       if (early_control == 0)
+               early_control = lane_count;
+
+       tg->funcs->set_early_control(tg, early_control);
+}
+
+static enum bp_result link_transmitter_control(
+               struct dc_bios *bios,
+       struct bp_transmitter_control *cntl)
+{
+       enum bp_result result;
+
+       result = bios->funcs->transmitter_control(bios, cntl);
+
+       return result;
+}
+
+/*
+ * @brief
+ * eDP only.
+ */
+void dce110_edp_wait_for_hpd_ready(
+               struct dc_link *link,
+               bool power_up)
+{
+       struct dc_context *ctx = link->ctx;
+       struct graphics_object_id connector = link->link_enc->connector;
+       struct gpio *hpd;
+       bool edp_hpd_high = false;
+       uint32_t time_elapsed = 0;
+       uint32_t timeout = power_up ?
+               PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
+
+       if (dal_graphics_object_id_get_connector_id(connector)
+                       != CONNECTOR_ID_EDP) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       if (!power_up)
+               /*
+                * From KV, we will not HPD low after turning off VCC -
+                * instead, we will check the SW timer in power_up().
+                */
+               return;
+
+       /*
+        * When we power on/off the eDP panel,
+        * we need to wait until SENSE bit is high/low.
+        */
+
+       /* obtain HPD */
+       /* TODO what to do with this? */
+       hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
+
+       if (!hpd) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       if (link != NULL) {
+               if (link->panel_config.pps.extra_t3_ms > 0) {
+                       int extra_t3_in_ms = link->panel_config.pps.extra_t3_ms;
+
+                       msleep(extra_t3_in_ms);
+               }
+       }
+
+       dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
+
+       /* wait until timeout or panel detected */
+
+       do {
+               uint32_t detected = 0;
+
+               dal_gpio_get_value(hpd, &detected);
+
+               if (!(detected ^ power_up)) {
+                       edp_hpd_high = true;
+                       break;
+               }
+
+               msleep(HPD_CHECK_INTERVAL);
+
+               time_elapsed += HPD_CHECK_INTERVAL;
+       } while (time_elapsed < timeout);
+
+       dal_gpio_close(hpd);
+
+       dal_gpio_destroy_irq(&hpd);
+
+       /* ensure that the panel is detected */
+       if (!edp_hpd_high)
+               DC_LOG_DC("%s: wait timed out!\n", __func__);
+}
+
+void dce110_edp_power_control(
+               struct dc_link *link,
+               bool power_up)
+{
+       struct dc_context *ctx = link->ctx;
+       struct bp_transmitter_control cntl = { 0 };
+       enum bp_result bp_result;
+       uint8_t panel_instance;
+
+
+       if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
+                       != CONNECTOR_ID_EDP) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       if (!link->panel_cntl)
+               return;
+       if (power_up !=
+               link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) {
+
+               unsigned long long current_ts = dm_get_timestamp(ctx);
+               unsigned long long time_since_edp_poweroff_ms =
+                               div64_u64(dm_get_elapse_time_in_ns(
+                                               ctx,
+                                               current_ts,
+                                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
+               unsigned long long time_since_edp_poweron_ms =
+                               div64_u64(dm_get_elapse_time_in_ns(
+                                               ctx,
+                                               current_ts,
+                                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)), 1000000);
+               DC_LOG_HW_RESUME_S3(
+                               "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu",
+                               __func__,
+                               power_up,
+                               current_ts,
+                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link),
+                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link),
+                               time_since_edp_poweroff_ms,
+                               time_since_edp_poweron_ms);
+
+               /* Send VBIOS command to prompt eDP panel power */
+               if (power_up) {
+                       /* edp requires a min of 500ms from LCDVDD off to on */
+                       unsigned long long remaining_min_edp_poweroff_time_ms = 500;
+
+                       /* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */
+                       if (link->local_sink != NULL)
+                               remaining_min_edp_poweroff_time_ms +=
+                                       link->panel_config.pps.extra_t12_ms;
+
+                       /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */
+                       if (ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) {
+                               if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms)
+                                       remaining_min_edp_poweroff_time_ms =
+                                               remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms;
+                               else
+                                       remaining_min_edp_poweroff_time_ms = 0;
+                       }
+
+                       if (remaining_min_edp_poweroff_time_ms) {
+                               DC_LOG_HW_RESUME_S3(
+                                               "%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n",
+                                               __func__, remaining_min_edp_poweroff_time_ms);
+                               msleep(remaining_min_edp_poweroff_time_ms);
+                               DC_LOG_HW_RESUME_S3(
+                                               "%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n",
+                                               __func__, remaining_min_edp_poweroff_time_ms);
+                               dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
+                                               __func__, remaining_min_edp_poweroff_time_ms);
+                       } else {
+                               DC_LOG_HW_RESUME_S3(
+                                               "%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n",
+                                               __func__, remaining_min_edp_poweroff_time_ms);
+                       }
+               }
+
+               DC_LOG_HW_RESUME_S3(
+                               "%s: BEGIN: Panel Power action: %s\n",
+                               __func__, (power_up ? "On":"Off"));
+
+               cntl.action = power_up ?
+                       TRANSMITTER_CONTROL_POWER_ON :
+                       TRANSMITTER_CONTROL_POWER_OFF;
+               cntl.transmitter = link->link_enc->transmitter;
+               cntl.connector_obj_id = link->link_enc->connector;
+               cntl.coherent = false;
+               cntl.lanes_number = LANE_COUNT_FOUR;
+               cntl.hpd_sel = link->link_enc->hpd_source;
+               panel_instance = link->panel_cntl->inst;
+
+               if (ctx->dc->ctx->dmub_srv &&
+                               ctx->dc->debug.dmub_command_table) {
+
+                       if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) {
+                               bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
+                                               LVTMA_CONTROL_POWER_ON,
+                                               panel_instance, link->link_powered_externally);
+                       } else {
+                               bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
+                                               LVTMA_CONTROL_POWER_OFF,
+                                               panel_instance, link->link_powered_externally);
+                       }
+               }
+
+               bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
+
+               DC_LOG_HW_RESUME_S3(
+                               "%s: END: Panel Power action: %s bp_result=%u\n",
+                               __func__, (power_up ? "On":"Off"),
+                               bp_result);
+
+               ctx->dc->link_srv->dp_trace_set_edp_power_timestamp(link, power_up);
+
+               DC_LOG_HW_RESUME_S3(
+                               "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n",
+                               __func__,
+                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link),
+                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link));
+
+               if (bp_result != BP_RESULT_OK)
+                       DC_LOG_ERROR(
+                                       "%s: Panel Power bp_result: %d\n",
+                                       __func__, bp_result);
+       } else {
+               DC_LOG_HW_RESUME_S3(
+                               "%s: Skipping Panel Power action: %s\n",
+                               __func__, (power_up ? "On":"Off"));
+       }
+}
+
+void dce110_edp_wait_for_T12(
+               struct dc_link *link)
+{
+       struct dc_context *ctx = link->ctx;
+
+       if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
+                       != CONNECTOR_ID_EDP) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       if (!link->panel_cntl)
+               return;
+
+       if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) &&
+                       ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) {
+               unsigned int t12_duration = 500; // Default T12 as per spec
+               unsigned long long current_ts = dm_get_timestamp(ctx);
+               unsigned long long time_since_edp_poweroff_ms =
+                               div64_u64(dm_get_elapse_time_in_ns(
+                                               ctx,
+                                               current_ts,
+                                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
+
+               t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12
+
+               if (time_since_edp_poweroff_ms < t12_duration)
+                       msleep(t12_duration - time_since_edp_poweroff_ms);
+       }
+}
+/*todo: cloned in stream enc, fix*/
+/*
+ * @brief
+ * eDP only. Control the backlight of the eDP panel
+ */
+void dce110_edp_backlight_control(
+               struct dc_link *link,
+               bool enable)
+{
+       struct dc_context *ctx = link->ctx;
+       struct bp_transmitter_control cntl = { 0 };
+       uint8_t panel_instance;
+       unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
+       unsigned int post_T7_delay = OLED_POST_T7_DELAY;
+
+       if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
+               != CONNECTOR_ID_EDP) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled ||
+               link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
+               link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) {
+               bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl);
+
+               if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) {
+                       DC_LOG_HW_RESUME_S3(
+                               "%s: panel already powered up/off. Do nothing.\n",
+                               __func__);
+                       return;
+               }
+       }
+
+       /* Send VBIOS command to control eDP panel backlight */
+
+       DC_LOG_HW_RESUME_S3(
+                       "%s: backlight action: %s\n",
+                       __func__, (enable ? "On":"Off"));
+
+       cntl.action = enable ?
+               TRANSMITTER_CONTROL_BACKLIGHT_ON :
+               TRANSMITTER_CONTROL_BACKLIGHT_OFF;
+
+       /*cntl.engine_id = ctx->engine;*/
+       cntl.transmitter = link->link_enc->transmitter;
+       cntl.connector_obj_id = link->link_enc->connector;
+       /*todo: unhardcode*/
+       cntl.lanes_number = LANE_COUNT_FOUR;
+       cntl.hpd_sel = link->link_enc->hpd_source;
+       cntl.signal = SIGNAL_TYPE_EDP;
+
+       /* For eDP, the following delays might need to be considered
+        * after link training completed:
+        * idle period - min. accounts for required BS-Idle pattern,
+        * max. allows for source frame synchronization);
+        * 50 msec max. delay from valid video data from source
+        * to video on dislpay or backlight enable.
+        *
+        * Disable the delay for now.
+        * Enable it in the future if necessary.
+        */
+       /* dc_service_sleep_in_milliseconds(50); */
+               /*edp 1.2*/
+       panel_instance = link->panel_cntl->inst;
+
+       if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
+               if (!link->dc->config.edp_no_power_sequencing)
+               /*
+                * Sometimes, DP receiver chip power-controlled externally by an
+                * Embedded Controller could be treated and used as eDP,
+                * if it drives mobile display. In this case,
+                * we shouldn't be doing power-sequencing, hence we can skip
+                * waiting for T7-ready.
+                */
+                       ctx->dc->link_srv->edp_receiver_ready_T7(link);
+               else
+                       DC_LOG_DC("edp_receiver_ready_T7 skipped\n");
+       }
+
+       /* Setting link_powered_externally will bypass delays in the backlight
+        * as they are not required if the link is being powered by a different
+        * source.
+        */
+       if (ctx->dc->ctx->dmub_srv &&
+                       ctx->dc->debug.dmub_command_table) {
+               if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
+                       ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
+                                       LVTMA_CONTROL_LCD_BLON,
+                                       panel_instance, link->link_powered_externally);
+               else
+                       ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
+                                       LVTMA_CONTROL_LCD_BLOFF,
+                                       panel_instance, link->link_powered_externally);
+       }
+
+       link_transmitter_control(ctx->dc_bios, &cntl);
+
+       if (enable && link->dpcd_sink_ext_caps.bits.oled &&
+           !link->dc->config.edp_no_power_sequencing) {
+               post_T7_delay += link->panel_config.pps.extra_post_t7_ms;
+               msleep(post_T7_delay);
+       }
+
+       if (link->dpcd_sink_ext_caps.bits.oled ||
+               link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
+               link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)
+               ctx->dc->link_srv->edp_backlight_enable_aux(link, enable);
+
+       /*edp 1.2*/
+       if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) {
+               if (!link->dc->config.edp_no_power_sequencing)
+               /*
+                * Sometimes, DP receiver chip power-controlled externally by an
+                * Embedded Controller could be treated and used as eDP,
+                * if it drives mobile display. In this case,
+                * we shouldn't be doing power-sequencing, hence we can skip
+                * waiting for T9-ready.
+                */
+                       ctx->dc->link_srv->edp_add_delay_for_T9(link);
+               else
+                       DC_LOG_DC("edp_receiver_ready_T9 skipped\n");
+       }
+
+       if (!enable && link->dpcd_sink_ext_caps.bits.oled) {
+               pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms;
+               msleep(pre_T11_delay);
+       }
+}
+
+void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
+{
+       /* notify audio driver for audio modes of monitor */
+       struct dc *dc;
+       struct clk_mgr *clk_mgr;
+       unsigned int i, num_audio = 1;
+       const struct link_hwss *link_hwss;
+
+       if (!pipe_ctx->stream)
+               return;
+
+       dc = pipe_ctx->stream->ctx->dc;
+       clk_mgr = dc->clk_mgr;
+       link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
+
+       if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
+               return;
+
+       if (pipe_ctx->stream_res.audio) {
+               for (i = 0; i < MAX_PIPES; i++) {
+                       /*current_state not updated yet*/
+                       if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
+                               num_audio++;
+               }
+
+               pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
+
+               if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa)
+                       /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
+                       clk_mgr->funcs->enable_pme_wa(clk_mgr);
+
+               link_hwss->enable_audio_packet(pipe_ctx);
+
+               if (pipe_ctx->stream_res.audio)
+                       pipe_ctx->stream_res.audio->enabled = true;
+       }
+}
+
+void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
+{
+       struct dc *dc;
+       struct clk_mgr *clk_mgr;
+       const struct link_hwss *link_hwss;
+
+       if (!pipe_ctx || !pipe_ctx->stream)
+               return;
+
+       dc = pipe_ctx->stream->ctx->dc;
+       clk_mgr = dc->clk_mgr;
+       link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
+
+       if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
+               return;
+
+       link_hwss->disable_audio_packet(pipe_ctx);
+
+       if (pipe_ctx->stream_res.audio) {
+               pipe_ctx->stream_res.audio->enabled = false;
+
+               if (clk_mgr->funcs->enable_pme_wa)
+                       /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
+                       clk_mgr->funcs->enable_pme_wa(clk_mgr);
+
+               /* TODO: notify audio driver for if audio modes list changed
+                * add audio mode list change flag */
+               /* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
+                * stream->stream_engine_id);
+                */
+       }
+}
+
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+       struct dccg *dccg = dc->res_pool->dccg;
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       struct dtbclk_dto_params dto_params = {0};
+       int dp_hpo_inst;
+       struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
+       struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
+
+       if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
+               pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
+                       pipe_ctx->stream_res.stream_enc);
+               pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute(
+                       pipe_ctx->stream_res.stream_enc);
+       }
+
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
+                                       pipe_ctx->stream_res.hpo_dp_stream_enc);
+       } else if (dc_is_dp_signal(pipe_ctx->stream->signal))
+               pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
+                       pipe_ctx->stream_res.stream_enc);
+
+       dc->hwss.disable_audio_stream(pipe_ctx);
+
+       link_hwss->reset_stream_encoder(pipe_ctx);
+
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && dccg) {
+               dto_params.otg_inst = tg->inst;
+               dto_params.timing = &pipe_ctx->stream->timing;
+               dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
+
+               dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+               dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
+               dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
+       } else if (dccg && dccg->funcs->disable_symclk_se) {
+               dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
+                                              link_enc->transmitter - TRANSMITTER_UNIPHY_A);
+       }
+
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               /* TODO: This looks like a bug to me as we are disabling HPO IO when
+                * we are just disabling a single HPO stream. Shouldn't we disable HPO
+                * HW control only when HPOs for all streams are disabled?
+                */
+               if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
+                       pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
+                                       pipe_ctx->stream->ctx->dc->hwseq, false);
+       }
+}
+
+void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings)
+{
+       struct encoder_unblank_param params = { { 0 } };
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dce_hwseq *hws = link->dc->hwseq;
+
+       /* only 3 items below are used by unblank */
+       params.timing = pipe_ctx->stream->timing;
+       params.link_settings.link_rate = link_settings->link_rate;
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal))
+               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
+
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+               hws->funcs.edp_backlight_control(link, true);
+       }
+}
+
+void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dce_hwseq *hws = link->dc->hwseq;
+
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+               if (!link->skip_implict_edp_power_control)
+                       hws->funcs.edp_backlight_control(link, false);
+               link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
+       }
+
+       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
+               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
+                               pipe_ctx->stream_res.hpo_dp_stream_enc);
+       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
+
+               if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) {
+                       /*
+                        * After output is idle pattern some sinks need time to recognize the stream
+                        * has changed or they enter protection state and hang.
+                        */
+                       msleep(60);
+               } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
+                       if (!link->dc->config.edp_no_power_sequencing) {
+                               /*
+                                * Sometimes, DP receiver chip power-controlled externally by an
+                                * Embedded Controller could be treated and used as eDP,
+                                * if it drives mobile display. In this case,
+                                * we shouldn't be doing power-sequencing, hence we can skip
+                                * waiting for T9-ready.
+                                */
+                               link->dc->link_srv->edp_receiver_ready_T9(link);
+                       }
+               }
+       }
+
+}
+
+
+void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
+{
+       if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
+               pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
+}
+
+static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
+{
+       switch (crtc_id) {
+       case CONTROLLER_ID_D0:
+               return DTO_SOURCE_ID0;
+       case CONTROLLER_ID_D1:
+               return DTO_SOURCE_ID1;
+       case CONTROLLER_ID_D2:
+               return DTO_SOURCE_ID2;
+       case CONTROLLER_ID_D3:
+               return DTO_SOURCE_ID3;
+       case CONTROLLER_ID_D4:
+               return DTO_SOURCE_ID4;
+       case CONTROLLER_ID_D5:
+               return DTO_SOURCE_ID5;
+       default:
+               return DTO_SOURCE_UNKNOWN;
+       }
+}
+
+static void build_audio_output(
+       struct dc_state *state,
+       const struct pipe_ctx *pipe_ctx,
+       struct audio_output *audio_output)
+{
+       const struct dc_stream_state *stream = pipe_ctx->stream;
+       audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id;
+
+       audio_output->signal = pipe_ctx->stream->signal;
+
+       /* audio_crtc_info  */
+
+       audio_output->crtc_info.h_total =
+               stream->timing.h_total;
+
+       /*
+        * Audio packets are sent during actual CRTC blank physical signal, we
+        * need to specify actual active signal portion
+        */
+       audio_output->crtc_info.h_active =
+                       stream->timing.h_addressable
+                       + stream->timing.h_border_left
+                       + stream->timing.h_border_right;
+
+       audio_output->crtc_info.v_active =
+                       stream->timing.v_addressable
+                       + stream->timing.v_border_top
+                       + stream->timing.v_border_bottom;
+
+       audio_output->crtc_info.pixel_repetition = 1;
+
+       audio_output->crtc_info.interlaced =
+                       stream->timing.flags.INTERLACE;
+
+       audio_output->crtc_info.refresh_rate =
+               (stream->timing.pix_clk_100hz*100)/
+               (stream->timing.h_total*stream->timing.v_total);
+
+       audio_output->crtc_info.color_depth =
+               stream->timing.display_color_depth;
+
+       audio_output->crtc_info.requested_pixel_clock_100Hz =
+                       pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
+
+       audio_output->crtc_info.calculated_pixel_clock_100Hz =
+                       pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
+
+/*for HDMI, audio ACR is with deep color ratio factor*/
+       if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) &&
+               audio_output->crtc_info.requested_pixel_clock_100Hz ==
+                               (stream->timing.pix_clk_100hz)) {
+               if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+                       audio_output->crtc_info.requested_pixel_clock_100Hz =
+                                       audio_output->crtc_info.requested_pixel_clock_100Hz/2;
+                       audio_output->crtc_info.calculated_pixel_clock_100Hz =
+                                       pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2;
+
+               }
+       }
+
+       if (state->clk_mgr &&
+               (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
+                       pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
+               audio_output->pll_info.dp_dto_source_clock_in_khz =
+                               state->clk_mgr->funcs->get_dp_ref_clk_frequency(
+                                               state->clk_mgr);
+       }
+
+       audio_output->pll_info.feed_back_divider =
+                       pipe_ctx->pll_settings.feedback_divider;
+
+       audio_output->pll_info.dto_source =
+               translate_to_dto_source(
+                       pipe_ctx->stream_res.tg->inst + 1);
+
+       /* TODO hard code to enable for now. Need get from stream */
+       audio_output->pll_info.ss_enabled = true;
+
+       audio_output->pll_info.ss_percentage =
+                       pipe_ctx->pll_settings.ss_percentage;
+}
+
+static void program_scaler(const struct dc *dc,
+               const struct pipe_ctx *pipe_ctx)
+{
+       struct tg_color color = {0};
+
+       /* TOFPGA */
+       if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
+               return;
+
+       if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
+               get_surface_visual_confirm_color(pipe_ctx, &color);
+       else
+               color_space_to_black_color(dc,
+                               pipe_ctx->stream->output_color_space,
+                               &color);
+
+       pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
+               pipe_ctx->plane_res.xfm,
+               pipe_ctx->plane_res.scl_data.lb_params.depth,
+               &pipe_ctx->stream->bit_depth_params);
+
+       if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {
+               /*
+                * The way 420 is packed, 2 channels carry Y component, 1 channel
+                * alternate between Cb and Cr, so both channels need the pixel
+                * value for Y
+                */
+               if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+                       color.color_r_cr = color.color_g_y;
+
+               pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
+                               pipe_ctx->stream_res.tg,
+                               &color);
+       }
+
+       pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
+               &pipe_ctx->plane_res.scl_data);
+}
+
+static enum dc_status dce110_enable_stream_timing(
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context,
+               struct dc *dc)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
+                       pipe_ctx[pipe_ctx->pipe_idx];
+       struct tg_color black_color = {0};
+
+       if (!pipe_ctx_old->stream) {
+
+               /* program blank color */
+               color_space_to_black_color(dc,
+                               stream->output_color_space, &black_color);
+               pipe_ctx->stream_res.tg->funcs->set_blank_color(
+                               pipe_ctx->stream_res.tg,
+                               &black_color);
+
+               /*
+                * Must blank CRTC after disabling power gating and before any
+                * programming, otherwise CRTC will be hung in bad state
+                */
+               pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
+
+               if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
+                               pipe_ctx->clock_source,
+                               &pipe_ctx->stream_res.pix_clk_params,
+                               dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                               &pipe_ctx->pll_settings)) {
+                       BREAK_TO_DEBUGGER();
+                       return DC_ERROR_UNEXPECTED;
+               }
+
+               if (dc_is_hdmi_tmds_signal(stream->signal)) {
+                       stream->link->phy_state.symclk_ref_cnts.otg = 1;
+                       if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
+                               stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+                       else
+                               stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+               }
+
+               pipe_ctx->stream_res.tg->funcs->program_timing(
+                               pipe_ctx->stream_res.tg,
+                               &stream->timing,
+                               0,
+                               0,
+                               0,
+                               0,
+                               pipe_ctx->stream->signal,
+                               true);
+       }
+
+       if (!pipe_ctx_old->stream) {
+               if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(
+                               pipe_ctx->stream_res.tg)) {
+                       BREAK_TO_DEBUGGER();
+                       return DC_ERROR_UNEXPECTED;
+               }
+       }
+
+       return DC_OK;
+}
+
+static enum dc_status apply_single_controller_ctx_to_hw(
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context,
+               struct dc *dc)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct drr_params params = {0};
+       unsigned int event_triggers = 0;
+       struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
+       struct dce_hwseq *hws = dc->hwseq;
+       const struct link_hwss *link_hwss = get_link_hwss(
+                       link, &pipe_ctx->link_res);
+
+
+       if (hws->funcs.disable_stream_gating) {
+               hws->funcs.disable_stream_gating(dc, pipe_ctx);
+       }
+
+       if (pipe_ctx->stream_res.audio != NULL) {
+               struct audio_output audio_output;
+
+               build_audio_output(context, pipe_ctx, &audio_output);
+
+               link_hwss->setup_audio_output(pipe_ctx, &audio_output,
+                               pipe_ctx->stream_res.audio->inst);
+
+               pipe_ctx->stream_res.audio->funcs->az_configure(
+                               pipe_ctx->stream_res.audio,
+                               pipe_ctx->stream->signal,
+                               &audio_output.crtc_info,
+                               &pipe_ctx->stream->audio_info);
+       }
+
+       /* make sure no pipes syncd to the pipe being enabled */
+       if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic)
+               check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx);
+
+       pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
+               pipe_ctx->stream_res.opp,
+               &stream->bit_depth_params,
+               &stream->clamping);
+
+       pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
+                       pipe_ctx->stream_res.opp,
+                       COLOR_SPACE_YCBCR601,
+                       stream->timing.display_color_depth,
+                       stream->signal);
+
+       while (odm_pipe) {
+               odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion(
+                               odm_pipe->stream_res.opp,
+                               COLOR_SPACE_YCBCR601,
+                               stream->timing.display_color_depth,
+                               stream->signal);
+
+               odm_pipe->stream_res.opp->funcs->opp_program_fmt(
+                               odm_pipe->stream_res.opp,
+                               &stream->bit_depth_params,
+                               &stream->clamping);
+               odm_pipe = odm_pipe->next_odm_pipe;
+       }
+
+       /* DCN3.1 FPGA Workaround
+        * Need to enable HPO DP Stream Encoder before setting OTG master enable.
+        * To do so, move calling function enable_stream_timing to only be done AFTER calling
+        * function core_link_enable_stream
+        */
+       if (!(hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)))
+               /*  */
+               /* Do not touch stream timing on seamless boot optimization. */
+               if (!pipe_ctx->stream->apply_seamless_boot_optimization)
+                       hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
+
+       if (hws->funcs.setup_vupdate_interrupt)
+               hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
+
+       params.vertical_total_min = stream->adjust.v_total_min;
+       params.vertical_total_max = stream->adjust.v_total_max;
+       if (pipe_ctx->stream_res.tg->funcs->set_drr)
+               pipe_ctx->stream_res.tg->funcs->set_drr(
+                       pipe_ctx->stream_res.tg, &params);
+
+       // DRR should set trigger event to monitor surface update event
+       if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
+               event_triggers = 0x80;
+       /* Event triggers and num frames initialized for DRR, but can be
+        * later updated for PSR use. Note DRR trigger events are generated
+        * regardless of whether num frames met.
+        */
+       if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
+               pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
+                               pipe_ctx->stream_res.tg, event_triggers, 2);
+
+       if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
+               pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
+                       pipe_ctx->stream_res.stream_enc,
+                       pipe_ctx->stream_res.tg->inst);
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal))
+               dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
+
+       if (!stream->dpms_off)
+               dc->link_srv->set_dpms_on(context, pipe_ctx);
+
+       /* DCN3.1 FPGA Workaround
+        * Need to enable HPO DP Stream Encoder before setting OTG master enable.
+        * To do so, move calling function enable_stream_timing to only be done AFTER calling
+        * function core_link_enable_stream
+        */
+       if (hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               if (!pipe_ctx->stream->apply_seamless_boot_optimization)
+                       hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
+       }
+
+       pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
+
+       /* Phantom and main stream share the same link (because the stream
+        * is constructed with the same sink). Make sure not to override
+        * and link programming on the main.
+        */
+       if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+               pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
+               pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false;
+       }
+       return DC_OK;
+}
+
+/******************************************************************************/
+
+static void power_down_encoders(struct dc *dc)
+{
+       int i;
+
+       for (i = 0; i < dc->link_count; i++) {
+               enum signal_type signal = dc->links[i]->connector_signal;
+
+               dc->link_srv->blank_dp_stream(dc->links[i], false);
+
+               if (signal != SIGNAL_TYPE_EDP)
+                       signal = SIGNAL_TYPE_NONE;
+
+               if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY)
+                       dc->links[i]->link_enc->funcs->disable_output(
+                                       dc->links[i]->link_enc, signal);
+
+               dc->links[i]->link_status.link_active = false;
+               memset(&dc->links[i]->cur_link_settings, 0,
+                               sizeof(dc->links[i]->cur_link_settings));
+       }
+}
+
+static void power_down_controllers(struct dc *dc)
+{
+       int i;
+
+       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+               dc->res_pool->timing_generators[i]->funcs->disable_crtc(
+                               dc->res_pool->timing_generators[i]);
+       }
+}
+
+static void power_down_clock_sources(struct dc *dc)
+{
+       int i;
+
+       if (dc->res_pool->dp_clock_source->funcs->cs_power_down(
+               dc->res_pool->dp_clock_source) == false)
+               dm_error("Failed to power down pll! (dp clk src)\n");
+
+       for (i = 0; i < dc->res_pool->clk_src_count; i++) {
+               if (dc->res_pool->clock_sources[i]->funcs->cs_power_down(
+                               dc->res_pool->clock_sources[i]) == false)
+                       dm_error("Failed to power down pll! (clk src index=%d)\n", i);
+       }
+}
+
+static void power_down_all_hw_blocks(struct dc *dc)
+{
+       power_down_encoders(dc);
+
+       power_down_controllers(dc);
+
+       power_down_clock_sources(dc);
+
+       if (dc->fbc_compressor)
+               dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
+}
+
+static void disable_vga_and_power_gate_all_controllers(
+               struct dc *dc)
+{
+       int i;
+       struct timing_generator *tg;
+       struct dc_context *ctx = dc->ctx;
+
+       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+               tg = dc->res_pool->timing_generators[i];
+
+               if (tg->funcs->disable_vga)
+                       tg->funcs->disable_vga(tg);
+       }
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               /* Enable CLOCK gating for each pipe BEFORE controller
+                * powergating. */
+               enable_display_pipe_clock_gating(ctx,
+                               true);
+
+               dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i;
+               dc->hwss.disable_plane(dc,
+                       &dc->current_state->res_ctx.pipe_ctx[i]);
+       }
+}
+
+
+static void get_edp_streams(struct dc_state *context,
+               struct dc_stream_state **edp_streams,
+               int *edp_stream_num)
+{
+       int i;
+
+       *edp_stream_num = 0;
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->streams[i]->signal == SIGNAL_TYPE_EDP) {
+                       edp_streams[*edp_stream_num] = context->streams[i];
+                       if (++(*edp_stream_num) == MAX_NUM_EDP)
+                               return;
+               }
+       }
+}
+
+static void get_edp_links_with_sink(
+               struct dc *dc,
+               struct dc_link **edp_links_with_sink,
+               int *edp_with_sink_num)
+{
+       int i;
+
+       /* check if there is an eDP panel not in use */
+       *edp_with_sink_num = 0;
+       for (i = 0; i < dc->link_count; i++) {
+               if (dc->links[i]->local_sink &&
+                       dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+                       edp_links_with_sink[*edp_with_sink_num] = dc->links[i];
+                       if (++(*edp_with_sink_num) == MAX_NUM_EDP)
+                               return;
+               }
+       }
+}
+
+/*
+ * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
+ *  1. Power down all DC HW blocks
+ *  2. Disable VGA engine on all controllers
+ *  3. Enable power gating for controller
+ *  4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
+ */
+void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
+{
+       struct dc_link *edp_links_with_sink[MAX_NUM_EDP];
+       struct dc_link *edp_links[MAX_NUM_EDP];
+       struct dc_stream_state *edp_streams[MAX_NUM_EDP];
+       struct dc_link *edp_link_with_sink = NULL;
+       struct dc_link *edp_link = NULL;
+       struct dce_hwseq *hws = dc->hwseq;
+       int edp_with_sink_num;
+       int edp_num;
+       int edp_stream_num;
+       int i;
+       bool can_apply_edp_fast_boot = false;
+       bool can_apply_seamless_boot = false;
+       bool keep_edp_vdd_on = false;
+       DC_LOGGER_INIT();
+
+
+       get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num);
+       dc_get_edp_links(dc, edp_links, &edp_num);
+
+       if (hws->funcs.init_pipes)
+               hws->funcs.init_pipes(dc, context);
+
+       get_edp_streams(context, edp_streams, &edp_stream_num);
+
+       // Check fastboot support, disable on DCE8 because of blank screens
+       if (edp_num && edp_stream_num && dc->ctx->dce_version != DCE_VERSION_8_0 &&
+                   dc->ctx->dce_version != DCE_VERSION_8_1 &&
+                   dc->ctx->dce_version != DCE_VERSION_8_3) {
+               for (i = 0; i < edp_num; i++) {
+                       edp_link = edp_links[i];
+                       if (edp_link != edp_streams[0]->link)
+                               continue;
+                       // enable fastboot if backend is enabled on eDP
+                       if (edp_link->link_enc->funcs->is_dig_enabled &&
+                           edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                           edp_link->link_status.link_active) {
+                               struct dc_stream_state *edp_stream = edp_streams[0];
+
+                               can_apply_edp_fast_boot = dc_validate_boot_timing(dc,
+                                       edp_stream->sink, &edp_stream->timing);
+                               edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot;
+                               if (can_apply_edp_fast_boot)
+                                       DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n");
+
+                               break;
+                       }
+               }
+               // We are trying to enable eDP, don't power down VDD
+               if (can_apply_edp_fast_boot)
+                       keep_edp_vdd_on = true;
+       }
+
+       // Check seamless boot support
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->streams[i]->apply_seamless_boot_optimization) {
+                       can_apply_seamless_boot = true;
+                       break;
+               }
+       }
+
+       /* eDP should not have stream in resume from S4 and so even with VBios post
+        * it should get turned off
+        */
+       if (edp_with_sink_num)
+               edp_link_with_sink = edp_links_with_sink[0];
+
+       if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) {
+               if (edp_link_with_sink && !keep_edp_vdd_on) {
+                       /*turn off backlight before DP_blank and encoder powered down*/
+                       hws->funcs.edp_backlight_control(edp_link_with_sink, false);
+               }
+               /*resume from S3, no vbios posting, no need to power down again*/
+               clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
+
+               power_down_all_hw_blocks(dc);
+               disable_vga_and_power_gate_all_controllers(dc);
+               if (edp_link_with_sink && !keep_edp_vdd_on)
+                       dc->hwss.edp_power_control(edp_link_with_sink, false);
+               clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
+       }
+       bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1);
+}
+
+static uint32_t compute_pstate_blackout_duration(
+       struct bw_fixed blackout_duration,
+       const struct dc_stream_state *stream)
+{
+       uint32_t total_dest_line_time_ns;
+       uint32_t pstate_blackout_duration_ns;
+
+       pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
+
+       total_dest_line_time_ns = 1000000UL *
+               (stream->timing.h_total * 10) /
+               stream->timing.pix_clk_100hz +
+               pstate_blackout_duration_ns;
+
+       return total_dest_line_time_ns;
+}
+
+static void dce110_set_displaymarks(
+       const struct dc *dc,
+       struct dc_state *context)
+{
+       uint8_t i, num_pipes;
+       unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
+
+       for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               uint32_t total_dest_line_time_ns;
+
+               if (pipe_ctx->stream == NULL)
+                       continue;
+
+               total_dest_line_time_ns = compute_pstate_blackout_duration(
+                       dc->bw_vbios->blackout_duration, pipe_ctx->stream);
+               pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
+                       pipe_ctx->plane_res.mi,
+                       context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
+                       context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
+                       context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes],
+                       context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
+                       total_dest_line_time_ns);
+               if (i == underlay_idx) {
+                       num_pipes++;
+                       pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
+                               pipe_ctx->plane_res.mi,
+                               context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
+                               context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
+                               context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
+                               total_dest_line_time_ns);
+               }
+               num_pipes++;
+       }
+}
+
+void dce110_set_safe_displaymarks(
+               struct resource_context *res_ctx,
+               const struct resource_pool *pool)
+{
+       int i;
+       int underlay_idx = pool->underlay_pipe_index;
+       struct dce_watermarks max_marks = {
+               MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK };
+       struct dce_watermarks nbp_marks = {
+               SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
+       struct dce_watermarks min_marks = { 0, 0, 0, 0};
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
+                       continue;
+
+               res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
+                               res_ctx->pipe_ctx[i].plane_res.mi,
+                               nbp_marks,
+                               max_marks,
+                               min_marks,
+                               max_marks,
+                               MAX_WATERMARK);
+
+               if (i == underlay_idx)
+                       res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
+                               res_ctx->pipe_ctx[i].plane_res.mi,
+                               nbp_marks,
+                               max_marks,
+                               max_marks,
+                               MAX_WATERMARK);
+
+       }
+}
+
+/*******************************************************************************
+ * Public functions
+ ******************************************************************************/
+
+static void set_drr(struct pipe_ctx **pipe_ctx,
+               int num_pipes, struct dc_crtc_timing_adjust adjust)
+{
+       int i = 0;
+       struct drr_params params = {0};
+       // DRR should set trigger event to monitor surface update event
+       unsigned int event_triggers = 0x80;
+       // Note DRR trigger events are generated regardless of whether num frames met.
+       unsigned int num_frames = 2;
+
+       params.vertical_total_max = adjust.v_total_max;
+       params.vertical_total_min = adjust.v_total_min;
+
+       /* TODO: If multiple pipes are to be supported, you need
+        * some GSL stuff. Static screen triggers may be programmed differently
+        * as well.
+        */
+       for (i = 0; i < num_pipes; i++) {
+               pipe_ctx[i]->stream_res.tg->funcs->set_drr(
+                       pipe_ctx[i]->stream_res.tg, &params);
+
+               if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
+                       pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
+                                       pipe_ctx[i]->stream_res.tg,
+                                       event_triggers, num_frames);
+       }
+}
+
+static void get_position(struct pipe_ctx **pipe_ctx,
+               int num_pipes,
+               struct crtc_position *position)
+{
+       int i = 0;
+
+       /* TODO: handle pipes > 1
+        */
+       for (i = 0; i < num_pipes; i++)
+               pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
+}
+
+static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
+               int num_pipes, const struct dc_static_screen_params *params)
+{
+       unsigned int i;
+       unsigned int triggers = 0;
+
+       if (params->triggers.overlay_update)
+               triggers |= 0x100;
+       if (params->triggers.surface_update)
+               triggers |= 0x80;
+       if (params->triggers.cursor_update)
+               triggers |= 0x2;
+       if (params->triggers.force_trigger)
+               triggers |= 0x1;
+
+       if (num_pipes) {
+               struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
+
+               if (dc->fbc_compressor)
+                       triggers |= 0x84;
+       }
+
+       for (i = 0; i < num_pipes; i++)
+               pipe_ctx[i]->stream_res.tg->funcs->
+                       set_static_screen_control(pipe_ctx[i]->stream_res.tg,
+                                       triggers, params->num_frames);
+}
+
+/*
+ *  Check if FBC can be enabled
+ */
+static bool should_enable_fbc(struct dc *dc,
+               struct dc_state *context,
+               uint32_t *pipe_idx)
+{
+       uint32_t i;
+       struct pipe_ctx *pipe_ctx = NULL;
+       struct resource_context *res_ctx = &context->res_ctx;
+       unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
+
+
+       ASSERT(dc->fbc_compressor);
+
+       /* FBC memory should be allocated */
+       if (!dc->ctx->fbc_gpu_addr)
+               return false;
+
+       /* Only supports single display */
+       if (context->stream_count != 1)
+               return false;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (res_ctx->pipe_ctx[i].stream) {
+
+                       pipe_ctx = &res_ctx->pipe_ctx[i];
+
+                       /* fbc not applicable on underlay pipe */
+                       if (pipe_ctx->pipe_idx != underlay_idx) {
+                               *pipe_idx = i;
+                               break;
+                       }
+               }
+       }
+
+       if (i == dc->res_pool->pipe_count)
+               return false;
+
+       if (!pipe_ctx->stream->link)
+               return false;
+
+       /* Only supports eDP */
+       if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
+               return false;
+
+       /* PSR should not be enabled */
+       if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
+               return false;
+
+       /* Replay should not be enabled */
+       if (pipe_ctx->stream->link->replay_settings.replay_feature_enabled)
+               return false;
+
+       /* Nothing to compress */
+       if (!pipe_ctx->plane_state)
+               return false;
+
+       /* Only for non-linear tiling */
+       if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
+               return false;
+
+       return true;
+}
+
+/*
+ *  Enable FBC
+ */
+static void enable_fbc(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       uint32_t pipe_idx = 0;
+
+       if (should_enable_fbc(dc, context, &pipe_idx)) {
+               /* Program GRPH COMPRESSED ADDRESS and PITCH */
+               struct compr_addr_and_pitch_params params = {0, 0, 0};
+               struct compressor *compr = dc->fbc_compressor;
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
+
+               params.source_view_width = pipe_ctx->stream->timing.h_addressable;
+               params.source_view_height = pipe_ctx->stream->timing.v_addressable;
+               params.inst = pipe_ctx->stream_res.tg->inst;
+               compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
+
+               compr->funcs->surface_address_and_pitch(compr, &params);
+               compr->funcs->set_fbc_invalidation_triggers(compr, 1);
+
+               compr->funcs->enable_fbc(compr, &params);
+       }
+}
+
+static void dce110_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+
+       /* Reset old context */
+       /* look up the targets that have been removed since last commit */
+       for (i = 0; i < MAX_PIPES; i++) {
+               struct pipe_ctx *pipe_ctx_old =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* Note: We need to disable output if clock sources change,
+                * since bios does optimization and doesn't apply if changing
+                * PHY when not already disabled.
+                */
+
+               /* Skip underlay pipe since it will be handled in commit surface*/
+               if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe)
+                       continue;
+
+               if (!pipe_ctx->stream ||
+                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
+
+                       /* Disable if new stream is null. O/w, if stream is
+                        * disabled already, no need to disable again.
+                        */
+                       if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
+                               dc->link_srv->set_dpms_off(pipe_ctx_old);
+
+                               /* free acquired resources*/
+                               if (pipe_ctx_old->stream_res.audio) {
+                                       /*disable az_endpoint*/
+                                       pipe_ctx_old->stream_res.audio->funcs->
+                                                       az_disable(pipe_ctx_old->stream_res.audio);
+
+                                       /*free audio*/
+                                       if (dc->caps.dynamic_audio == true) {
+                                               /*we have to dynamic arbitrate the audio endpoints*/
+                                               /*we free the resource, need reset is_audio_acquired*/
+                                               update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
+                                                               pipe_ctx_old->stream_res.audio, false);
+                                               pipe_ctx_old->stream_res.audio = NULL;
+                                       }
+                               }
+                       }
+
+                       pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
+                       if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
+                               dm_error("DC: failed to blank crtc!\n");
+                               BREAK_TO_DEBUGGER();
+                       }
+                       pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg);
+                       pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0;
+                       pipe_ctx_old->plane_res.mi->funcs->free_mem_input(
+                                       pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
+
+                       if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx,
+                                                                               dc->res_pool,
+                                                                               old_clk))
+                               old_clk->funcs->cs_power_down(old_clk);
+
+                       dc->hwss.disable_plane(dc, pipe_ctx_old);
+
+                       pipe_ctx_old->stream = NULL;
+               }
+       }
+}
+
+static void dce110_setup_audio_dto(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+
+       /* program audio wall clock. use HDMI as clock source if HDMI
+        * audio active. Otherwise, use DP as clock source
+        * first, loop to find any HDMI audio, if not, loop find DP audio
+        */
+       /* Setup audio rate clock source */
+       /* Issue:
+       * Audio lag happened on DP monitor when unplug a HDMI monitor
+       *
+       * Cause:
+       * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL
+       * is set to either dto0 or dto1, audio should work fine.
+       * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1,
+       * set to dto0 will cause audio lag.
+       *
+       * Solution:
+       * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx,
+       * find first available pipe with audio, setup audio wall DTO per topology
+       * instead of per pipe.
+       */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream == NULL)
+                       continue;
+
+               if (pipe_ctx->top_pipe)
+                       continue;
+               if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
+                       continue;
+               if (pipe_ctx->stream_res.audio != NULL) {
+                       struct audio_output audio_output;
+
+                       build_audio_output(context, pipe_ctx, &audio_output);
+
+                       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {
+                               struct dtbclk_dto_params dto_params = {0};
+
+                               dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
+                                       dc->res_pool->dccg, &dto_params);
+
+                               pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
+                                               pipe_ctx->stream_res.audio,
+                                               pipe_ctx->stream->signal,
+                                               &audio_output.crtc_info,
+                                               &audio_output.pll_info);
+                       } else
+                               pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
+                                       pipe_ctx->stream_res.audio,
+                                       pipe_ctx->stream->signal,
+                                       &audio_output.crtc_info,
+                                       &audio_output.pll_info);
+                       break;
+               }
+       }
+
+       /* no HDMI audio is found, try DP audio */
+       if (i == dc->res_pool->pipe_count) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+                       if (pipe_ctx->stream == NULL)
+                               continue;
+
+                       if (pipe_ctx->top_pipe)
+                               continue;
+
+                       if (!dc_is_dp_signal(pipe_ctx->stream->signal))
+                               continue;
+
+                       if (pipe_ctx->stream_res.audio != NULL) {
+                               struct audio_output audio_output;
+
+                               build_audio_output(context, pipe_ctx, &audio_output);
+
+                               pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
+                                       pipe_ctx->stream_res.audio,
+                                       pipe_ctx->stream->signal,
+                                       &audio_output.crtc_info,
+                                       &audio_output.pll_info);
+                               break;
+                       }
+               }
+       }
+}
+
+enum dc_status dce110_apply_ctx_to_hw(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+       enum dc_status status;
+       int i;
+
+       /* reset syncd pipes from disabled pipes */
+       if (dc->config.use_pipe_ctx_sync_logic)
+               reset_syncd_pipes_from_disabled_pipes(dc, context);
+
+       /* Reset old context */
+       /* look up the targets that have been removed since last commit */
+       hws->funcs.reset_hw_ctx_wrap(dc, context);
+
+       /* Skip applying if no targets */
+       if (context->stream_count <= 0)
+               return DC_OK;
+
+       /* Apply new context */
+       dcb->funcs->set_scratch_critical_state(dcb, true);
+
+       /* below is for real asic only */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx_old =
+                                       &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe)
+                       continue;
+
+               if (pipe_ctx->stream == pipe_ctx_old->stream) {
+                       if (pipe_ctx_old->clock_source != pipe_ctx->clock_source)
+                               dce_crtc_switch_to_clk_src(dc->hwseq,
+                                               pipe_ctx->clock_source, i);
+                       continue;
+               }
+
+               hws->funcs.enable_display_power_gating(
+                               dc, i, dc->ctx->dc_bios,
+                               PIPE_GATING_CONTROL_DISABLE);
+       }
+
+       if (dc->fbc_compressor)
+               dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
+
+       dce110_setup_audio_dto(dc, context);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx_old =
+                                       &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream == NULL)
+                       continue;
+
+               if (pipe_ctx->stream == pipe_ctx_old->stream &&
+                       pipe_ctx->stream->link->link_state_valid) {
+                       continue;
+               }
+
+               if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
+                       continue;
+
+               if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
+                       continue;
+
+               status = apply_single_controller_ctx_to_hw(
+                               pipe_ctx,
+                               context,
+                               dc);
+
+               if (DC_OK != status)
+                       return status;
+
+#ifdef CONFIG_DRM_AMD_DC_FP
+               if (hws->funcs.resync_fifo_dccg_dio)
+                       hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
+#endif
+       }
+
+       if (dc->fbc_compressor)
+               enable_fbc(dc, dc->current_state);
+
+       dcb->funcs->set_scratch_critical_state(dcb, false);
+
+       return DC_OK;
+}
+
+/*******************************************************************************
+ * Front End programming
+ ******************************************************************************/
+static void set_default_colors(struct pipe_ctx *pipe_ctx)
+{
+       struct default_adjustment default_adjust = { 0 };
+
+       default_adjust.force_hw_default = false;
+       default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
+       default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
+       default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
+       default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
+
+       /* display color depth */
+       default_adjust.color_depth =
+               pipe_ctx->stream->timing.display_color_depth;
+
+       /* Lb color depth */
+       default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
+
+       pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
+                                       pipe_ctx->plane_res.xfm, &default_adjust);
+}
+
+
+/*******************************************************************************
+ * In order to turn on/off specific surface we will program
+ * Blender + CRTC
+ *
+ * In case that we have two surfaces and they have a different visibility
+ * we can't turn off the CRTC since it will turn off the entire display
+ *
+ * |----------------------------------------------- |
+ * |bottom pipe|curr pipe  |              |         |
+ * |Surface    |Surface    | Blender      |  CRCT   |
+ * |visibility |visibility | Configuration|         |
+ * |------------------------------------------------|
+ * |   off     |    off    | CURRENT_PIPE | blank   |
+ * |   off     |    on     | CURRENT_PIPE | unblank |
+ * |   on      |    off    | OTHER_PIPE   | unblank |
+ * |   on      |    on     | BLENDING     | unblank |
+ * -------------------------------------------------|
+ *
+ ******************************************************************************/
+static void program_surface_visibility(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx)
+{
+       enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE;
+       bool blank_target = false;
+
+       if (pipe_ctx->bottom_pipe) {
+
+               /* For now we are supporting only two pipes */
+               ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL);
+
+               if (pipe_ctx->bottom_pipe->plane_state->visible) {
+                       if (pipe_ctx->plane_state->visible)
+                               blender_mode = BLND_MODE_BLENDING;
+                       else
+                               blender_mode = BLND_MODE_OTHER_PIPE;
+
+               } else if (!pipe_ctx->plane_state->visible)
+                       blank_target = true;
+
+       } else if (!pipe_ctx->plane_state->visible)
+               blank_target = true;
+
+       dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
+       pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
+
+}
+
+static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
+{
+       int i = 0;
+       struct xfm_grph_csc_adjustment adjust;
+       memset(&adjust, 0, sizeof(adjust));
+       adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+
+       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
+               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+
+               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+                       adjust.temperature_matrix[i] =
+                               pipe_ctx->stream->gamut_remap_matrix.matrix[i];
+       }
+
+       pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
+}
+static void update_plane_addr(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx)
+{
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+
+       if (plane_state == NULL)
+               return;
+
+       pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
+                       pipe_ctx->plane_res.mi,
+                       &plane_state->address,
+                       plane_state->flip_immediate);
+
+       plane_state->status.requested_address = plane_state->address;
+}
+
+static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+
+       if (plane_state == NULL)
+               return;
+
+       plane_state->status.is_flip_pending =
+                       pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
+                                       pipe_ctx->plane_res.mi);
+
+       if (plane_state->status.is_flip_pending && !plane_state->visible)
+               pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address;
+
+       plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
+       if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+                       pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) {
+               plane_state->status.is_right_eye =\
+                               !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
+       }
+}
+
+void dce110_power_down(struct dc *dc)
+{
+       power_down_all_hw_blocks(dc);
+       disable_vga_and_power_gate_all_controllers(dc);
+}
+
+static bool wait_for_reset_trigger_to_occur(
+       struct dc_context *dc_ctx,
+       struct timing_generator *tg)
+{
+       struct dc_context *ctx = dc_ctx;
+       bool rc = false;
+
+       /* To avoid endless loop we wait at most
+        * frames_to_wait_on_triggered_reset frames for the reset to occur. */
+       const uint32_t frames_to_wait_on_triggered_reset = 10;
+       uint32_t i;
+
+       for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
+
+               if (!tg->funcs->is_counter_moving(tg)) {
+                       DC_ERROR("TG counter is not moving!\n");
+                       break;
+               }
+
+               if (tg->funcs->did_triggered_reset_occur(tg)) {
+                       rc = true;
+                       /* usually occurs at i=1 */
+                       DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
+                                       i);
+                       break;
+               }
+
+               /* Wait for one frame. */
+               tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
+               tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
+       }
+
+       if (false == rc)
+               DC_ERROR("GSL: Timeout on reset trigger!\n");
+
+       return rc;
+}
+
+/* Enable timing synchronization for a group of Timing Generators. */
+static void dce110_enable_timing_synchronization(
+               struct dc *dc,
+               int group_index,
+               int group_size,
+               struct pipe_ctx *grouped_pipes[])
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct dcp_gsl_params gsl_params = { 0 };
+       int i;
+       DC_LOGGER_INIT();
+
+       DC_SYNC_INFO("GSL: Setting-up...\n");
+
+       /* Designate a single TG in the group as a master.
+        * Since HW doesn't care which one, we always assign
+        * the 1st one in the group. */
+       gsl_params.gsl_group = 0;
+       gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst;
+
+       for (i = 0; i < group_size; i++)
+               grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
+                                       grouped_pipes[i]->stream_res.tg, &gsl_params);
+
+       /* Reset slave controllers on master VSync */
+       DC_SYNC_INFO("GSL: enabling trigger-reset\n");
+
+       for (i = 1 /* skip the master */; i < group_size; i++)
+               grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
+                               grouped_pipes[i]->stream_res.tg,
+                               gsl_params.gsl_group);
+
+       for (i = 1 /* skip the master */; i < group_size; i++) {
+               DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
+               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
+               grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
+                               grouped_pipes[i]->stream_res.tg);
+       }
+
+       /* GSL Vblank synchronization is a one time sync mechanism, assumption
+        * is that the sync'ed displays will not drift out of sync over time*/
+       DC_SYNC_INFO("GSL: Restoring register states.\n");
+       for (i = 0; i < group_size; i++)
+               grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
+
+       DC_SYNC_INFO("GSL: Set-up complete.\n");
+}
+
+static void dce110_enable_per_frame_crtc_position_reset(
+               struct dc *dc,
+               int group_size,
+               struct pipe_ctx *grouped_pipes[])
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct dcp_gsl_params gsl_params = { 0 };
+       int i;
+       DC_LOGGER_INIT();
+
+       gsl_params.gsl_group = 0;
+       gsl_params.gsl_master = 0;
+
+       for (i = 0; i < group_size; i++)
+               grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
+                                       grouped_pipes[i]->stream_res.tg, &gsl_params);
+
+       DC_SYNC_INFO("GSL: enabling trigger-reset\n");
+
+       for (i = 1; i < group_size; i++)
+               grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
+                               grouped_pipes[i]->stream_res.tg,
+                               gsl_params.gsl_master,
+                               &grouped_pipes[i]->stream->triggered_crtc_reset);
+
+       DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
+       for (i = 1; i < group_size; i++)
+               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
+
+       for (i = 0; i < group_size; i++)
+               grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg);
+
+}
+
+static void init_pipes(struct dc *dc, struct dc_state *context)
+{
+       // Do nothing
+}
+
+static void init_hw(struct dc *dc)
+{
+       int i;
+       struct dc_bios *bp;
+       struct transform *xfm;
+       struct abm *abm;
+       struct dmcu *dmcu;
+       struct dce_hwseq *hws = dc->hwseq;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+
+       bp = dc->ctx->dc_bios;
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               xfm = dc->res_pool->transforms[i];
+               xfm->funcs->transform_reset(xfm);
+
+               hws->funcs.enable_display_power_gating(
+                               dc, i, bp,
+                               PIPE_GATING_CONTROL_INIT);
+               hws->funcs.enable_display_power_gating(
+                               dc, i, bp,
+                               PIPE_GATING_CONTROL_DISABLE);
+               hws->funcs.enable_display_pipe_clock_gating(
+                       dc->ctx,
+                       true);
+       }
+
+       dce_clock_gating_power_up(dc->hwseq, false);
+       /***************************************/
+
+       for (i = 0; i < dc->link_count; i++) {
+               /****************************************/
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector). */
+               struct dc_link *link = dc->links[i];
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+               tg->funcs->disable_vga(tg);
+
+               /* Blank controller using driver code instead of
+                * command table. */
+               tg->funcs->set_blank(tg, true);
+               hwss_wait_for_blank_complete(tg);
+       }
+
+       for (i = 0; i < dc->res_pool->audio_count; i++) {
+               struct audio *audio = dc->res_pool->audios[i];
+               audio->funcs->hw_init(audio);
+       }
+
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               if (link->panel_cntl)
+                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
+       }
+
+       abm = dc->res_pool->abm;
+       if (abm != NULL)
+               abm->funcs->abm_init(abm, backlight);
+
+       dmcu = dc->res_pool->dmcu;
+       if (dmcu != NULL && abm != NULL)
+               abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
+
+       if (dc->fbc_compressor)
+               dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
+
+}
+
+
+void dce110_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct clk_mgr *dccg = dc->clk_mgr;
+
+       dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
+       if (dccg)
+               dccg->funcs->update_clocks(
+                               dccg,
+                               context,
+                               false);
+}
+
+void dce110_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct clk_mgr *dccg = dc->clk_mgr;
+
+       dce110_set_displaymarks(dc, context);
+
+       if (dccg)
+               dccg->funcs->update_clocks(
+                               dccg,
+                               context,
+                               true);
+}
+
+static void dce110_program_front_end_for_pipe(
+               struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct mem_input *mi = pipe_ctx->plane_res.mi;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       struct xfm_grph_csc_adjustment adjust;
+       struct out_csc_color_matrix tbl_entry;
+       unsigned int i;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       memset(&tbl_entry, 0, sizeof(tbl_entry));
+
+       memset(&adjust, 0, sizeof(adjust));
+       adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+       dce_enable_fe_clock(dc->hwseq, mi->inst, true);
+
+       set_default_colors(pipe_ctx);
+       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
+                       == true) {
+               tbl_entry.color_space =
+                       pipe_ctx->stream->output_color_space;
+
+               for (i = 0; i < 12; i++)
+                       tbl_entry.regval[i] =
+                       pipe_ctx->stream->csc_color_matrix.matrix[i];
+
+               pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
+                               (pipe_ctx->plane_res.xfm, &tbl_entry);
+       }
+
+       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
+               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+
+               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+                       adjust.temperature_matrix[i] =
+                               pipe_ctx->stream->gamut_remap_matrix.matrix[i];
+       }
+
+       pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
+
+       pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
+
+       program_scaler(dc, pipe_ctx);
+
+       mi->funcs->mem_input_program_surface_config(
+                       mi,
+                       plane_state->format,
+                       &plane_state->tiling_info,
+                       &plane_state->plane_size,
+                       plane_state->rotation,
+                       NULL,
+                       false);
+       if (mi->funcs->set_blank)
+               mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
+
+       if (dc->config.gpu_vm_support)
+               mi->funcs->mem_input_program_pte_vm(
+                               pipe_ctx->plane_res.mi,
+                               plane_state->format,
+                               &plane_state->tiling_info,
+                               plane_state->rotation);
+
+       /* Moved programming gamma from dc to hwss */
+       if (pipe_ctx->plane_state->update_flags.bits.full_update ||
+                       pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+                       pipe_ctx->plane_state->update_flags.bits.gamma_change)
+               hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
+
+       if (pipe_ctx->plane_state->update_flags.bits.full_update)
+               hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
+
+       DC_LOG_SURFACE(
+                       "Pipe:%d %p: addr hi:0x%x, "
+                       "addr low:0x%x, "
+                       "src: %d, %d, %d,"
+                       " %d; dst: %d, %d, %d, %d;"
+                       "clip: %d, %d, %d, %d\n",
+                       pipe_ctx->pipe_idx,
+                       (void *) pipe_ctx->plane_state,
+                       pipe_ctx->plane_state->address.grph.addr.high_part,
+                       pipe_ctx->plane_state->address.grph.addr.low_part,
+                       pipe_ctx->plane_state->src_rect.x,
+                       pipe_ctx->plane_state->src_rect.y,
+                       pipe_ctx->plane_state->src_rect.width,
+                       pipe_ctx->plane_state->src_rect.height,
+                       pipe_ctx->plane_state->dst_rect.x,
+                       pipe_ctx->plane_state->dst_rect.y,
+                       pipe_ctx->plane_state->dst_rect.width,
+                       pipe_ctx->plane_state->dst_rect.height,
+                       pipe_ctx->plane_state->clip_rect.x,
+                       pipe_ctx->plane_state->clip_rect.y,
+                       pipe_ctx->plane_state->clip_rect.width,
+                       pipe_ctx->plane_state->clip_rect.height);
+
+       DC_LOG_SURFACE(
+                       "Pipe %d: width, height, x, y\n"
+                       "viewport:%d, %d, %d, %d\n"
+                       "recout:  %d, %d, %d, %d\n",
+                       pipe_ctx->pipe_idx,
+                       pipe_ctx->plane_res.scl_data.viewport.width,
+                       pipe_ctx->plane_res.scl_data.viewport.height,
+                       pipe_ctx->plane_res.scl_data.viewport.x,
+                       pipe_ctx->plane_res.scl_data.viewport.y,
+                       pipe_ctx->plane_res.scl_data.recout.width,
+                       pipe_ctx->plane_res.scl_data.recout.height,
+                       pipe_ctx->plane_res.scl_data.recout.x,
+                       pipe_ctx->plane_res.scl_data.recout.y);
+}
+
+static void dce110_apply_ctx_for_surface(
+               struct dc *dc,
+               const struct dc_stream_state *stream,
+               int num_planes,
+               struct dc_state *context)
+{
+       int i;
+
+       if (num_planes == 0)
+               return;
+
+       if (dc->fbc_compressor)
+               dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream != stream)
+                       continue;
+
+               /* Need to allocate mem before program front end for Fiji */
+               pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
+                               pipe_ctx->plane_res.mi,
+                               pipe_ctx->stream->timing.h_total,
+                               pipe_ctx->stream->timing.v_total,
+                               pipe_ctx->stream->timing.pix_clk_100hz / 10,
+                               context->stream_count);
+
+               dce110_program_front_end_for_pipe(dc, pipe_ctx);
+
+               dc->hwss.update_plane_addr(dc, pipe_ctx);
+
+               program_surface_visibility(dc, pipe_ctx);
+
+       }
+
+       if (dc->fbc_compressor)
+               enable_fbc(dc, context);
+}
+
+static void dce110_post_unlock_program_front_end(
+               struct dc *dc,
+               struct dc_state *context)
+{
+}
+
+static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       int fe_idx = pipe_ctx->plane_res.mi ?
+               pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
+
+       /* Do not power down fe when stream is active on dce*/
+       if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
+               return;
+
+       hws->funcs.enable_display_power_gating(
+               dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
+
+       dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
+                               dc->res_pool->transforms[fe_idx]);
+}
+
+static void dce110_wait_for_mpcc_disconnect(
+               struct dc *dc,
+               struct resource_pool *res_pool,
+               struct pipe_ctx *pipe_ctx)
+{
+       /* do nothing*/
+}
+
+static void program_output_csc(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum dc_color_space colorspace,
+               uint16_t *matrix,
+               int opp_id)
+{
+       int i;
+       struct out_csc_color_matrix tbl_entry;
+
+       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
+               enum dc_color_space color_space = pipe_ctx->stream->output_color_space;
+
+               for (i = 0; i < 12; i++)
+                       tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
+
+               tbl_entry.color_space = color_space;
+
+               pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
+                               pipe_ctx->plane_res.xfm, &tbl_entry);
+       }
+}
+
+static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+       struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+       struct mem_input *mi = pipe_ctx->plane_res.mi;
+       struct dc_cursor_mi_param param = {
+               .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
+               .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz,
+               .viewport = pipe_ctx->plane_res.scl_data.viewport,
+               .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
+               .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
+               .rotation = pipe_ctx->plane_state->rotation,
+               .mirror = pipe_ctx->plane_state->horizontal_mirror
+       };
+
+       /**
+        * If the cursor's source viewport is clipped then we need to
+        * translate the cursor to appear in the correct position on
+        * the screen.
+        *
+        * This translation isn't affected by scaling so it needs to be
+        * done *after* we adjust the position for the scale factor.
+        *
+        * This is only done by opt-in for now since there are still
+        * some usecases like tiled display that might enable the
+        * cursor on both streams while expecting dc to clip it.
+        */
+       if (pos_cpy.translate_by_source) {
+               pos_cpy.x += pipe_ctx->plane_state->src_rect.x;
+               pos_cpy.y += pipe_ctx->plane_state->src_rect.y;
+       }
+
+       if (pipe_ctx->plane_state->address.type
+                       == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+               pos_cpy.enable = false;
+
+       if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
+               pos_cpy.enable = false;
+
+       if (ipp->funcs->ipp_cursor_set_position)
+               ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+       if (mi->funcs->set_cursor_position)
+               mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+}
+
+static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+       if (pipe_ctx->plane_res.ipp &&
+           pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
+               pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
+                               pipe_ctx->plane_res.ipp, attributes);
+
+       if (pipe_ctx->plane_res.mi &&
+           pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
+               pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
+                               pipe_ctx->plane_res.mi, attributes);
+
+       if (pipe_ctx->plane_res.xfm &&
+           pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
+               pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
+                               pipe_ctx->plane_res.xfm, attributes);
+}
+
+bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
+               uint32_t backlight_pwm_u16_16,
+               uint32_t frame_ramp)
+{
+       struct dc_link *link = pipe_ctx->stream->link;
+       struct dc  *dc = link->ctx->dc;
+       struct abm *abm = pipe_ctx->stream_res.abm;
+       struct panel_cntl *panel_cntl = link->panel_cntl;
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+       bool fw_set_brightness = true;
+       /* DMCU -1 for all controller id values,
+        * therefore +1 here
+        */
+       uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
+
+       if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
+               return false;
+
+       if (dmcu)
+               fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
+
+       if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
+               panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
+       else
+               abm->funcs->set_backlight_level_pwm(
+                               abm,
+                               backlight_pwm_u16_16,
+                               frame_ramp,
+                               controller_id,
+                               link->panel_cntl->inst);
+
+       return true;
+}
+
+void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
+{
+       struct abm *abm = pipe_ctx->stream_res.abm;
+       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
+
+       if (abm)
+               abm->funcs->set_abm_immediate_disable(abm,
+                               pipe_ctx->stream->link->panel_cntl->inst);
+
+       if (panel_cntl)
+               panel_cntl->funcs->store_backlight_level(panel_cntl);
+}
+
+void dce110_set_pipe(struct pipe_ctx *pipe_ctx)
+{
+       struct abm *abm = pipe_ctx->stream_res.abm;
+       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
+       uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1;
+
+       if (abm && panel_cntl)
+               abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst);
+}
+
+void dce110_enable_lvds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum clock_source_id clock_source,
+               uint32_t pixel_clock)
+{
+       link->link_enc->funcs->enable_lvds_output(
+                       link->link_enc,
+                       clock_source,
+                       pixel_clock);
+       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+}
+
+void dce110_enable_tmds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               enum dc_color_depth color_depth,
+               uint32_t pixel_clock)
+{
+       link->link_enc->funcs->enable_tmds_output(
+                       link->link_enc,
+                       clock_source,
+                       color_depth,
+                       signal,
+                       pixel_clock);
+       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+}
+
+void dce110_enable_dp_link_output(
+               struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               const struct dc_link_settings *link_settings)
+{
+       struct dc  *dc = link->ctx->dc;
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+       struct pipe_ctx *pipes =
+                       link->dc->current_state->res_ctx.pipe_ctx;
+       struct clock_source *dp_cs =
+                       link->dc->res_pool->dp_clock_source;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       unsigned int i;
+
+       /*
+        * Add the logic to extract BOTH power up and power down sequences
+        * from enable/disable link output and only call edp panel control
+        * in enable_link_dp and disable_link_dp once.
+        */
+       if (link->connector_signal == SIGNAL_TYPE_EDP) {
+               link->dc->hwss.edp_wait_for_hpd_ready(link, true);
+       }
+
+       /* If the current pixel clock source is not DTO(happens after
+        * switching from HDMI passive dongle to DP on the same connector),
+        * switch the pixel clock source to DTO.
+        */
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (pipes[i].stream != NULL &&
+                               pipes[i].stream->link == link) {
+                       if (pipes[i].clock_source != NULL &&
+                                       pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
+                               pipes[i].clock_source = dp_cs;
+                               pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
+                                               pipes[i].stream->timing.pix_clk_100hz;
+                               pipes[i].clock_source->funcs->program_pix_clk(
+                                               pipes[i].clock_source,
+                                               &pipes[i].stream_res.pix_clk_params,
+                                               dc->link_srv->dp_get_encoding_format(link_settings),
+                                               &pipes[i].pll_settings);
+                       }
+               }
+       }
+
+       if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
+               if (dc->clk_mgr->funcs->notify_link_rate_change)
+                       dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
+       }
+
+       if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       if (link_hwss->ext.enable_dp_link_output)
+               link_hwss->ext.enable_dp_link_output(link, link_res, signal,
+                               clock_source, link_settings);
+
+       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+
+       if (dmcu != NULL && dmcu->funcs->unlock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
+}
+
+void dce110_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal)
+{
+       struct dc *dc = link->ctx->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control)
+               link->dc->hwss.edp_backlight_control(link, false);
+       else if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       link_hwss->disable_link_output(link, link_res, signal);
+       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+       /*
+        * Add the logic to extract BOTH power up and power down sequences
+        * from enable/disable link output and only call edp panel control
+        * in enable_link_dp and disable_link_dp once.
+        */
+       if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+}
+
+static const struct hw_sequencer_funcs dce110_funcs = {
+       .program_gamut_remap = program_gamut_remap,
+       .program_output_csc = program_output_csc,
+       .init_hw = init_hw,
+       .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
+       .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
+       .post_unlock_program_front_end = dce110_post_unlock_program_front_end,
+       .update_plane_addr = update_plane_addr,
+       .update_pending_status = dce110_update_pending_status,
+       .enable_accelerated_mode = dce110_enable_accelerated_mode,
+       .enable_timing_synchronization = dce110_enable_timing_synchronization,
+       .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
+       .update_info_frame = dce110_update_info_frame,
+       .enable_stream = dce110_enable_stream,
+       .disable_stream = dce110_disable_stream,
+       .unblank_stream = dce110_unblank_stream,
+       .blank_stream = dce110_blank_stream,
+       .enable_audio_stream = dce110_enable_audio_stream,
+       .disable_audio_stream = dce110_disable_audio_stream,
+       .disable_plane = dce110_power_down_fe,
+       .pipe_control_lock = dce_pipe_control_lock,
+       .interdependent_update_lock = NULL,
+       .cursor_lock = dce_pipe_control_lock,
+       .prepare_bandwidth = dce110_prepare_bandwidth,
+       .optimize_bandwidth = dce110_optimize_bandwidth,
+       .set_drr = set_drr,
+       .get_position = get_position,
+       .set_static_screen_control = set_static_screen_control,
+       .setup_stereo = NULL,
+       .set_avmute = dce110_set_avmute,
+       .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
+       .edp_backlight_control = dce110_edp_backlight_control,
+       .edp_power_control = dce110_edp_power_control,
+       .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
+       .set_cursor_position = dce110_set_cursor_position,
+       .set_cursor_attribute = dce110_set_cursor_attribute,
+       .set_backlight_level = dce110_set_backlight_level,
+       .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
+       .set_pipe = dce110_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
+};
+
+static const struct hwseq_private_funcs dce110_private_funcs = {
+       .init_pipes = init_pipes,
+       .update_plane_addr = update_plane_addr,
+       .set_input_transfer_func = dce110_set_input_transfer_func,
+       .set_output_transfer_func = dce110_set_output_transfer_func,
+       .power_down = dce110_power_down,
+       .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
+       .enable_display_power_gating = dce110_enable_display_power_gating,
+       .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
+       .enable_stream_timing = dce110_enable_stream_timing,
+       .disable_stream_gating = NULL,
+       .enable_stream_gating = NULL,
+       .edp_backlight_control = dce110_edp_backlight_control,
+};
+
+void dce110_hw_sequencer_construct(struct dc *dc)
+{
+       dc->hwss = dce110_funcs;
+       dc->hwseq->funcs = dce110_private_funcs;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.h
new file mode 100644 (file)
index 0000000..08028a1
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+* 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_HWSS_DCE110_H__
+#define __DC_HWSS_DCE110_H__
+
+#include "core_types.h"
+#include "hw_sequencer_private.h"
+
+struct dc;
+struct dc_state;
+struct dm_pp_display_configuration;
+
+void dce110_hw_sequencer_construct(struct dc *dc);
+
+enum dc_status dce110_apply_ctx_to_hw(
+               struct dc *dc,
+               struct dc_state *context);
+
+
+void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
+
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx);
+
+void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings);
+
+void dce110_blank_stream(struct pipe_ctx *pipe_ctx);
+
+void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx);
+void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx);
+
+void dce110_update_info_frame(struct pipe_ctx *pipe_ctx);
+
+void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
+void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context);
+
+void dce110_power_down(struct dc *dc);
+
+void dce110_set_safe_displaymarks(
+               struct resource_context *res_ctx,
+               const struct resource_pool *pool);
+
+void dce110_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+
+void dce110_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+
+void dce110_edp_power_control(
+               struct dc_link *link,
+               bool power_up);
+
+void dce110_edp_backlight_control(
+       struct dc_link *link,
+       bool enable);
+
+void dce110_edp_wait_for_hpd_ready(
+               struct dc_link *link,
+               bool power_up);
+
+bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
+               uint32_t backlight_pwm_u16_16,
+               uint32_t frame_ramp);
+void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
+void dce110_set_pipe(struct pipe_ctx *pipe_ctx);
+void dce110_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal);
+void dce110_enable_lvds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum clock_source_id clock_source,
+               uint32_t pixel_clock);
+void dce110_enable_tmds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               enum dc_color_depth color_depth,
+               uint32_t pixel_clock);
+void dce110_enable_dp_link_output(
+               struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               const struct dc_link_settings *link_settings);
+#endif /* __DC_HWSS_DCE110_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce112/dce112_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce112/dce112_hwseq.c
new file mode 100644 (file)
index 0000000..ed9b011
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015 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 "dm_services.h"
+#include "dc.h"
+#include "core_types.h"
+#include "dce112_hwseq.h"
+
+#include "dce110/dce110_hwseq.h"
+
+/* include DCE11.2 register header files */
+#include "dce/dce_11_2_d.h"
+#include "dce/dce_11_2_sh_mask.h"
+
+struct dce112_hw_seq_reg_offsets {
+       uint32_t crtc;
+};
+
+
+static const struct dce112_hw_seq_reg_offsets reg_offsets[] = {
+{
+       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
+}
+};
+#define HW_REG_CRTC(reg, id)\
+       (reg + reg_offsets[id].crtc)
+
+/*******************************************************************************
+ * Private definitions
+ ******************************************************************************/
+
+static void dce112_init_pte(struct dc_context *ctx)
+{
+       uint32_t addr;
+       uint32_t value = 0;
+       uint32_t chunk_int = 0;
+       uint32_t chunk_mul = 0;
+
+       addr = mmDVMM_PTE_REQ;
+       value = dm_read_reg(ctx, addr);
+
+       chunk_int = get_reg_field_value(
+               value,
+               DVMM_PTE_REQ,
+               HFLIP_PTEREQ_PER_CHUNK_INT);
+
+       chunk_mul = get_reg_field_value(
+               value,
+               DVMM_PTE_REQ,
+               HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
+
+       if (chunk_int != 0x4 || chunk_mul != 0x4) {
+
+               set_reg_field_value(
+                       value,
+                       255,
+                       DVMM_PTE_REQ,
+                       MAX_PTEREQ_TO_ISSUE);
+
+               set_reg_field_value(
+                       value,
+                       4,
+                       DVMM_PTE_REQ,
+                       HFLIP_PTEREQ_PER_CHUNK_INT);
+
+               set_reg_field_value(
+                       value,
+                       4,
+                       DVMM_PTE_REQ,
+                       HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
+
+               dm_write_reg(ctx, addr, value);
+       }
+}
+
+static bool dce112_enable_display_power_gating(
+       struct dc *dc,
+       uint8_t controller_id,
+       struct dc_bios *dcb,
+       enum pipe_gating_control power_gating)
+{
+       enum bp_result bp_result = BP_RESULT_OK;
+       enum bp_pipe_control_action cntl;
+       struct dc_context *ctx = dc->ctx;
+
+       if (power_gating == PIPE_GATING_CONTROL_INIT)
+               cntl = ASIC_PIPE_INIT;
+       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
+               cntl = ASIC_PIPE_ENABLE;
+       else
+               cntl = ASIC_PIPE_DISABLE;
+
+       if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
+
+               bp_result = dcb->funcs->enable_disp_power_gating(
+                                               dcb, controller_id + 1, cntl);
+
+               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
+                * by default when command table is called
+                */
+               dm_write_reg(ctx,
+                       HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
+                       0);
+       }
+
+       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
+               dce112_init_pte(ctx);
+
+       if (bp_result == BP_RESULT_OK)
+               return true;
+       else
+               return false;
+}
+
+void dce112_hw_sequencer_construct(struct dc *dc)
+{
+       /* All registers used by dce11.2 match those in dce11 in offset and
+        * structure
+        */
+       dce110_hw_sequencer_construct(dc);
+       dc->hwseq->funcs.enable_display_power_gating = dce112_enable_display_power_gating;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce112/dce112_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce112/dce112_hwseq.h
new file mode 100644 (file)
index 0000000..943f1b2
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+* 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_HWSS_DCE112_H__
+#define __DC_HWSS_DCE112_H__
+
+#include "core_types.h"
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dce112_hw_sequencer_construct(struct dc *dc);
+
+#endif /* __DC_HWSS_DCE112_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c
new file mode 100644 (file)
index 0000000..22ee304
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2015 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 "dm_services.h"
+#include "dc.h"
+#include "core_types.h"
+#include "dce120_hwseq.h"
+#include "dce/dce_hwseq.h"
+
+#include "dce110/dce110_hwseq.h"
+
+#include "dce/dce_12_0_offset.h"
+#include "dce/dce_12_0_sh_mask.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.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
+
+struct dce120_hw_seq_reg_offsets {
+       uint32_t crtc;
+};
+
+#if 0
+static const struct dce120_hw_seq_reg_offsets reg_offsets[] = {
+{
+       .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
+},
+{
+       .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
+}
+};
+
+#define HW_REG_CRTC(reg, id)\
+       (reg + reg_offsets[id].crtc)
+
+#define CNTL_ID(controller_id)\
+       controller_id
+/*******************************************************************************
+ * Private definitions
+ ******************************************************************************/
+static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id)
+{
+       uint32_t addr;
+       uint32_t value = 0;
+       uint32_t chunk_int = 0;
+       uint32_t chunk_mul = 0;
+/*
+       addr = mmDCP0_DVMM_PTE_CONTROL + controller_id *
+                       (mmDCP1_DVMM_PTE_CONTROL- mmDCP0_DVMM_PTE_CONTROL);
+
+       value = dm_read_reg(ctx, addr);
+
+       set_reg_field_value(
+                       value, 0, DCP, controller_id,
+                       DVMM_PTE_CONTROL,
+                       DVMM_USE_SINGLE_PTE);
+
+       set_reg_field_value_soc15(
+                       value, 1, DCP, controller_id,
+                       DVMM_PTE_CONTROL,
+                       DVMM_PTE_BUFFER_MODE0);
+
+       set_reg_field_value_soc15(
+                       value, 1, DCP, controller_id,
+                       DVMM_PTE_CONTROL,
+                       DVMM_PTE_BUFFER_MODE1);
+
+       dm_write_reg(ctx, addr, value);*/
+
+       addr = mmDVMM_PTE_REQ;
+       value = dm_read_reg(ctx, addr);
+
+       chunk_int = get_reg_field_value(
+               value,
+               DVMM_PTE_REQ,
+               HFLIP_PTEREQ_PER_CHUNK_INT);
+
+       chunk_mul = get_reg_field_value(
+               value,
+               DVMM_PTE_REQ,
+               HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
+
+       if (chunk_int != 0x4 || chunk_mul != 0x4) {
+
+               set_reg_field_value(
+                       value,
+                       255,
+                       DVMM_PTE_REQ,
+                       MAX_PTEREQ_TO_ISSUE);
+
+               set_reg_field_value(
+                       value,
+                       4,
+                       DVMM_PTE_REQ,
+                       HFLIP_PTEREQ_PER_CHUNK_INT);
+
+               set_reg_field_value(
+                       value,
+                       4,
+                       DVMM_PTE_REQ,
+                       HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
+
+               dm_write_reg(ctx, addr, value);
+       }
+}
+#endif
+
+static bool dce120_enable_display_power_gating(
+       struct dc *dc,
+       uint8_t controller_id,
+       struct dc_bios *dcb,
+       enum pipe_gating_control power_gating)
+{
+       /* disable for bringup */
+#if 0
+       enum bp_result bp_result = BP_RESULT_OK;
+       enum bp_pipe_control_action cntl;
+       struct dc_context *ctx = dc->ctx;
+
+       if (power_gating == PIPE_GATING_CONTROL_INIT)
+               cntl = ASIC_PIPE_INIT;
+       else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
+               cntl = ASIC_PIPE_ENABLE;
+       else
+               cntl = ASIC_PIPE_DISABLE;
+
+       if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
+
+               bp_result = dcb->funcs->enable_disp_power_gating(
+                                               dcb, controller_id + 1, cntl);
+
+               /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
+                * by default when command table is called
+                */
+               dm_write_reg(ctx,
+                       HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id),
+                       0);
+       }
+
+       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
+               dce120_init_pte(ctx, controller_id);
+
+       if (bp_result == BP_RESULT_OK)
+               return true;
+       else
+               return false;
+#endif
+       return false;
+}
+
+static void dce120_update_dchub(
+       struct dce_hwseq *hws,
+       struct dchub_init_data *dh_data)
+{
+       /* TODO: port code from dal2 */
+       switch (dh_data->fb_mode) {
+       case FRAME_BUFFER_MODE_ZFB_ONLY:
+               /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
+               REG_UPDATE_2(DCHUB_FB_LOCATION,
+                               FB_TOP, 0,
+                               FB_BASE, 0x0FFFF);
+
+               REG_UPDATE(DCHUB_AGP_BASE,
+                               AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
+
+               REG_UPDATE(DCHUB_AGP_BOT,
+                               AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
+
+               REG_UPDATE(DCHUB_AGP_TOP,
+                               AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
+               break;
+       case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
+               /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
+               REG_UPDATE(DCHUB_AGP_BASE,
+                               AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
+
+               REG_UPDATE(DCHUB_AGP_BOT,
+                               AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
+
+               REG_UPDATE(DCHUB_AGP_TOP,
+                               AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
+               break;
+       case FRAME_BUFFER_MODE_LOCAL_ONLY:
+               /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
+               REG_UPDATE(DCHUB_AGP_BASE,
+                               AGP_BASE, 0);
+
+               REG_UPDATE(DCHUB_AGP_BOT,
+                               AGP_BOT, 0x03FFFF);
+
+               REG_UPDATE(DCHUB_AGP_TOP,
+                               AGP_TOP, 0);
+               break;
+       default:
+               break;
+       }
+
+       dh_data->dchub_initialzied = true;
+       dh_data->dchub_info_valid = false;
+}
+
+/**
+ * dce121_xgmi_enabled() - Check if xGMI is enabled
+ * @hws: DCE hardware sequencer object
+ *
+ * Return true if xGMI is enabled. False otherwise.
+ */
+bool dce121_xgmi_enabled(struct dce_hwseq *hws)
+{
+       uint32_t pf_max_region;
+
+       REG_GET(MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION, &pf_max_region);
+       /* PF_MAX_REGION == 0 means xgmi is disabled */
+       return !!pf_max_region;
+}
+
+void dce120_hw_sequencer_construct(struct dc *dc)
+{
+       /* All registers used by dce11.2 match those in dce11 in offset and
+        * structure
+        */
+       dce110_hw_sequencer_construct(dc);
+       dc->hwseq->funcs.enable_display_power_gating = dce120_enable_display_power_gating;
+       dc->hwss.update_dchub = dce120_update_dchub;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.h
new file mode 100644 (file)
index 0000000..bc02453
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+* 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_HWSS_DCE120_H__
+#define __DC_HWSS_DCE120_H__
+
+#include "core_types.h"
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+bool dce121_xgmi_enabled(struct dce_hwseq *hws);
+void dce120_hw_sequencer_construct(struct dc *dc);
+
+#endif /* __DC_HWSS_DCE112_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c
new file mode 100644 (file)
index 0000000..0a054e8
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 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 "dm_services.h"
+#include "dc.h"
+#include "core_types.h"
+#include "dce80_hwseq.h"
+
+#include "dce/dce_hwseq.h"
+#include "dce110/dce110_hwseq.h"
+#include "dce100/dce100_hwseq.h"
+
+/* include DCE8 register header files */
+#include "dce/dce_8_0_d.h"
+#include "dce/dce_8_0_sh_mask.h"
+
+/*******************************************************************************
+ * Private definitions
+ ******************************************************************************/
+
+/***************************PIPE_CONTROL***********************************/
+
+void dce80_hw_sequencer_construct(struct dc *dc)
+{
+       dce110_hw_sequencer_construct(dc);
+
+       dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
+       dc->hwss.pipe_control_lock = dce_pipe_control_lock;
+       dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
+       dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.h
new file mode 100644 (file)
index 0000000..e43af83
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+* 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_HWSS_DCE80_H__
+#define __DC_HWSS_DCE80_H__
+
+#include "core_types.h"
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dce80_hw_sequencer_construct(struct dc *dc);
+
+#endif /* __DC_HWSS_DCE80_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
new file mode 100644 (file)
index 0000000..2b8b836
--- /dev/null
@@ -0,0 +1,3898 @@
+/*
+ * 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 <linux/delay.h>
+#include "dm_services.h"
+#include "basics/dc_common.h"
+#include "core_types.h"
+#include "resource.h"
+#include "custom_float.h"
+#include "dcn10_hwseq.h"
+#include "dcn10/dcn10_hw_sequencer_debug.h"
+#include "dce/dce_hwseq.h"
+#include "abm.h"
+#include "dmcu.h"
+#include "dcn10/dcn10_optc.h"
+#include "dcn10/dcn10_dpp.h"
+#include "dcn10/dcn10_mpc.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "reg_helper.h"
+#include "dcn10/dcn10_hubp.h"
+#include "dcn10/dcn10_hubbub.h"
+#include "dcn10/dcn10_cm_common.h"
+#include "dccg.h"
+#include "clk_mgr.h"
+#include "link_hwss.h"
+#include "dpcd_defs.h"
+#include "dsc.h"
+#include "dce/dmub_psr.h"
+#include "dc_dmub_srv.h"
+#include "dce/dmub_hw_lock_mgr.h"
+#include "dc_trace.h"
+#include "dce/dmub_outbox.h"
+#include "link.h"
+
+#define DC_LOGGER \
+       dc_logger
+#define DC_LOGGER_INIT(logger) \
+       struct dal_logger *dc_logger = logger
+
+#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
+
+/*print is 17 wide, first two characters are spaces*/
+#define DTN_INFO_MICRO_SEC(ref_cycle) \
+       print_microsec(dc_ctx, log_ctx, ref_cycle)
+
+#define GAMMA_HW_POINTS_NUM 256
+
+#define PGFSM_POWER_ON 0
+#define PGFSM_POWER_OFF 2
+
+static void print_microsec(struct dc_context *dc_ctx,
+                          struct dc_log_buffer_ctx *log_ctx,
+                          uint32_t ref_cycle)
+{
+       const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
+       static const unsigned int frac = 1000;
+       uint32_t us_x10 = (ref_cycle * frac) / ref_clk_mhz;
+
+       DTN_INFO("  %11d.%03d",
+                       us_x10 / frac,
+                       us_x10 % frac);
+}
+
+void dcn10_lock_all_pipes(struct dc *dc,
+       struct dc_state *context,
+       bool lock)
+{
+       struct pipe_ctx *pipe_ctx;
+       struct pipe_ctx *old_pipe_ctx;
+       struct timing_generator *tg;
+       int i;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+               pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               tg = pipe_ctx->stream_res.tg;
+
+               /*
+                * Only lock the top pipe's tg to prevent redundant
+                * (un)locking. Also skip if pipe is disabled.
+                */
+               if (pipe_ctx->top_pipe ||
+                   !pipe_ctx->stream ||
+                   (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state) ||
+                   !tg->funcs->is_tg_enabled(tg) ||
+                       pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM)
+                       continue;
+
+               if (lock)
+                       dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
+               else
+                       dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
+       }
+}
+
+static void log_mpc_crc(struct dc *dc,
+       struct dc_log_buffer_ctx *log_ctx)
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       if (REG(MPC_CRC_RESULT_GB))
+               DTN_INFO("MPC_CRC_RESULT_GB:%d MPC_CRC_RESULT_C:%d MPC_CRC_RESULT_AR:%d\n",
+               REG_READ(MPC_CRC_RESULT_GB), REG_READ(MPC_CRC_RESULT_C), REG_READ(MPC_CRC_RESULT_AR));
+       if (REG(DPP_TOP0_DPP_CRC_VAL_B_A))
+               DTN_INFO("DPP_TOP0_DPP_CRC_VAL_B_A:%d DPP_TOP0_DPP_CRC_VAL_R_G:%d\n",
+               REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G));
+}
+
+static void dcn10_log_hubbub_state(struct dc *dc,
+                                  struct dc_log_buffer_ctx *log_ctx)
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct dcn_hubbub_wm wm;
+       int i;
+
+       memset(&wm, 0, sizeof(struct dcn_hubbub_wm));
+       dc->res_pool->hubbub->funcs->wm_read_state(dc->res_pool->hubbub, &wm);
+
+       DTN_INFO("HUBBUB WM:      data_urgent  pte_meta_urgent"
+                       "         sr_enter          sr_exit  dram_clk_change\n");
+
+       for (i = 0; i < 4; i++) {
+               struct dcn_hubbub_wm_set *s;
+
+               s = &wm.sets[i];
+               DTN_INFO("WM_Set[%d]:", s->wm_set);
+               DTN_INFO_MICRO_SEC(s->data_urgent);
+               DTN_INFO_MICRO_SEC(s->pte_meta_urgent);
+               DTN_INFO_MICRO_SEC(s->sr_enter);
+               DTN_INFO_MICRO_SEC(s->sr_exit);
+               DTN_INFO_MICRO_SEC(s->dram_clk_change);
+               DTN_INFO("\n");
+       }
+
+       DTN_INFO("\n");
+}
+
+static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct resource_pool *pool = dc->res_pool;
+       int i;
+
+       DTN_INFO(
+               "HUBP:  format  addr_hi  width  height  rot  mir  sw_mode  dcc_en  blank_en  clock_en  ttu_dis  underflow   min_ttu_vblank       qos_low_wm      qos_high_wm\n");
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct hubp *hubp = pool->hubps[i];
+               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
+
+               hubp->funcs->hubp_read_state(hubp);
+
+               if (!s->blank_en) {
+                       DTN_INFO("[%2d]:  %5xh  %6xh  %5d  %6d  %2xh  %2xh  %6xh  %6d  %8d  %8d  %7d  %8xh",
+                                       hubp->inst,
+                                       s->pixel_format,
+                                       s->inuse_addr_hi,
+                                       s->viewport_width,
+                                       s->viewport_height,
+                                       s->rotation_angle,
+                                       s->h_mirror_en,
+                                       s->sw_mode,
+                                       s->dcc_en,
+                                       s->blank_en,
+                                       s->clock_en,
+                                       s->ttu_disable,
+                                       s->underflow_status);
+                       DTN_INFO_MICRO_SEC(s->min_ttu_vblank);
+                       DTN_INFO_MICRO_SEC(s->qos_level_low_wm);
+                       DTN_INFO_MICRO_SEC(s->qos_level_high_wm);
+                       DTN_INFO("\n");
+               }
+       }
+
+       DTN_INFO("\n=========RQ========\n");
+       DTN_INFO("HUBP:  drq_exp_m  prq_exp_m  mrq_exp_m  crq_exp_m  plane1_ba  L:chunk_s  min_chu_s  meta_ch_s"
+               "  min_m_c_s  dpte_gr_s  mpte_gr_s  swath_hei  pte_row_h  C:chunk_s  min_chu_s  meta_ch_s"
+               "  min_m_c_s  dpte_gr_s  mpte_gr_s  swath_hei  pte_row_h\n");
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
+               struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
+
+               if (!s->blank_en)
+                       DTN_INFO("[%2d]:  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh\n",
+                               pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode,
+                               rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size,
+                               rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size,
+                               rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size,
+                               rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height,
+                               rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size,
+                               rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size,
+                               rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size,
+                               rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear);
+       }
+
+       DTN_INFO("========DLG========\n");
+       DTN_INFO("HUBP:  rc_hbe     dlg_vbe    min_d_y_n  rc_per_ht  rc_x_a_s "
+                       "  dst_y_a_s  dst_y_pf   dst_y_vvb  dst_y_rvb  dst_y_vfl  dst_y_rfl  rf_pix_fq"
+                       "  vratio_pf  vrat_pf_c  rc_pg_vbl  rc_pg_vbc  rc_mc_vbl  rc_mc_vbc  rc_pg_fll"
+                       "  rc_pg_flc  rc_mc_fll  rc_mc_flc  pr_nom_l   pr_nom_c   rc_pg_nl   rc_pg_nc "
+                       "  mr_nom_l   mr_nom_c   rc_mc_nl   rc_mc_nc   rc_ld_pl   rc_ld_pc   rc_ld_l  "
+                       "  rc_ld_c    cha_cur0   ofst_cur1  cha_cur1   vr_af_vc0  ddrq_limt  x_rt_dlay"
+                       "  x_rp_dlay  x_rr_sfl\n");
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
+               struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
+
+               if (!s->blank_en)
+                       DTN_INFO("[%2d]:  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh"
+                               "  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh"
+                               "  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh\n",
+                               pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start,
+                               dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler,
+                               dlg_regs->dst_y_prefetch, dlg_regs->dst_y_per_vm_vblank, dlg_regs->dst_y_per_row_vblank,
+                               dlg_regs->dst_y_per_vm_flip, dlg_regs->dst_y_per_row_flip, dlg_regs->ref_freq_to_pix_freq,
+                               dlg_regs->vratio_prefetch, dlg_regs->vratio_prefetch_c, dlg_regs->refcyc_per_pte_group_vblank_l,
+                               dlg_regs->refcyc_per_pte_group_vblank_c, dlg_regs->refcyc_per_meta_chunk_vblank_l,
+                               dlg_regs->refcyc_per_meta_chunk_vblank_c, dlg_regs->refcyc_per_pte_group_flip_l,
+                               dlg_regs->refcyc_per_pte_group_flip_c, dlg_regs->refcyc_per_meta_chunk_flip_l,
+                               dlg_regs->refcyc_per_meta_chunk_flip_c, dlg_regs->dst_y_per_pte_row_nom_l,
+                               dlg_regs->dst_y_per_pte_row_nom_c, dlg_regs->refcyc_per_pte_group_nom_l,
+                               dlg_regs->refcyc_per_pte_group_nom_c, dlg_regs->dst_y_per_meta_row_nom_l,
+                               dlg_regs->dst_y_per_meta_row_nom_c, dlg_regs->refcyc_per_meta_chunk_nom_l,
+                               dlg_regs->refcyc_per_meta_chunk_nom_c, dlg_regs->refcyc_per_line_delivery_pre_l,
+                               dlg_regs->refcyc_per_line_delivery_pre_c, dlg_regs->refcyc_per_line_delivery_l,
+                               dlg_regs->refcyc_per_line_delivery_c, dlg_regs->chunk_hdl_adjust_cur0, dlg_regs->dst_y_offset_cur1,
+                               dlg_regs->chunk_hdl_adjust_cur1, dlg_regs->vready_after_vcount0, dlg_regs->dst_y_delta_drq_limit,
+                               dlg_regs->xfc_reg_transfer_delay, dlg_regs->xfc_reg_precharge_delay,
+                               dlg_regs->xfc_reg_remote_surface_flip_latency);
+       }
+
+       DTN_INFO("========TTU========\n");
+       DTN_INFO("HUBP:  qos_ll_wm  qos_lh_wm  mn_ttu_vb  qos_l_flp  rc_rd_p_l  rc_rd_l    rc_rd_p_c"
+                       "  rc_rd_c    rc_rd_c0   rc_rd_pc0  rc_rd_c1   rc_rd_pc1  qos_lf_l   qos_rds_l"
+                       "  qos_lf_c   qos_rds_c  qos_lf_c0  qos_rds_c0 qos_lf_c1  qos_rds_c1\n");
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
+               struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr;
+
+               if (!s->blank_en)
+                       DTN_INFO("[%2d]:  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh  %8xh\n",
+                               pool->hubps[i]->inst, ttu_regs->qos_level_low_wm, ttu_regs->qos_level_high_wm, ttu_regs->min_ttu_vblank,
+                               ttu_regs->qos_level_flip, ttu_regs->refcyc_per_req_delivery_pre_l, ttu_regs->refcyc_per_req_delivery_l,
+                               ttu_regs->refcyc_per_req_delivery_pre_c, ttu_regs->refcyc_per_req_delivery_c, ttu_regs->refcyc_per_req_delivery_cur0,
+                               ttu_regs->refcyc_per_req_delivery_pre_cur0, ttu_regs->refcyc_per_req_delivery_cur1,
+                               ttu_regs->refcyc_per_req_delivery_pre_cur1, ttu_regs->qos_level_fixed_l, ttu_regs->qos_ramp_disable_l,
+                               ttu_regs->qos_level_fixed_c, ttu_regs->qos_ramp_disable_c, ttu_regs->qos_level_fixed_cur0,
+                               ttu_regs->qos_ramp_disable_cur0, ttu_regs->qos_level_fixed_cur1, ttu_regs->qos_ramp_disable_cur1);
+       }
+       DTN_INFO("\n");
+}
+
+void dcn10_log_hw_state(struct dc *dc,
+       struct dc_log_buffer_ctx *log_ctx)
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct resource_pool *pool = dc->res_pool;
+       int i;
+
+       DTN_INFO_BEGIN();
+
+       dcn10_log_hubbub_state(dc, log_ctx);
+
+       dcn10_log_hubp_states(dc, log_ctx);
+
+       DTN_INFO("DPP:    IGAM format  IGAM mode    DGAM mode    RGAM mode"
+                       "  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24   "
+                       "C31 C32   C33 C34\n");
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct dpp *dpp = pool->dpps[i];
+               struct dcn_dpp_state s = {0};
+
+               dpp->funcs->dpp_read_state(dpp, &s);
+
+               if (!s.is_enabled)
+                       continue;
+
+               DTN_INFO("[%2d]:  %11xh  %-11s  %-11s  %-11s"
+                               "%8x    %08xh %08xh %08xh %08xh %08xh %08xh",
+                               dpp->inst,
+                               s.igam_input_format,
+                               (s.igam_lut_mode == 0) ? "BypassFixed" :
+                                       ((s.igam_lut_mode == 1) ? "BypassFloat" :
+                                       ((s.igam_lut_mode == 2) ? "RAM" :
+                                       ((s.igam_lut_mode == 3) ? "RAM" :
+                                                                "Unknown"))),
+                               (s.dgam_lut_mode == 0) ? "Bypass" :
+                                       ((s.dgam_lut_mode == 1) ? "sRGB" :
+                                       ((s.dgam_lut_mode == 2) ? "Ycc" :
+                                       ((s.dgam_lut_mode == 3) ? "RAM" :
+                                       ((s.dgam_lut_mode == 4) ? "RAM" :
+                                                                "Unknown")))),
+                               (s.rgam_lut_mode == 0) ? "Bypass" :
+                                       ((s.rgam_lut_mode == 1) ? "sRGB" :
+                                       ((s.rgam_lut_mode == 2) ? "Ycc" :
+                                       ((s.rgam_lut_mode == 3) ? "RAM" :
+                                       ((s.rgam_lut_mode == 4) ? "RAM" :
+                                                                "Unknown")))),
+                               s.gamut_remap_mode,
+                               s.gamut_remap_c11_c12,
+                               s.gamut_remap_c13_c14,
+                               s.gamut_remap_c21_c22,
+                               s.gamut_remap_c23_c24,
+                               s.gamut_remap_c31_c32,
+                               s.gamut_remap_c33_c34);
+               DTN_INFO("\n");
+       }
+       DTN_INFO("\n");
+
+       DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE\n");
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct mpcc_state s = {0};
+
+               pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
+               if (s.opp_id != 0xf)
+                       DTN_INFO("[%2d]:  %2xh  %2xh  %6xh  %4d  %10d  %7d  %12d  %4d\n",
+                               i, s.opp_id, s.dpp_id, s.bot_mpcc_id,
+                               s.mode, s.alpha_mode, s.pre_multiplied_alpha, s.overlap_only,
+                               s.idle);
+       }
+       DTN_INFO("\n");
+
+       DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
+
+       for (i = 0; i < pool->timing_generator_count; i++) {
+               struct timing_generator *tg = pool->timing_generators[i];
+               struct dcn_otg_state s = {0};
+               /* Read shared OTG state registers for all DCNx */
+               optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
+
+               /*
+                * For DCN2 and greater, a register on the OPP is used to
+                * determine if the CRTC is blanked instead of the OTG. So use
+                * dpg_is_blanked() if exists, otherwise fallback on otg.
+                *
+                * TODO: Implement DCN-specific read_otg_state hooks.
+                */
+               if (pool->opps[i]->funcs->dpg_is_blanked)
+                       s.blank_enabled = pool->opps[i]->funcs->dpg_is_blanked(pool->opps[i]);
+               else
+                       s.blank_enabled = tg->funcs->is_blanked(tg);
+
+               //only print if OTG master is enabled
+               if ((s.otg_enabled & 1) == 0)
+                       continue;
+
+               DTN_INFO("[%d]: %5d %5d %5d %5d %5d %5d %5d %9d %9d %5d %5d %5d %5d %5d %5d %5d  %9d %8d\n",
+                               tg->inst,
+                               s.v_blank_start,
+                               s.v_blank_end,
+                               s.v_sync_a_start,
+                               s.v_sync_a_end,
+                               s.v_sync_a_pol,
+                               s.v_total_max,
+                               s.v_total_min,
+                               s.v_total_max_sel,
+                               s.v_total_min_sel,
+                               s.h_blank_start,
+                               s.h_blank_end,
+                               s.h_sync_a_start,
+                               s.h_sync_a_end,
+                               s.h_sync_a_pol,
+                               s.h_total,
+                               s.v_total,
+                               s.underflow_occurred_status,
+                               s.blank_enabled);
+
+               // Clear underflow for debug purposes
+               // We want to keep underflow sticky bit on for the longevity tests outside of test environment.
+               // This function is called only from Windows or Diags test environment, hence it's safe to clear
+               // it from here without affecting the original intent.
+               tg->funcs->clear_optc_underflow(tg);
+       }
+       DTN_INFO("\n");
+
+       // dcn_dsc_state struct field bytes_per_pixel was renamed to bits_per_pixel
+       // TODO: Update golden log header to reflect this name change
+       DTN_INFO("DSC: CLOCK_EN  SLICE_WIDTH  Bytes_pp\n");
+       for (i = 0; i < pool->res_cap->num_dsc; i++) {
+               struct display_stream_compressor *dsc = pool->dscs[i];
+               struct dcn_dsc_state s = {0};
+
+               dsc->funcs->dsc_read_state(dsc, &s);
+               DTN_INFO("[%d]: %-9d %-12d %-10d\n",
+               dsc->inst,
+                       s.dsc_clock_en,
+                       s.dsc_slice_width,
+                       s.dsc_bits_per_pixel);
+               DTN_INFO("\n");
+       }
+       DTN_INFO("\n");
+
+       DTN_INFO("S_ENC: DSC_MODE  SEC_GSP7_LINE_NUM"
+                       "  VBID6_LINE_REFERENCE  VBID6_LINE_NUM  SEC_GSP7_ENABLE  SEC_STREAM_ENABLE\n");
+       for (i = 0; i < pool->stream_enc_count; i++) {
+               struct stream_encoder *enc = pool->stream_enc[i];
+               struct enc_state s = {0};
+
+               if (enc->funcs->enc_read_state) {
+                       enc->funcs->enc_read_state(enc, &s);
+                       DTN_INFO("[%-3d]: %-9d %-18d %-21d %-15d %-16d %-17d\n",
+                               enc->id,
+                               s.dsc_mode,
+                               s.sec_gsp_pps_line_num,
+                               s.vbid6_line_reference,
+                               s.vbid6_line_num,
+                               s.sec_gsp_pps_enable,
+                               s.sec_stream_enable);
+                       DTN_INFO("\n");
+               }
+       }
+       DTN_INFO("\n");
+
+       DTN_INFO("L_ENC: DPHY_FEC_EN  DPHY_FEC_READY_SHADOW  DPHY_FEC_ACTIVE_STATUS  DP_LINK_TRAINING_COMPLETE\n");
+       for (i = 0; i < dc->link_count; i++) {
+               struct link_encoder *lenc = dc->links[i]->link_enc;
+
+               struct link_enc_state s = {0};
+
+               if (lenc && lenc->funcs->read_state) {
+                       lenc->funcs->read_state(lenc, &s);
+                       DTN_INFO("[%-3d]: %-12d %-22d %-22d %-25d\n",
+                               i,
+                               s.dphy_fec_en,
+                               s.dphy_fec_ready_shadow,
+                               s.dphy_fec_active_status,
+                               s.dp_link_training_complete);
+                       DTN_INFO("\n");
+               }
+       }
+       DTN_INFO("\n");
+
+       DTN_INFO("\nCALCULATED Clocks: dcfclk_khz:%d  dcfclk_deep_sleep_khz:%d  dispclk_khz:%d\n"
+               "dppclk_khz:%d  max_supported_dppclk_khz:%d  fclk_khz:%d  socclk_khz:%d\n\n",
+                       dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz,
+                       dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz,
+                       dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz,
+                       dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz,
+                       dc->current_state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz,
+                       dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz,
+                       dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz);
+
+       log_mpc_crc(dc, log_ctx);
+
+       {
+               if (pool->hpo_dp_stream_enc_count > 0) {
+                       DTN_INFO("DP HPO S_ENC:  Enabled  OTG   Format   Depth   Vid   SDP   Compressed  Link\n");
+                       for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) {
+                               struct hpo_dp_stream_encoder_state hpo_dp_se_state = {0};
+                               struct hpo_dp_stream_encoder *hpo_dp_stream_enc = pool->hpo_dp_stream_enc[i];
+
+                               if (hpo_dp_stream_enc && hpo_dp_stream_enc->funcs->read_state) {
+                                       hpo_dp_stream_enc->funcs->read_state(hpo_dp_stream_enc, &hpo_dp_se_state);
+
+                                       DTN_INFO("[%d]:                 %d    %d   %6s       %d     %d     %d            %d     %d\n",
+                                                       hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0,
+                                                       hpo_dp_se_state.stream_enc_enabled,
+                                                       hpo_dp_se_state.otg_inst,
+                                                       (hpo_dp_se_state.pixel_encoding == 0) ? "4:4:4" :
+                                                                       ((hpo_dp_se_state.pixel_encoding == 1) ? "4:2:2" :
+                                                                       (hpo_dp_se_state.pixel_encoding == 2) ? "4:2:0" : "Y-Only"),
+                                                       (hpo_dp_se_state.component_depth == 0) ? 6 :
+                                                                       ((hpo_dp_se_state.component_depth == 1) ? 8 :
+                                                                       (hpo_dp_se_state.component_depth == 2) ? 10 : 12),
+                                                       hpo_dp_se_state.vid_stream_enabled,
+                                                       hpo_dp_se_state.sdp_enabled,
+                                                       hpo_dp_se_state.compressed_format,
+                                                       hpo_dp_se_state.mapped_to_link_enc);
+                               }
+                       }
+
+                       DTN_INFO("\n");
+               }
+
+               /* log DP HPO L_ENC section if any hpo_dp_link_enc exists */
+               if (pool->hpo_dp_link_enc_count) {
+                       DTN_INFO("DP HPO L_ENC:  Enabled  Mode   Lanes   Stream  Slots   VC Rate X    VC Rate Y\n");
+
+                       for (i = 0; i < pool->hpo_dp_link_enc_count; i++) {
+                               struct hpo_dp_link_encoder *hpo_dp_link_enc = pool->hpo_dp_link_enc[i];
+                               struct hpo_dp_link_enc_state hpo_dp_le_state = {0};
+
+                               if (hpo_dp_link_enc->funcs->read_state) {
+                                       hpo_dp_link_enc->funcs->read_state(hpo_dp_link_enc, &hpo_dp_le_state);
+                                       DTN_INFO("[%d]:                 %d  %6s     %d        %d      %d     %d     %d\n",
+                                                       hpo_dp_link_enc->inst,
+                                                       hpo_dp_le_state.link_enc_enabled,
+                                                       (hpo_dp_le_state.link_mode == 0) ? "TPS1" :
+                                                                       (hpo_dp_le_state.link_mode == 1) ? "TPS2" :
+                                                                       (hpo_dp_le_state.link_mode == 2) ? "ACTIVE" : "TEST",
+                                                       hpo_dp_le_state.lane_count,
+                                                       hpo_dp_le_state.stream_src[0],
+                                                       hpo_dp_le_state.slot_count[0],
+                                                       hpo_dp_le_state.vc_rate_x[0],
+                                                       hpo_dp_le_state.vc_rate_y[0]);
+                                       DTN_INFO("\n");
+                               }
+                       }
+
+                       DTN_INFO("\n");
+               }
+       }
+
+       DTN_INFO_END();
+}
+
+bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+       if (tg->funcs->is_optc_underflow_occurred(tg)) {
+               tg->funcs->clear_optc_underflow(tg);
+               return true;
+       }
+
+       if (hubp->funcs->hubp_get_underflow_status(hubp)) {
+               hubp->funcs->hubp_clear_underflow(hubp);
+               return true;
+       }
+       return false;
+}
+
+void dcn10_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable)
+{
+       bool force_on = true; /* disable power gating */
+
+       if (enable)
+               force_on = false;
+
+       /* DCHUBP0/1/2/3 */
+       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
+
+       /* DPP0/1/2/3 */
+       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
+}
+
+void dcn10_disable_vga(
+       struct dce_hwseq *hws)
+{
+       unsigned int in_vga1_mode = 0;
+       unsigned int in_vga2_mode = 0;
+       unsigned int in_vga3_mode = 0;
+       unsigned int in_vga4_mode = 0;
+
+       REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode);
+       REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode);
+       REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode);
+       REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode);
+
+       if (in_vga1_mode == 0 && in_vga2_mode == 0 &&
+                       in_vga3_mode == 0 && in_vga4_mode == 0)
+               return;
+
+       REG_WRITE(D1VGA_CONTROL, 0);
+       REG_WRITE(D2VGA_CONTROL, 0);
+       REG_WRITE(D3VGA_CONTROL, 0);
+       REG_WRITE(D4VGA_CONTROL, 0);
+
+       /* HW Engineer's Notes:
+        *  During switch from vga->extended, if we set the VGA_TEST_ENABLE and
+        *  then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly.
+        *
+        *  Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset
+        *  VGA_TEST_ENABLE, to leave it in the same state as before.
+        */
+       REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1);
+       REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
+}
+
+/**
+ * dcn10_dpp_pg_control - DPP power gate control.
+ *
+ * @hws: dce_hwseq reference.
+ * @dpp_inst: DPP instance reference.
+ * @power_on: true if we want to enable power gate, false otherwise.
+ *
+ * Enable or disable power gate in the specific DPP instance.
+ */
+void dcn10_dpp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dpp_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? PGFSM_POWER_ON : PGFSM_POWER_OFF;
+
+       if (hws->ctx->dc->debug.disable_dpp_power_gate)
+               return;
+       if (REG(DOMAIN1_PG_CONFIG) == 0)
+               return;
+
+       switch (dpp_inst) {
+       case 0: /* DPP0 */
+               REG_UPDATE(DOMAIN1_PG_CONFIG,
+                               DOMAIN1_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN1_PG_STATUS,
+                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DPP1 */
+               REG_UPDATE(DOMAIN3_PG_CONFIG,
+                               DOMAIN3_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN3_PG_STATUS,
+                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DPP2 */
+               REG_UPDATE(DOMAIN5_PG_CONFIG,
+                               DOMAIN5_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN5_PG_STATUS,
+                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DPP3 */
+               REG_UPDATE(DOMAIN7_PG_CONFIG,
+                               DOMAIN7_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN7_PG_STATUS,
+                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+/**
+ * dcn10_hubp_pg_control - HUBP power gate control.
+ *
+ * @hws: dce_hwseq reference.
+ * @hubp_inst: DPP instance reference.
+ * @power_on: true if we want to enable power gate, false otherwise.
+ *
+ * Enable or disable power gate in the specific HUBP instance.
+ */
+void dcn10_hubp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int hubp_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? PGFSM_POWER_ON : PGFSM_POWER_OFF;
+
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
+               return;
+       if (REG(DOMAIN0_PG_CONFIG) == 0)
+               return;
+
+       switch (hubp_inst) {
+       case 0: /* DCHUBP0 */
+               REG_UPDATE(DOMAIN0_PG_CONFIG,
+                               DOMAIN0_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN0_PG_STATUS,
+                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DCHUBP1 */
+               REG_UPDATE(DOMAIN2_PG_CONFIG,
+                               DOMAIN2_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN2_PG_STATUS,
+                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DCHUBP2 */
+               REG_UPDATE(DOMAIN4_PG_CONFIG,
+                               DOMAIN4_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN4_PG_STATUS,
+                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DCHUBP3 */
+               REG_UPDATE(DOMAIN6_PG_CONFIG,
+                               DOMAIN6_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN6_PG_STATUS,
+                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+static void power_on_plane_resources(
+       struct dce_hwseq *hws,
+       int plane_id)
+{
+       DC_LOGGER_INIT(hws->ctx->logger);
+
+       if (hws->funcs.dpp_root_clock_control)
+               hws->funcs.dpp_root_clock_control(hws, plane_id, true);
+
+       if (REG(DC_IP_REQUEST_CNTL)) {
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+                               IP_REQUEST_EN, 1);
+
+               if (hws->funcs.dpp_pg_control)
+                       hws->funcs.dpp_pg_control(hws, plane_id, true);
+
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, plane_id, true);
+
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+                               IP_REQUEST_EN, 0);
+               DC_LOG_DEBUG(
+                               "Un-gated front end for pipe %d\n", plane_id);
+       }
+}
+
+static void undo_DEGVIDCN10_253_wa(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = dc->res_pool->hubps[0];
+
+       if (!hws->wa_state.DEGVIDCN10_253_applied)
+               return;
+
+       hubp->funcs->set_blank(hubp, true);
+
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 1);
+
+       hws->funcs.hubp_pg_control(hws, 0, false);
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 0);
+
+       hws->wa_state.DEGVIDCN10_253_applied = false;
+}
+
+static void apply_DEGVIDCN10_253_wa(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = dc->res_pool->hubps[0];
+       int i;
+
+       if (dc->debug.disable_stutter)
+               return;
+
+       if (!hws->wa.DEGVIDCN10_253)
+               return;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (!dc->res_pool->hubps[i]->power_gated)
+                       return;
+       }
+
+       /* all pipe power gated, apply work around to enable stutter. */
+
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 1);
+
+       hws->funcs.hubp_pg_control(hws, 0, true);
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 0);
+
+       hubp->funcs->set_hubp_blank_en(hubp, false);
+       hws->wa_state.DEGVIDCN10_253_applied = true;
+}
+
+void dcn10_bios_golden_init(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *bp = dc->ctx->dc_bios;
+       int i;
+       bool allow_self_fresh_force_enable = true;
+
+       if (hws->funcs.s0i3_golden_init_wa && hws->funcs.s0i3_golden_init_wa(dc))
+               return;
+
+       if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
+               allow_self_fresh_force_enable =
+                               dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
+
+
+       /* WA for making DF sleep when idle after resume from S0i3.
+        * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
+        * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
+        * before calling command table and it changed to 1 after,
+        * it should be set back to 0.
+        */
+
+       /* initialize dcn global */
+       bp->funcs->enable_disp_power_gating(bp,
+                       CONTROLLER_ID_D0, ASIC_PIPE_INIT);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               /* initialize dcn per pipe */
+               bp->funcs->enable_disp_power_gating(bp,
+                               CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
+       }
+
+       if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+               if (allow_self_fresh_force_enable == false &&
+                               dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub))
+                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
+                                                                               !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
+
+}
+
+static void false_optc_underflow_wa(
+               struct dc *dc,
+               const struct dc_stream_state *stream,
+               struct timing_generator *tg)
+{
+       int i;
+       bool underflow;
+
+       if (!dc->hwseq->wa.false_optc_underflow)
+               return;
+
+       underflow = tg->funcs->is_optc_underflow_occurred(tg);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (old_pipe_ctx->stream != stream)
+                       continue;
+
+               dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, old_pipe_ctx);
+       }
+
+       if (tg->funcs->set_blank_data_double_buffer)
+               tg->funcs->set_blank_data_double_buffer(tg, true);
+
+       if (tg->funcs->is_optc_underflow_occurred(tg) && !underflow)
+               tg->funcs->clear_optc_underflow(tg);
+}
+
+static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
+{
+       struct pipe_ctx *other_pipe;
+       int vready_offset = pipe->pipe_dlg_param.vready_offset;
+
+       /* Always use the largest vready_offset of all connected pipes */
+       for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+       for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+       for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+       for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+
+       return vready_offset;
+}
+
+enum dc_status dcn10_enable_stream_timing(
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context,
+               struct dc *dc)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       enum dc_color_space color_space;
+       struct tg_color black_color = {0};
+
+       /* by upper caller loop, pipe0 is parent pipe and be called first.
+        * back end is set up by for pipe0. Other children pipe share back end
+        * with pipe 0. No program is needed.
+        */
+       if (pipe_ctx->top_pipe != NULL)
+               return DC_OK;
+
+       /* TODO check if timing_changed, disable stream if timing changed */
+
+       /* HW program guide assume display already disable
+        * by unplug sequence. OTG assume stop.
+        */
+       pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, true);
+
+       if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
+                       pipe_ctx->clock_source,
+                       &pipe_ctx->stream_res.pix_clk_params,
+                       dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                       &pipe_ctx->pll_settings)) {
+               BREAK_TO_DEBUGGER();
+               return DC_ERROR_UNEXPECTED;
+       }
+
+       if (dc_is_hdmi_tmds_signal(stream->signal)) {
+               stream->link->phy_state.symclk_ref_cnts.otg = 1;
+               if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+               else
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+       }
+
+       pipe_ctx->stream_res.tg->funcs->program_timing(
+                       pipe_ctx->stream_res.tg,
+                       &stream->timing,
+                       calculate_vready_offset_for_group(pipe_ctx),
+                       pipe_ctx->pipe_dlg_param.vstartup_start,
+                       pipe_ctx->pipe_dlg_param.vupdate_offset,
+                       pipe_ctx->pipe_dlg_param.vupdate_width,
+                       pipe_ctx->stream->signal,
+                       true);
+
+#if 0 /* move to after enable_crtc */
+       /* TODO: OPP FMT, ABM. etc. should be done here. */
+       /* or FPGA now. instance 0 only. TODO: move to opp.c */
+
+       inst_offset = reg_offsets[pipe_ctx->stream_res.tg->inst].fmt;
+
+       pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
+                               pipe_ctx->stream_res.opp,
+                               &stream->bit_depth_params,
+                               &stream->clamping);
+#endif
+       /* program otg blank color */
+       color_space = stream->output_color_space;
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       /*
+        * The way 420 is packed, 2 channels carry Y component, 1 channel
+        * alternate between Cb and Cr, so both channels need the pixel
+        * value for Y
+        */
+       if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+               black_color.color_r_cr = black_color.color_g_y;
+
+       if (pipe_ctx->stream_res.tg->funcs->set_blank_color)
+               pipe_ctx->stream_res.tg->funcs->set_blank_color(
+                               pipe_ctx->stream_res.tg,
+                               &black_color);
+
+       if (pipe_ctx->stream_res.tg->funcs->is_blanked &&
+                       !pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) {
+               pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true);
+               hwss_wait_for_blank_complete(pipe_ctx->stream_res.tg);
+               false_optc_underflow_wa(dc, pipe_ctx->stream, pipe_ctx->stream_res.tg);
+       }
+
+       /* VTG is  within DCHUB command block. DCFCLK is always on */
+       if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(pipe_ctx->stream_res.tg)) {
+               BREAK_TO_DEBUGGER();
+               return DC_ERROR_UNEXPECTED;
+       }
+
+       /* TODO program crtc source select for non-virtual signal*/
+       /* TODO program FMT */
+       /* TODO setup link_enc */
+       /* TODO set stream attributes */
+       /* TODO program audio */
+       /* TODO enable stream if timing changed */
+       /* TODO unblank stream if DP */
+
+       return DC_OK;
+}
+
+static void dcn10_reset_back_end_for_pipe(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context)
+{
+       int i;
+       struct dc_link *link;
+       DC_LOGGER_INIT(dc->ctx->logger);
+       if (pipe_ctx->stream_res.stream_enc == NULL) {
+               pipe_ctx->stream = NULL;
+               return;
+       }
+
+       link = pipe_ctx->stream->link;
+       /* DPMS may already disable or */
+       /* dpms_off status is incorrect due to fastboot
+        * feature. When system resume from S4 with second
+        * screen only, the dpms_off would be true but
+        * VBIOS lit up eDP, so check link status too.
+        */
+       if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+               dc->link_srv->set_dpms_off(pipe_ctx);
+       else if (pipe_ctx->stream_res.audio)
+               dc->hwss.disable_audio_stream(pipe_ctx);
+
+       if (pipe_ctx->stream_res.audio) {
+               /*disable az_endpoint*/
+               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+               /*free audio*/
+               if (dc->caps.dynamic_audio == true) {
+                       /*we have to dynamic arbitrate the audio endpoints*/
+                       /*we free the resource, need reset is_audio_acquired*/
+                       update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
+                                       pipe_ctx->stream_res.audio, false);
+                       pipe_ctx->stream_res.audio = NULL;
+               }
+       }
+
+       /* by upper caller loop, parent pipe: pipe0, will be reset last.
+        * back end share by all pipes and will be disable only when disable
+        * parent pipe.
+        */
+       if (pipe_ctx->top_pipe == NULL) {
+
+               if (pipe_ctx->stream_res.abm)
+                       dc->hwss.set_abm_immediate_disable(pipe_ctx);
+
+               pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
+
+               pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+               if (pipe_ctx->stream_res.tg->funcs->set_drr)
+                       pipe_ctx->stream_res.tg->funcs->set_drr(
+                                       pipe_ctx->stream_res.tg, NULL);
+               pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (&dc->current_state->res_ctx.pipe_ctx[i] == pipe_ctx)
+                       break;
+
+       if (i == dc->res_pool->pipe_count)
+               return;
+
+       pipe_ctx->stream = NULL;
+       DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
+                                       pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
+}
+
+static bool dcn10_hw_wa_force_recovery(struct dc *dc)
+{
+       struct hubp *hubp ;
+       unsigned int i;
+       bool need_recover = true;
+
+       if (!dc->debug.recovery_enabled)
+               return false;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               if (pipe_ctx != NULL) {
+                       hubp = pipe_ctx->plane_res.hubp;
+                       if (hubp != NULL && hubp->funcs->hubp_get_underflow_status) {
+                               if (hubp->funcs->hubp_get_underflow_status(hubp) != 0) {
+                                       /* one pipe underflow, we will reset all the pipes*/
+                                       need_recover = true;
+                               }
+                       }
+               }
+       }
+       if (!need_recover)
+               return false;
+       /*
+       DCHUBP_CNTL:HUBP_BLANK_EN=1
+       DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1
+       DCHUBP_CNTL:HUBP_DISABLE=1
+       DCHUBP_CNTL:HUBP_DISABLE=0
+       DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=0
+       DCSURF_PRIMARY_SURFACE_ADDRESS
+       DCHUBP_CNTL:HUBP_BLANK_EN=0
+       */
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               if (pipe_ctx != NULL) {
+                       hubp = pipe_ctx->plane_res.hubp;
+                       /*DCHUBP_CNTL:HUBP_BLANK_EN=1*/
+                       if (hubp != NULL && hubp->funcs->set_hubp_blank_en)
+                               hubp->funcs->set_hubp_blank_en(hubp, true);
+               }
+       }
+       /*DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1*/
+       hubbub1_soft_reset(dc->res_pool->hubbub, true);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               if (pipe_ctx != NULL) {
+                       hubp = pipe_ctx->plane_res.hubp;
+                       /*DCHUBP_CNTL:HUBP_DISABLE=1*/
+                       if (hubp != NULL && hubp->funcs->hubp_disable_control)
+                               hubp->funcs->hubp_disable_control(hubp, true);
+               }
+       }
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               if (pipe_ctx != NULL) {
+                       hubp = pipe_ctx->plane_res.hubp;
+                       /*DCHUBP_CNTL:HUBP_DISABLE=0*/
+                       if (hubp != NULL && hubp->funcs->hubp_disable_control)
+                               hubp->funcs->hubp_disable_control(hubp, true);
+               }
+       }
+       /*DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=0*/
+       hubbub1_soft_reset(dc->res_pool->hubbub, false);
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               if (pipe_ctx != NULL) {
+                       hubp = pipe_ctx->plane_res.hubp;
+                       /*DCHUBP_CNTL:HUBP_BLANK_EN=0*/
+                       if (hubp != NULL && hubp->funcs->set_hubp_blank_en)
+                               hubp->funcs->set_hubp_blank_en(hubp, true);
+               }
+       }
+       return true;
+
+}
+
+void dcn10_verify_allow_pstate_change_high(struct dc *dc)
+{
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       static bool should_log_hw_state; /* prevent hw state log by default */
+
+       if (!hubbub->funcs->verify_allow_pstate_change_high)
+               return;
+
+       if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) {
+               int i = 0;
+
+               if (should_log_hw_state)
+                       dcn10_log_hw_state(dc, NULL);
+
+               TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
+               BREAK_TO_DEBUGGER();
+               if (dcn10_hw_wa_force_recovery(dc)) {
+                       /*check again*/
+                       if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub))
+                               BREAK_TO_DEBUGGER();
+               }
+       }
+}
+
+/* trigger HW to start disconnect plane from stream on the next vsync */
+void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       int dpp_id = pipe_ctx->plane_res.dpp->inst;
+       struct mpc *mpc = dc->res_pool->mpc;
+       struct mpc_tree *mpc_tree_params;
+       struct mpcc *mpcc_to_remove = NULL;
+       struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
+
+       mpc_tree_params = &(opp->mpc_tree_params);
+       mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
+
+       /*Already reset*/
+       if (mpcc_to_remove == NULL)
+               return;
+
+       mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
+       // Phantom pipes have OTG disabled by default, so MPCC_STATUS will never assert idle,
+       // so don't wait for MPCC_IDLE in the programming sequence
+       if (opp != NULL && !pipe_ctx->plane_state->is_phantom)
+               opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+
+       dc->optimized_required = true;
+
+       if (hubp->funcs->hubp_disconnect)
+               hubp->funcs->hubp_disconnect(hubp);
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+}
+
+/**
+ * dcn10_plane_atomic_power_down - Power down plane components.
+ *
+ * @dc: dc struct reference. used for grab hwseq.
+ * @dpp: dpp struct reference.
+ * @hubp: hubp struct reference.
+ *
+ * Keep in mind that this operation requires a power gate configuration;
+ * however, requests for switch power gate are precisely controlled to avoid
+ * problems. For this reason, power gate request is usually disabled. This
+ * function first needs to enable the power gate request before disabling DPP
+ * and HUBP. Finally, it disables the power gate request again.
+ */
+void dcn10_plane_atomic_power_down(struct dc *dc,
+               struct dpp *dpp,
+               struct hubp *hubp)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       if (REG(DC_IP_REQUEST_CNTL)) {
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+                               IP_REQUEST_EN, 1);
+
+               if (hws->funcs.dpp_pg_control)
+                       hws->funcs.dpp_pg_control(hws, dpp->inst, false);
+
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, hubp->inst, false);
+
+               dpp->funcs->dpp_reset(dpp);
+
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+                               IP_REQUEST_EN, 0);
+               DC_LOG_DEBUG(
+                               "Power gated front end %d\n", hubp->inst);
+       }
+
+       if (hws->funcs.dpp_root_clock_control)
+               hws->funcs.dpp_root_clock_control(hws, dpp->inst, false);
+}
+
+/* disable HW used by plane.
+ * note:  cannot disable until disconnect is complete
+ */
+void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+       int opp_id = hubp->opp_id;
+
+       dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
+
+       hubp->funcs->hubp_clk_cntl(hubp, false);
+
+       dpp->funcs->dpp_dppclk_control(dpp, false, false);
+
+       if (opp_id != 0xf && pipe_ctx->stream_res.opp->mpc_tree_params.opp_list == NULL)
+               pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+                               pipe_ctx->stream_res.opp,
+                               false);
+
+       hubp->power_gated = true;
+       dc->optimized_required = false; /* We're powering off, no need to optimize */
+
+       hws->funcs.plane_atomic_power_down(dc,
+                       pipe_ctx->plane_res.dpp,
+                       pipe_ctx->plane_res.hubp);
+
+       pipe_ctx->stream = NULL;
+       memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
+       memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
+       pipe_ctx->top_pipe = NULL;
+       pipe_ctx->bottom_pipe = NULL;
+       pipe_ctx->plane_state = NULL;
+}
+
+void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
+               return;
+
+       hws->funcs.plane_atomic_disable(dc, pipe_ctx);
+
+       apply_DEGVIDCN10_253_wa(dc);
+
+       DC_LOG_DC("Power down front end %d\n",
+                                       pipe_ctx->pipe_idx);
+}
+
+void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       bool can_apply_seamless_boot = false;
+
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->streams[i]->apply_seamless_boot_optimization) {
+                       can_apply_seamless_boot = true;
+                       break;
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* There is assumption that pipe_ctx is not mapping irregularly
+                * to non-preferred front end. If pipe_ctx->stream is not NULL,
+                * we will use the pipe, so don't disable
+                */
+               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+                       continue;
+
+               /* Blank controller using driver code instead of
+                * command table.
+                */
+               if (tg->funcs->is_tg_enabled(tg)) {
+                       if (hws->funcs.init_blank != NULL) {
+                               hws->funcs.init_blank(dc, tg);
+                               tg->funcs->lock(tg);
+                       } else {
+                               tg->funcs->lock(tg);
+                               tg->funcs->set_blank(tg, true);
+                               hwss_wait_for_blank_complete(tg);
+                       }
+               }
+       }
+
+       /* Reset det size */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = dc->res_pool->hubps[i];
+
+               /* Do not need to reset for seamless boot */
+               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+                       continue;
+
+               if (hubbub && hubp) {
+                       if (hubbub->funcs->program_det_size)
+                               hubbub->funcs->program_det_size(hubbub, hubp->inst, 0);
+               }
+       }
+
+       /* num_opp will be equal to number of mpcc */
+       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* Cannot reset the MPC mux if seamless boot */
+               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+                       continue;
+
+               dc->res_pool->mpc->funcs->mpc_init_single_inst(
+                               dc->res_pool->mpc, i);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+               struct hubp *hubp = dc->res_pool->hubps[i];
+               struct dpp *dpp = dc->res_pool->dpps[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* There is assumption that pipe_ctx is not mapping irregularly
+                * to non-preferred front end. If pipe_ctx->stream is not NULL,
+                * we will use the pipe, so don't disable
+                */
+               if (can_apply_seamless_boot &&
+                       pipe_ctx->stream != NULL &&
+                       pipe_ctx->stream_res.tg->funcs->is_tg_enabled(
+                               pipe_ctx->stream_res.tg)) {
+                       // Enable double buffering for OTG_BLANK no matter if
+                       // seamless boot is enabled or not to suppress global sync
+                       // signals when OTG blanked. This is to prevent pipe from
+                       // requesting data while in PSR.
+                       tg->funcs->tg_init(tg);
+                       hubp->power_gated = true;
+                       continue;
+               }
+
+               /* Disable on the current state so the new one isn't cleared. */
+               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               dpp->funcs->dpp_reset(dpp);
+
+               pipe_ctx->stream_res.tg = tg;
+               pipe_ctx->pipe_idx = i;
+
+               pipe_ctx->plane_res.hubp = hubp;
+               pipe_ctx->plane_res.dpp = dpp;
+               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+               hubp->mpcc_id = dpp->inst;
+               hubp->opp_id = OPP_ID_INVALID;
+               hubp->power_gated = false;
+
+               dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+               dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+               dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+               pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
+
+               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       tg->funcs->unlock(tg);
+
+               dc->hwss.disable_plane(dc, pipe_ctx);
+
+               pipe_ctx->stream_res.tg = NULL;
+               pipe_ctx->plane_res.hubp = NULL;
+
+               if (tg->funcs->is_tg_enabled(tg)) {
+                       if (tg->funcs->init_odm)
+                               tg->funcs->init_odm(tg);
+               }
+
+               tg->funcs->tg_init(tg);
+       }
+
+       /* Power gate DSCs */
+       if (hws->funcs.dsc_pg_control != NULL) {
+               uint32_t num_opps = 0;
+               uint32_t opp_id_src0 = OPP_ID_INVALID;
+               uint32_t opp_id_src1 = OPP_ID_INVALID;
+
+               // Step 1: To find out which OPTC is running & OPTC DSC is ON
+               // We can't use res_pool->res_cap->num_timing_generator to check
+               // Because it records display pipes default setting built in driver,
+               // not display pipes of the current chip.
+               // Some ASICs would be fused display pipes less than the default setting.
+               // In dcnxx_resource_construct function, driver would obatin real information.
+               for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+                       uint32_t optc_dsc_state = 0;
+                       struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+                       if (tg->funcs->is_tg_enabled(tg)) {
+                               if (tg->funcs->get_dsc_status)
+                                       tg->funcs->get_dsc_status(tg, &optc_dsc_state);
+                               // Only one OPTC with DSC is ON, so if we got one result, we would exit this block.
+                               // non-zero value is DSC enabled
+                               if (optc_dsc_state != 0) {
+                                       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+                                       break;
+                               }
+                       }
+               }
+
+               // Step 2: To power down DSC but skip DSC  of running OPTC
+               for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+                       struct dcn_dsc_state s  = {0};
+
+                       dc->res_pool->dscs[i]->funcs->dsc_read_state(dc->res_pool->dscs[i], &s);
+
+                       if ((s.dsc_opp_source == opp_id_src0 || s.dsc_opp_source == opp_id_src1) &&
+                               s.dsc_clock_en && s.dsc_fw_en)
+                               continue;
+
+                       hws->funcs.dsc_pg_control(hws, dc->res_pool->dscs[i]->inst, false);
+               }
+       }
+}
+
+void dcn10_init_hw(struct dc *dc)
+{
+       int i;
+       struct abm *abm = dc->res_pool->abm;
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+       struct resource_pool *res_pool = dc->res_pool;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+       bool   is_optimized_init_done = false;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       /* Align bw context with hw config when system resume. */
+       if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
+               dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz;
+               dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz;
+       }
+
+       // Initialize the dccg
+       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init)
+               dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       if (!dcb->funcs->is_accelerated_mode(dcb))
+               hws->funcs.disable_vga(dc->hwseq);
+
+       if (!dc_dmub_srv_optimized_init_done(dc->ctx->dmub_srv))
+               hws->funcs.bios_golden_init(dc);
+
+
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (res_pool->dccg && res_pool->hubbub) {
+
+                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+               } else {
+                       // Not all ASICs have DCCG sw component
+                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+               }
+       } else
+               ASSERT_CRITICAL(false);
+
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               if (!is_optimized_init_done)
+                       link->link_enc->funcs->hw_init(link->link_enc);
+
+               /* Check for enabled DIG to identify enabled display */
+               if (link->link_enc->funcs->is_dig_enabled &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
+                       link->link_status.link_active = true;
+                       if (link->link_enc->funcs->fec_is_active &&
+                                       link->link_enc->funcs->fec_is_active(link->link_enc))
+                               link->fec_state = dc_link_fec_enabled;
+               }
+       }
+
+       /* we want to turn off all dp displays before doing detection */
+       dc->link_srv->blank_all_dp_displays(dc);
+
+       if (hws->funcs.enable_power_gating_plane)
+               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
+
+       /* If taking control over from VBIOS, we may want to optimize our first
+        * mode set, so we need to skip powering down pipes until we know which
+        * pipes we want to use.
+        * Otherwise, if taking control is not possible, we need to power
+        * everything down.
+        */
+       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
+               if (!is_optimized_init_done) {
+                       hws->funcs.init_pipes(dc, dc->current_state);
+                       if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+                               dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
+                                               !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
+               }
+       }
+
+       if (!is_optimized_init_done) {
+
+               for (i = 0; i < res_pool->audio_count; i++) {
+                       struct audio *audio = res_pool->audios[i];
+
+                       audio->funcs->hw_init(audio);
+               }
+
+               for (i = 0; i < dc->link_count; i++) {
+                       struct dc_link *link = dc->links[i];
+
+                       if (link->panel_cntl)
+                               backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
+               }
+
+               if (abm != NULL)
+                       abm->funcs->abm_init(abm, backlight);
+
+               if (dmcu != NULL && !dmcu->auto_load_dmcu)
+                       dmcu->funcs->dmcu_init(dmcu);
+       }
+
+       if (abm != NULL && dmcu != NULL)
+               abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
+
+       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
+       if (!is_optimized_init_done)
+               REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+       if (!dc->debug.disable_clock_gate) {
+               /* enable all DCN clock gating */
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+       }
+
+       if (dc->clk_mgr->funcs->notify_wm_ranges)
+               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+}
+
+/* In headless boot cases, DIG may be turned
+ * on which causes HW/SW discrepancies.
+ * To avoid this, power down hardware on boot
+ * if DIG is turned on
+ */
+void dcn10_power_down_on_boot(struct dc *dc)
+{
+       struct dc_link *edp_links[MAX_NUM_EDP];
+       struct dc_link *edp_link = NULL;
+       int edp_num;
+       int i = 0;
+
+       dc_get_edp_links(dc, edp_links, &edp_num);
+       if (edp_num)
+               edp_link = edp_links[0];
+
+       if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
+                       edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                       dc->hwseq->funcs.edp_backlight_control &&
+                       dc->hwss.power_down &&
+                       dc->hwss.edp_power_control) {
+               dc->hwseq->funcs.edp_backlight_control(edp_link, false);
+               dc->hwss.power_down(dc);
+               dc->hwss.edp_power_control(edp_link, false);
+       } else {
+               for (i = 0; i < dc->link_count; i++) {
+                       struct dc_link *link = dc->links[i];
+
+                       if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
+                                       link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
+                                       dc->hwss.power_down) {
+                               dc->hwss.power_down(dc);
+                               break;
+                       }
+
+               }
+       }
+
+       /*
+        * Call update_clocks with empty context
+        * to send DISPLAY_OFF
+        * Otherwise DISPLAY_OFF may not be asserted
+        */
+       if (dc->clk_mgr->funcs->set_low_power_state)
+               dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
+}
+
+void dcn10_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* Reset Back End*/
+       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
+               struct pipe_ctx *pipe_ctx_old =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe_ctx_old->stream)
+                       continue;
+
+               if (pipe_ctx_old->top_pipe)
+                       continue;
+
+               if (!pipe_ctx->stream ||
+                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
+
+                       dcn10_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
+                       if (hws->funcs.enable_stream_gating)
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
+                       if (old_clk)
+                               old_clk->funcs->cs_power_down(old_clk);
+               }
+       }
+}
+
+static bool patch_address_for_sbs_tb_stereo(
+               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
+{
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       bool sec_split = pipe_ctx->top_pipe &&
+                       pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
+       if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+               (pipe_ctx->stream->timing.timing_3d_format ==
+                TIMING_3D_FORMAT_SIDE_BY_SIDE ||
+                pipe_ctx->stream->timing.timing_3d_format ==
+                TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
+               *addr = plane_state->address.grph_stereo.left_addr;
+               plane_state->address.grph_stereo.left_addr =
+               plane_state->address.grph_stereo.right_addr;
+               return true;
+       } else {
+               if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
+                       plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
+                       plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
+                       plane_state->address.grph_stereo.right_addr =
+                       plane_state->address.grph_stereo.left_addr;
+                       plane_state->address.grph_stereo.right_meta_addr =
+                       plane_state->address.grph_stereo.left_meta_addr;
+               }
+       }
+       return false;
+}
+
+void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       bool addr_patched = false;
+       PHYSICAL_ADDRESS_LOC addr;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+
+       if (plane_state == NULL)
+               return;
+
+       addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
+
+       pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
+                       pipe_ctx->plane_res.hubp,
+                       &plane_state->address,
+                       plane_state->flip_immediate);
+
+       plane_state->status.requested_address = plane_state->address;
+
+       if (plane_state->flip_immediate)
+               plane_state->status.current_address = plane_state->address;
+
+       if (addr_patched)
+               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
+}
+
+bool dcn10_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                       const struct dc_plane_state *plane_state)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       const struct dc_transfer_func *tf = NULL;
+       bool result = true;
+
+       if (dpp_base == NULL)
+               return false;
+
+       if (plane_state->in_transfer_func)
+               tf = plane_state->in_transfer_func;
+
+       if (plane_state->gamma_correction &&
+               !dpp_base->ctx->dc->debug.always_use_regamma
+               && !plane_state->gamma_correction->is_identity
+                       && dce_use_lut(plane_state->format))
+               dpp_base->funcs->dpp_program_input_lut(dpp_base, plane_state->gamma_correction);
+
+       if (tf == NULL)
+               dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
+       else if (tf->type == TF_TYPE_PREDEFINED) {
+               switch (tf->tf) {
+               case TRANSFER_FUNCTION_SRGB:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_HW_sRGB);
+                       break;
+               case TRANSFER_FUNCTION_BT709:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_HW_xvYCC);
+                       break;
+               case TRANSFER_FUNCTION_LINEAR:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
+                       break;
+               case TRANSFER_FUNCTION_PQ:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_USER_PWL);
+                       cm_helper_translate_curve_to_degamma_hw_format(tf, &dpp_base->degamma_params);
+                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base, &dpp_base->degamma_params);
+                       result = true;
+                       break;
+               default:
+                       result = false;
+                       break;
+               }
+       } else if (tf->type == TF_TYPE_BYPASS) {
+               dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
+       } else {
+               cm_helper_translate_curve_to_degamma_hw_format(tf,
+                                       &dpp_base->degamma_params);
+               dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
+                               &dpp_base->degamma_params);
+               result = true;
+       }
+
+       return result;
+}
+
+#define MAX_NUM_HW_POINTS 0x200
+
+static void log_tf(struct dc_context *ctx,
+                               struct dc_transfer_func *tf, uint32_t hw_points_num)
+{
+       // DC_LOG_GAMMA is default logging of all hw points
+       // DC_LOG_ALL_GAMMA logs all points, not only hw points
+       // DC_LOG_ALL_TF_POINTS logs all channels of the tf
+       int i = 0;
+
+       DC_LOG_GAMMA("Gamma Correction TF");
+       DC_LOG_ALL_GAMMA("Logging all tf points...");
+       DC_LOG_ALL_TF_CHANNELS("Logging all channels...");
+
+       for (i = 0; i < hw_points_num; i++) {
+               DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
+               DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
+               DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
+       }
+
+       for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) {
+               DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
+               DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
+               DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
+       }
+}
+
+bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream)
+{
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+
+       if (dpp == NULL)
+               return false;
+
+       dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
+
+       if (stream->out_transfer_func &&
+           stream->out_transfer_func->type == TF_TYPE_PREDEFINED &&
+           stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB)
+               dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_SRGB);
+
+       /* dcn10_translate_regamma_to_hw_format takes 750us, only do it when full
+        * update.
+        */
+       else if (cm_helper_translate_curve_to_hw_format(dc->ctx,
+                       stream->out_transfer_func,
+                       &dpp->regamma_params, false)) {
+               dpp->funcs->dpp_program_regamma_pwl(
+                               dpp,
+                               &dpp->regamma_params, OPP_REGAMMA_USER);
+       } else
+               dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS);
+
+       if (stream != NULL && stream->ctx != NULL &&
+                       stream->out_transfer_func != NULL) {
+               log_tf(stream->ctx,
+                               stream->out_transfer_func,
+                               dpp->regamma_params.hw_points_num);
+       }
+
+       return true;
+}
+
+void dcn10_pipe_control_lock(
+       struct dc *dc,
+       struct pipe_ctx *pipe,
+       bool lock)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* use TG master update lock to lock everything on the TG
+        * therefore only top pipe need to lock
+        */
+       if (!pipe || pipe->top_pipe)
+               return;
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+
+       if (lock)
+               pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
+       else
+               pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+}
+
+/**
+ * delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE.
+ *
+ * Software keepout workaround to prevent cursor update locking from stalling
+ * out cursor updates indefinitely or from old values from being retained in
+ * the case where the viewport changes in the same frame as the cursor.
+ *
+ * The idea is to calculate the remaining time from VPOS to VUPDATE. If it's
+ * too close to VUPDATE, then stall out until VUPDATE finishes.
+ *
+ * TODO: Optimize cursor programming to be once per frame before VUPDATE
+ *       to avoid the need for this workaround.
+ *
+ * @dc: Current DC state
+ * @pipe_ctx: Pipe_ctx pointer for delayed cursor update
+ *
+ * Return: void
+ */
+static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct crtc_position position;
+       uint32_t vupdate_start, vupdate_end;
+       unsigned int lines_to_vupdate, us_to_vupdate, vpos;
+       unsigned int us_per_line, us_vupdate;
+
+       if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position)
+               return;
+
+       if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg)
+               return;
+
+       dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start,
+                                      &vupdate_end);
+
+       dc->hwss.get_position(&pipe_ctx, 1, &position);
+       vpos = position.vertical_count;
+
+       /* Avoid wraparound calculation issues */
+       vupdate_start += stream->timing.v_total;
+       vupdate_end += stream->timing.v_total;
+       vpos += stream->timing.v_total;
+
+       if (vpos <= vupdate_start) {
+               /* VPOS is in VACTIVE or back porch. */
+               lines_to_vupdate = vupdate_start - vpos;
+       } else if (vpos > vupdate_end) {
+               /* VPOS is in the front porch. */
+               return;
+       } else {
+               /* VPOS is in VUPDATE. */
+               lines_to_vupdate = 0;
+       }
+
+       /* Calculate time until VUPDATE in microseconds. */
+       us_per_line =
+               stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
+       us_to_vupdate = lines_to_vupdate * us_per_line;
+
+       /* 70 us is a conservative estimate of cursor update time*/
+       if (us_to_vupdate > 70)
+               return;
+
+       /* Stall out until the cursor update completes. */
+       if (vupdate_end < vupdate_start)
+               vupdate_end += stream->timing.v_total;
+       us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
+       udelay(us_to_vupdate + us_vupdate);
+}
+
+void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
+{
+       /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
+       if (!pipe || pipe->top_pipe)
+               return;
+
+       /* Prevent cursor lock from stalling out cursor updates. */
+       if (lock)
+               delay_cursor_until_vupdate(dc, pipe);
+
+       if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) {
+               union dmub_hw_lock_flags hw_locks = { 0 };
+               struct dmub_hw_lock_inst_flags inst_flags = { 0 };
+
+               hw_locks.bits.lock_cursor = 1;
+               inst_flags.opp_inst = pipe->stream_res.opp->inst;
+
+               dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
+                                       lock,
+                                       &hw_locks,
+                                       &inst_flags);
+       } else
+               dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
+                               pipe->stream_res.opp->inst, lock);
+}
+
+static bool wait_for_reset_trigger_to_occur(
+       struct dc_context *dc_ctx,
+       struct timing_generator *tg)
+{
+       bool rc = false;
+
+       DC_LOGGER_INIT(dc_ctx->logger);
+
+       /* To avoid endless loop we wait at most
+        * frames_to_wait_on_triggered_reset frames for the reset to occur. */
+       const uint32_t frames_to_wait_on_triggered_reset = 10;
+       int i;
+
+       for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
+
+               if (!tg->funcs->is_counter_moving(tg)) {
+                       DC_ERROR("TG counter is not moving!\n");
+                       break;
+               }
+
+               if (tg->funcs->did_triggered_reset_occur(tg)) {
+                       rc = true;
+                       /* usually occurs at i=1 */
+                       DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
+                                       i);
+                       break;
+               }
+
+               /* Wait for one frame. */
+               tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE);
+               tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
+       }
+
+       if (false == rc)
+               DC_ERROR("GSL: Timeout on reset trigger!\n");
+
+       return rc;
+}
+
+static uint64_t reduceSizeAndFraction(uint64_t *numerator,
+                                     uint64_t *denominator,
+                                     bool checkUint32Bounary)
+{
+       int i;
+       bool ret = checkUint32Bounary == false;
+       uint64_t max_int32 = 0xffffffff;
+       uint64_t num, denom;
+       static const uint16_t prime_numbers[] = {
+               2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
+               47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
+               107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
+               167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
+               229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
+               283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353,
+               359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
+               431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487,
+               491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
+               571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
+               641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
+               709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773,
+               787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857,
+               859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
+               941, 947, 953, 967, 971, 977, 983, 991, 997};
+       int count = ARRAY_SIZE(prime_numbers);
+
+       num = *numerator;
+       denom = *denominator;
+       for (i = 0; i < count; i++) {
+               uint32_t num_remainder, denom_remainder;
+               uint64_t num_result, denom_result;
+               if (checkUint32Bounary &&
+                       num <= max_int32 && denom <= max_int32) {
+                       ret = true;
+                       break;
+               }
+               do {
+                       num_result = div_u64_rem(num, prime_numbers[i], &num_remainder);
+                       denom_result = div_u64_rem(denom, prime_numbers[i], &denom_remainder);
+                       if (num_remainder == 0 && denom_remainder == 0) {
+                               num = num_result;
+                               denom = denom_result;
+                       }
+               } while (num_remainder == 0 && denom_remainder == 0);
+       }
+       *numerator = num;
+       *denominator = denom;
+       return ret;
+}
+
+static bool is_low_refresh_rate(struct pipe_ctx *pipe)
+{
+       uint32_t master_pipe_refresh_rate =
+               pipe->stream->timing.pix_clk_100hz * 100 /
+               pipe->stream->timing.h_total /
+               pipe->stream->timing.v_total;
+       return master_pipe_refresh_rate <= 30;
+}
+
+static uint8_t get_clock_divider(struct pipe_ctx *pipe,
+                                bool account_low_refresh_rate)
+{
+       uint32_t clock_divider = 1;
+       uint32_t numpipes = 1;
+
+       if (account_low_refresh_rate && is_low_refresh_rate(pipe))
+               clock_divider *= 2;
+
+       if (pipe->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+               clock_divider *= 2;
+
+       while (pipe->next_odm_pipe) {
+               pipe = pipe->next_odm_pipe;
+               numpipes++;
+       }
+       clock_divider *= numpipes;
+
+       return clock_divider;
+}
+
+static int dcn10_align_pixel_clocks(struct dc *dc, int group_size,
+                                   struct pipe_ctx *grouped_pipes[])
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       int i, master = -1, embedded = -1;
+       struct dc_crtc_timing *hw_crtc_timing;
+       uint64_t phase[MAX_PIPES];
+       uint64_t modulo[MAX_PIPES];
+       unsigned int pclk;
+
+       uint32_t embedded_pix_clk_100hz;
+       uint16_t embedded_h_total;
+       uint16_t embedded_v_total;
+       uint32_t dp_ref_clk_100hz =
+               dc->res_pool->dp_clock_source->ctx->dc->clk_mgr->dprefclk_khz*10;
+
+       DC_LOGGER_INIT(dc_ctx->logger);
+
+       hw_crtc_timing = kcalloc(MAX_PIPES, sizeof(*hw_crtc_timing), GFP_KERNEL);
+       if (!hw_crtc_timing)
+               return master;
+
+       if (dc->config.vblank_alignment_dto_params &&
+               dc->res_pool->dp_clock_source->funcs->override_dp_pix_clk) {
+               embedded_h_total =
+                       (dc->config.vblank_alignment_dto_params >> 32) & 0x7FFF;
+               embedded_v_total =
+                       (dc->config.vblank_alignment_dto_params >> 48) & 0x7FFF;
+               embedded_pix_clk_100hz =
+                       dc->config.vblank_alignment_dto_params & 0xFFFFFFFF;
+
+               for (i = 0; i < group_size; i++) {
+                       grouped_pipes[i]->stream_res.tg->funcs->get_hw_timing(
+                                       grouped_pipes[i]->stream_res.tg,
+                                       &hw_crtc_timing[i]);
+                       dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
+                               dc->res_pool->dp_clock_source,
+                               grouped_pipes[i]->stream_res.tg->inst,
+                               &pclk);
+                       hw_crtc_timing[i].pix_clk_100hz = pclk;
+                       if (dc_is_embedded_signal(
+                                       grouped_pipes[i]->stream->signal)) {
+                               embedded = i;
+                               master = i;
+                               phase[i] = embedded_pix_clk_100hz*100;
+                               modulo[i] = dp_ref_clk_100hz*100;
+                       } else {
+
+                               phase[i] = (uint64_t)embedded_pix_clk_100hz*
+                                       hw_crtc_timing[i].h_total*
+                                       hw_crtc_timing[i].v_total;
+                               phase[i] = div_u64(phase[i], get_clock_divider(grouped_pipes[i], true));
+                               modulo[i] = (uint64_t)dp_ref_clk_100hz*
+                                       embedded_h_total*
+                                       embedded_v_total;
+
+                               if (reduceSizeAndFraction(&phase[i],
+                                               &modulo[i], true) == false) {
+                                       /*
+                                        * this will help to stop reporting
+                                        * this timing synchronizable
+                                        */
+                                       DC_SYNC_INFO("Failed to reduce DTO parameters\n");
+                                       grouped_pipes[i]->stream->has_non_synchronizable_pclk = true;
+                               }
+                       }
+               }
+
+               for (i = 0; i < group_size; i++) {
+                       if (i != embedded && !grouped_pipes[i]->stream->has_non_synchronizable_pclk) {
+                               dc->res_pool->dp_clock_source->funcs->override_dp_pix_clk(
+                                       dc->res_pool->dp_clock_source,
+                                       grouped_pipes[i]->stream_res.tg->inst,
+                                       phase[i], modulo[i]);
+                               dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
+                                       dc->res_pool->dp_clock_source,
+                                       grouped_pipes[i]->stream_res.tg->inst, &pclk);
+                               grouped_pipes[i]->stream->timing.pix_clk_100hz =
+                                       pclk*get_clock_divider(grouped_pipes[i], false);
+                               if (master == -1)
+                                       master = i;
+                       }
+               }
+
+       }
+
+       kfree(hw_crtc_timing);
+       return master;
+}
+
+void dcn10_enable_vblanks_synchronization(
+       struct dc *dc,
+       int group_index,
+       int group_size,
+       struct pipe_ctx *grouped_pipes[])
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct output_pixel_processor *opp;
+       struct timing_generator *tg;
+       int i, width, height, master;
+
+       DC_LOGGER_INIT(dc_ctx->logger);
+
+       for (i = 1; i < group_size; i++) {
+               opp = grouped_pipes[i]->stream_res.opp;
+               tg = grouped_pipes[i]->stream_res.tg;
+               tg->funcs->get_otg_active_size(tg, &width, &height);
+
+               if (!tg->funcs->is_tg_enabled(tg)) {
+                       DC_SYNC_INFO("Skipping timing sync on disabled OTG\n");
+                       return;
+               }
+
+               if (opp->funcs->opp_program_dpg_dimensions)
+                       opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1);
+       }
+
+       for (i = 0; i < group_size; i++) {
+               if (grouped_pipes[i]->stream == NULL)
+                       continue;
+               grouped_pipes[i]->stream->vblank_synchronized = false;
+               grouped_pipes[i]->stream->has_non_synchronizable_pclk = false;
+       }
+
+       DC_SYNC_INFO("Aligning DP DTOs\n");
+
+       master = dcn10_align_pixel_clocks(dc, group_size, grouped_pipes);
+
+       DC_SYNC_INFO("Synchronizing VBlanks\n");
+
+       if (master >= 0) {
+               for (i = 0; i < group_size; i++) {
+                       if (i != master && !grouped_pipes[i]->stream->has_non_synchronizable_pclk)
+                               grouped_pipes[i]->stream_res.tg->funcs->align_vblanks(
+                                       grouped_pipes[master]->stream_res.tg,
+                                       grouped_pipes[i]->stream_res.tg,
+                                       grouped_pipes[master]->stream->timing.pix_clk_100hz,
+                                       grouped_pipes[i]->stream->timing.pix_clk_100hz,
+                                       get_clock_divider(grouped_pipes[master], false),
+                                       get_clock_divider(grouped_pipes[i], false));
+                       grouped_pipes[i]->stream->vblank_synchronized = true;
+               }
+               grouped_pipes[master]->stream->vblank_synchronized = true;
+               DC_SYNC_INFO("Sync complete\n");
+       }
+
+       for (i = 1; i < group_size; i++) {
+               opp = grouped_pipes[i]->stream_res.opp;
+               tg = grouped_pipes[i]->stream_res.tg;
+               tg->funcs->get_otg_active_size(tg, &width, &height);
+               if (opp->funcs->opp_program_dpg_dimensions)
+                       opp->funcs->opp_program_dpg_dimensions(opp, width, height);
+       }
+}
+
+void dcn10_enable_timing_synchronization(
+       struct dc *dc,
+       int group_index,
+       int group_size,
+       struct pipe_ctx *grouped_pipes[])
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct output_pixel_processor *opp;
+       struct timing_generator *tg;
+       int i, width, height;
+
+       DC_LOGGER_INIT(dc_ctx->logger);
+
+       DC_SYNC_INFO("Setting up OTG reset trigger\n");
+
+       for (i = 1; i < group_size; i++) {
+               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
+                       continue;
+
+               opp = grouped_pipes[i]->stream_res.opp;
+               tg = grouped_pipes[i]->stream_res.tg;
+               tg->funcs->get_otg_active_size(tg, &width, &height);
+
+               if (!tg->funcs->is_tg_enabled(tg)) {
+                       DC_SYNC_INFO("Skipping timing sync on disabled OTG\n");
+                       return;
+               }
+
+               if (opp->funcs->opp_program_dpg_dimensions)
+                       opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1);
+       }
+
+       for (i = 0; i < group_size; i++) {
+               if (grouped_pipes[i]->stream == NULL)
+                       continue;
+
+               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
+                       continue;
+
+               grouped_pipes[i]->stream->vblank_synchronized = false;
+       }
+
+       for (i = 1; i < group_size; i++) {
+               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
+                       continue;
+
+               grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
+                               grouped_pipes[i]->stream_res.tg,
+                               grouped_pipes[0]->stream_res.tg->inst);
+       }
+
+       DC_SYNC_INFO("Waiting for trigger\n");
+
+       /* Need to get only check 1 pipe for having reset as all the others are
+        * synchronized. Look at last pipe programmed to reset.
+        */
+
+       if (grouped_pipes[1]->stream && grouped_pipes[1]->stream->mall_stream_config.type != SUBVP_PHANTOM)
+               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[1]->stream_res.tg);
+
+       for (i = 1; i < group_size; i++) {
+               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
+                       continue;
+
+               grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
+                               grouped_pipes[i]->stream_res.tg);
+       }
+
+       for (i = 1; i < group_size; i++) {
+               if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
+                       continue;
+
+               opp = grouped_pipes[i]->stream_res.opp;
+               tg = grouped_pipes[i]->stream_res.tg;
+               tg->funcs->get_otg_active_size(tg, &width, &height);
+               if (opp->funcs->opp_program_dpg_dimensions)
+                       opp->funcs->opp_program_dpg_dimensions(opp, width, height);
+       }
+
+       DC_SYNC_INFO("Sync complete\n");
+}
+
+void dcn10_enable_per_frame_crtc_position_reset(
+       struct dc *dc,
+       int group_size,
+       struct pipe_ctx *grouped_pipes[])
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       int i;
+
+       DC_LOGGER_INIT(dc_ctx->logger);
+
+       DC_SYNC_INFO("Setting up\n");
+       for (i = 0; i < group_size; i++)
+               if (grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset)
+                       grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset(
+                                       grouped_pipes[i]->stream_res.tg,
+                                       0,
+                                       &grouped_pipes[i]->stream->triggered_crtc_reset);
+
+       DC_SYNC_INFO("Waiting for trigger\n");
+
+       for (i = 0; i < group_size; i++)
+               wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
+
+       DC_SYNC_INFO("Multi-display sync is complete\n");
+}
+
+static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1,
+               struct vm_system_aperture_param *apt,
+               struct dce_hwseq *hws)
+{
+       PHYSICAL_ADDRESS_LOC physical_page_number;
+       uint32_t logical_addr_low;
+       uint32_t logical_addr_high;
+
+       REG_GET(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
+                       PHYSICAL_PAGE_NUMBER_MSB, &physical_page_number.high_part);
+       REG_GET(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
+                       PHYSICAL_PAGE_NUMBER_LSB, &physical_page_number.low_part);
+
+       REG_GET(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+                       LOGICAL_ADDR, &logical_addr_low);
+
+       REG_GET(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+                       LOGICAL_ADDR, &logical_addr_high);
+
+       apt->sys_default.quad_part =  physical_page_number.quad_part << 12;
+       apt->sys_low.quad_part =  (int64_t)logical_addr_low << 18;
+       apt->sys_high.quad_part =  (int64_t)logical_addr_high << 18;
+}
+
+/* Temporary read settings, future will get values from kmd directly */
+static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
+               struct vm_context0_param *vm0,
+               struct dce_hwseq *hws)
+{
+       PHYSICAL_ADDRESS_LOC fb_base;
+       PHYSICAL_ADDRESS_LOC fb_offset;
+       uint32_t fb_base_value;
+       uint32_t fb_offset_value;
+
+       REG_GET(DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, &fb_base_value);
+       REG_GET(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, &fb_offset_value);
+
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
+                       PAGE_DIRECTORY_ENTRY_HI32, &vm0->pte_base.high_part);
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
+                       PAGE_DIRECTORY_ENTRY_LO32, &vm0->pte_base.low_part);
+
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
+                       LOGICAL_PAGE_NUMBER_HI4, &vm0->pte_start.high_part);
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
+                       LOGICAL_PAGE_NUMBER_LO32, &vm0->pte_start.low_part);
+
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
+                       LOGICAL_PAGE_NUMBER_HI4, &vm0->pte_end.high_part);
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
+                       LOGICAL_PAGE_NUMBER_LO32, &vm0->pte_end.low_part);
+
+       REG_GET(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
+                       PHYSICAL_PAGE_ADDR_HI4, &vm0->fault_default.high_part);
+       REG_GET(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
+                       PHYSICAL_PAGE_ADDR_LO32, &vm0->fault_default.low_part);
+
+       /*
+        * The values in VM_CONTEXT0_PAGE_TABLE_BASE_ADDR is in UMA space.
+        * Therefore we need to do
+        * DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR
+        * - DCHUBBUB_SDPIF_FB_OFFSET + DCHUBBUB_SDPIF_FB_BASE
+        */
+       fb_base.quad_part = (uint64_t)fb_base_value << 24;
+       fb_offset.quad_part = (uint64_t)fb_offset_value << 24;
+       vm0->pte_base.quad_part += fb_base.quad_part;
+       vm0->pte_base.quad_part -= fb_offset.quad_part;
+}
+
+
+static void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp)
+{
+       struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+       struct vm_system_aperture_param apt = {0};
+       struct vm_context0_param vm0 = {0};
+
+       mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
+       mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
+
+       hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt);
+       hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0);
+}
+
+static void dcn10_enable_plane(
+       struct dc *dc,
+       struct pipe_ctx *pipe_ctx,
+       struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+
+       if (dc->debug.sanity_checks) {
+               hws->funcs.verify_allow_pstate_change_high(dc);
+       }
+
+       undo_DEGVIDCN10_253_wa(dc);
+
+       power_on_plane_resources(dc->hwseq,
+               pipe_ctx->plane_res.hubp->inst);
+
+       /* enable DCFCLK current DCHUB */
+       pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
+
+       /* make sure OPP_PIPE_CLOCK_EN = 1 */
+       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+                       pipe_ctx->stream_res.opp,
+                       true);
+
+       if (dc->config.gpu_vm_support)
+               dcn10_program_pte_vm(hws, pipe_ctx->plane_res.hubp);
+
+       if (dc->debug.sanity_checks) {
+               hws->funcs.verify_allow_pstate_change_high(dc);
+       }
+
+       if (!pipe_ctx->top_pipe
+               && pipe_ctx->plane_state
+               && pipe_ctx->plane_state->flip_int_enabled
+               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
+                       pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
+
+}
+
+void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
+{
+       int i = 0;
+       struct dpp_grph_csc_adjustment adjust;
+       memset(&adjust, 0, sizeof(adjust));
+       adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+
+       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
+               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+                       adjust.temperature_matrix[i] =
+                               pipe_ctx->stream->gamut_remap_matrix.matrix[i];
+       } else if (pipe_ctx->plane_state &&
+                  pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) {
+               adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+                       adjust.temperature_matrix[i] =
+                               pipe_ctx->plane_state->gamut_remap_matrix.matrix[i];
+       }
+
+       pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
+}
+
+
+static bool dcn10_is_rear_mpo_fix_required(struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace)
+{
+       if (pipe_ctx->plane_state && pipe_ctx->plane_state->layer_index > 0 && is_rgb_cspace(colorspace)) {
+               if (pipe_ctx->top_pipe) {
+                       struct pipe_ctx *top = pipe_ctx->top_pipe;
+
+                       while (top->top_pipe)
+                               top = top->top_pipe; // Traverse to top pipe_ctx
+                       if (top->plane_state && top->plane_state->layer_index == 0)
+                               return true; // Front MPO plane not hidden
+               }
+       }
+       return false;
+}
+
+static void dcn10_set_csc_adjustment_rgb_mpo_fix(struct pipe_ctx *pipe_ctx, uint16_t *matrix)
+{
+       // Override rear plane RGB bias to fix MPO brightness
+       uint16_t rgb_bias = matrix[3];
+
+       matrix[3] = 0;
+       matrix[7] = 0;
+       matrix[11] = 0;
+       pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
+       matrix[3] = rgb_bias;
+       matrix[7] = rgb_bias;
+       matrix[11] = rgb_bias;
+}
+
+void dcn10_program_output_csc(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum dc_color_space colorspace,
+               uint16_t *matrix,
+               int opp_id)
+{
+       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
+               if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) {
+
+                       /* MPO is broken with RGB colorspaces when OCSC matrix
+                        * brightness offset >= 0 on DCN1 due to OCSC before MPC
+                        * Blending adds offsets from front + rear to rear plane
+                        *
+                        * Fix is to set RGB bias to 0 on rear plane, top plane
+                        * black value pixels add offset instead of rear + front
+                        */
+
+                       int16_t rgb_bias = matrix[3];
+                       // matrix[3/7/11] are all the same offset value
+
+                       if (rgb_bias > 0 && dcn10_is_rear_mpo_fix_required(pipe_ctx, colorspace)) {
+                               dcn10_set_csc_adjustment_rgb_mpo_fix(pipe_ctx, matrix);
+                       } else {
+                               pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
+                       }
+               }
+       } else {
+               if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL)
+                       pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
+       }
+}
+
+static void dcn10_update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state)
+{
+       struct dc_bias_and_scale bns_params = {0};
+
+       // program the input csc
+       dpp->funcs->dpp_setup(dpp,
+                       plane_state->format,
+                       EXPANSION_MODE_ZERO,
+                       plane_state->input_csc_color_matrix,
+                       plane_state->color_space,
+                       NULL);
+
+       //set scale and bias registers
+       build_prescale_params(&bns_params, plane_state);
+       if (dpp->funcs->dpp_program_bias_and_scale)
+               dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
+}
+
+void dcn10_update_visual_confirm_color(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               int mpcc_id)
+{
+       struct mpc *mpc = dc->res_pool->mpc;
+
+       if (mpc->funcs->set_bg_color) {
+               memcpy(&pipe_ctx->plane_state->visual_confirm_color, &(pipe_ctx->visual_confirm_color), sizeof(struct tg_color));
+               mpc->funcs->set_bg_color(mpc, &(pipe_ctx->visual_confirm_color), mpcc_id);
+       }
+}
+
+void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct mpcc_blnd_cfg blnd_cfg = {0};
+       bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
+       int mpcc_id;
+       struct mpcc *new_mpcc;
+       struct mpc *mpc = dc->res_pool->mpc;
+       struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
+
+       blnd_cfg.overlap_only = false;
+       blnd_cfg.global_gain = 0xff;
+
+       if (per_pixel_alpha) {
+               /* DCN1.0 has output CM before MPC which seems to screw with
+                * pre-multiplied alpha.
+                */
+               blnd_cfg.pre_multiplied_alpha = (is_rgb_cspace(
+                               pipe_ctx->stream->output_color_space)
+                                               && pipe_ctx->plane_state->pre_multiplied_alpha);
+               if (pipe_ctx->plane_state->global_alpha) {
+                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN;
+                       blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value;
+               } else {
+                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
+               }
+       } else {
+               blnd_cfg.pre_multiplied_alpha = false;
+               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
+       }
+
+       if (pipe_ctx->plane_state->global_alpha)
+               blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
+       else
+               blnd_cfg.global_alpha = 0xff;
+
+       /*
+        * TODO: remove hack
+        * Note: currently there is a bug in init_hw such that
+        * on resume from hibernate, BIOS sets up MPCC0, and
+        * we do mpcc_remove but the mpcc cannot go to idle
+        * after remove. This cause us to pick mpcc1 here,
+        * which causes a pstate hang for yet unknown reason.
+        */
+       mpcc_id = hubp->inst;
+
+       /* If there is no full update, don't need to touch MPC tree*/
+       if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
+               mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
+               dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
+               return;
+       }
+
+       /* check if this MPCC is already being used */
+       new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
+       /* remove MPCC if being used */
+       if (new_mpcc != NULL)
+               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, new_mpcc);
+       else
+               if (dc->debug.sanity_checks)
+                       mpc->funcs->assert_mpcc_idle_before_connect(
+                                       dc->res_pool->mpc, mpcc_id);
+
+       /* Call MPC to insert new plane */
+       new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
+                       mpc_tree_params,
+                       &blnd_cfg,
+                       NULL,
+                       NULL,
+                       hubp->inst,
+                       mpcc_id);
+       dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
+
+       ASSERT(new_mpcc != NULL);
+       hubp->opp_id = pipe_ctx->stream_res.opp->inst;
+       hubp->mpcc_id = mpcc_id;
+}
+
+static void update_scaler(struct pipe_ctx *pipe_ctx)
+{
+       bool per_pixel_alpha =
+                       pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
+
+       pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
+       pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP;
+       /* scaler configuration */
+       pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
+                       pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
+}
+
+static void dcn10_update_dchubp_dpp(
+       struct dc *dc,
+       struct pipe_ctx *pipe_ctx,
+       struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       struct plane_size size = plane_state->plane_size;
+       unsigned int compat_level = 0;
+       bool should_divided_by_2 = false;
+
+       /* depends on DML calculation, DPP clock value may change dynamically */
+       /* If request max dpp clk is lower than current dispclk, no need to
+        * divided by 2
+        */
+       if (plane_state->update_flags.bits.full_update) {
+
+               /* new calculated dispclk, dppclk are stored in
+                * context->bw_ctx.bw.dcn.clk.dispclk_khz / dppclk_khz. current
+                * dispclk, dppclk are from dc->clk_mgr->clks.dispclk_khz.
+                * dcn10_validate_bandwidth compute new dispclk, dppclk.
+                * dispclk will put in use after optimize_bandwidth when
+                * ramp_up_dispclk_with_dpp is called.
+                * there are two places for dppclk be put in use. One location
+                * is the same as the location as dispclk. Another is within
+                * update_dchubp_dpp which happens between pre_bandwidth and
+                * optimize_bandwidth.
+                * dppclk updated within update_dchubp_dpp will cause new
+                * clock values of dispclk and dppclk not be in use at the same
+                * time. when clocks are decreased, this may cause dppclk is
+                * lower than previous configuration and let pipe stuck.
+                * for example, eDP + external dp,  change resolution of DP from
+                * 1920x1080x144hz to 1280x960x60hz.
+                * before change: dispclk = 337889 dppclk = 337889
+                * change mode, dcn10_validate_bandwidth calculate
+                *                dispclk = 143122 dppclk = 143122
+                * update_dchubp_dpp be executed before dispclk be updated,
+                * dispclk = 337889, but dppclk use new value dispclk /2 =
+                * 168944. this will cause pipe pstate warning issue.
+                * solution: between pre_bandwidth and optimize_bandwidth, while
+                * dispclk is going to be decreased, keep dppclk = dispclk
+                **/
+               if (context->bw_ctx.bw.dcn.clk.dispclk_khz <
+                               dc->clk_mgr->clks.dispclk_khz)
+                       should_divided_by_2 = false;
+               else
+                       should_divided_by_2 =
+                                       context->bw_ctx.bw.dcn.clk.dppclk_khz <=
+                                       dc->clk_mgr->clks.dispclk_khz / 2;
+
+               dpp->funcs->dpp_dppclk_control(
+                               dpp,
+                               should_divided_by_2,
+                               true);
+
+               if (dc->res_pool->dccg)
+                       dc->res_pool->dccg->funcs->update_dpp_dto(
+                                       dc->res_pool->dccg,
+                                       dpp->inst,
+                                       pipe_ctx->plane_res.bw.dppclk_khz);
+               else
+                       dc->clk_mgr->clks.dppclk_khz = should_divided_by_2 ?
+                                               dc->clk_mgr->clks.dispclk_khz / 2 :
+                                                       dc->clk_mgr->clks.dispclk_khz;
+       }
+
+       /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
+        * VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
+        * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
+        */
+       if (plane_state->update_flags.bits.full_update) {
+               hubp->funcs->hubp_vtg_sel(hubp, pipe_ctx->stream_res.tg->inst);
+
+               hubp->funcs->hubp_setup(
+                       hubp,
+                       &pipe_ctx->dlg_regs,
+                       &pipe_ctx->ttu_regs,
+                       &pipe_ctx->rq_regs,
+                       &pipe_ctx->pipe_dlg_param);
+               hubp->funcs->hubp_setup_interdependent(
+                       hubp,
+                       &pipe_ctx->dlg_regs,
+                       &pipe_ctx->ttu_regs);
+       }
+
+       size.surface_size = pipe_ctx->plane_res.scl_data.viewport;
+
+       if (plane_state->update_flags.bits.full_update ||
+               plane_state->update_flags.bits.bpp_change)
+               dcn10_update_dpp(dpp, plane_state);
+
+       if (plane_state->update_flags.bits.full_update ||
+               plane_state->update_flags.bits.per_pixel_alpha_change ||
+               plane_state->update_flags.bits.global_alpha_change)
+               hws->funcs.update_mpcc(dc, pipe_ctx);
+
+       if (plane_state->update_flags.bits.full_update ||
+               plane_state->update_flags.bits.per_pixel_alpha_change ||
+               plane_state->update_flags.bits.global_alpha_change ||
+               plane_state->update_flags.bits.scaling_change ||
+               plane_state->update_flags.bits.position_change) {
+               update_scaler(pipe_ctx);
+       }
+
+       if (plane_state->update_flags.bits.full_update ||
+               plane_state->update_flags.bits.scaling_change ||
+               plane_state->update_flags.bits.position_change) {
+               hubp->funcs->mem_program_viewport(
+                       hubp,
+                       &pipe_ctx->plane_res.scl_data.viewport,
+                       &pipe_ctx->plane_res.scl_data.viewport_c);
+       }
+
+       if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
+               dc->hwss.set_cursor_position(pipe_ctx);
+               dc->hwss.set_cursor_attribute(pipe_ctx);
+
+               if (dc->hwss.set_cursor_sdr_white_level)
+                       dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
+       }
+
+       if (plane_state->update_flags.bits.full_update) {
+               /*gamut remap*/
+               dc->hwss.program_gamut_remap(pipe_ctx);
+
+               dc->hwss.program_output_csc(dc,
+                               pipe_ctx,
+                               pipe_ctx->stream->output_color_space,
+                               pipe_ctx->stream->csc_color_matrix.matrix,
+                               pipe_ctx->stream_res.opp->inst);
+       }
+
+       if (plane_state->update_flags.bits.full_update ||
+               plane_state->update_flags.bits.pixel_format_change ||
+               plane_state->update_flags.bits.horizontal_mirror_change ||
+               plane_state->update_flags.bits.rotation_change ||
+               plane_state->update_flags.bits.swizzle_change ||
+               plane_state->update_flags.bits.dcc_change ||
+               plane_state->update_flags.bits.bpp_change ||
+               plane_state->update_flags.bits.scaling_change ||
+               plane_state->update_flags.bits.plane_size_change) {
+               hubp->funcs->hubp_program_surface_config(
+                       hubp,
+                       plane_state->format,
+                       &plane_state->tiling_info,
+                       &size,
+                       plane_state->rotation,
+                       &plane_state->dcc,
+                       plane_state->horizontal_mirror,
+                       compat_level);
+       }
+
+       hubp->power_gated = false;
+
+       hws->funcs.update_plane_addr(dc, pipe_ctx);
+
+       if (is_pipe_tree_visible(pipe_ctx))
+               hubp->funcs->set_blank(hubp, false);
+}
+
+void dcn10_blank_pixel_data(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool blank)
+{
+       enum dc_color_space color_space;
+       struct tg_color black_color = {0};
+       struct stream_resource *stream_res = &pipe_ctx->stream_res;
+       struct dc_stream_state *stream = pipe_ctx->stream;
+
+       /* program otg blank color */
+       color_space = stream->output_color_space;
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       /*
+        * The way 420 is packed, 2 channels carry Y component, 1 channel
+        * alternate between Cb and Cr, so both channels need the pixel
+        * value for Y
+        */
+       if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+               black_color.color_r_cr = black_color.color_g_y;
+
+
+       if (stream_res->tg->funcs->set_blank_color)
+               stream_res->tg->funcs->set_blank_color(
+                               stream_res->tg,
+                               &black_color);
+
+       if (!blank) {
+               if (stream_res->tg->funcs->set_blank)
+                       stream_res->tg->funcs->set_blank(stream_res->tg, blank);
+               if (stream_res->abm) {
+                       dc->hwss.set_pipe(pipe_ctx);
+                       stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
+               }
+       } else {
+               dc->hwss.set_abm_immediate_disable(pipe_ctx);
+               if (stream_res->tg->funcs->set_blank) {
+                       stream_res->tg->funcs->wait_for_state(stream_res->tg, CRTC_STATE_VBLANK);
+                       stream_res->tg->funcs->set_blank(stream_res->tg, blank);
+               }
+       }
+}
+
+void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx)
+{
+       struct fixed31_32 multiplier = pipe_ctx->plane_state->hdr_mult;
+       uint32_t hw_mult = 0x1f000; // 1.0 default multiplier
+       struct custom_float_format fmt;
+
+       fmt.exponenta_bits = 6;
+       fmt.mantissa_bits = 12;
+       fmt.sign = true;
+
+
+       if (!dc_fixpt_eq(multiplier, dc_fixpt_from_int(0))) // check != 0
+               convert_to_custom_float_format(multiplier, &fmt, &hw_mult);
+
+       pipe_ctx->plane_res.dpp->funcs->dpp_set_hdr_multiplier(
+                       pipe_ctx->plane_res.dpp, hw_mult);
+}
+
+void dcn10_program_pipe(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+
+       if (pipe_ctx->top_pipe == NULL) {
+               bool blank = !is_pipe_tree_visible(pipe_ctx);
+
+               pipe_ctx->stream_res.tg->funcs->program_global_sync(
+                               pipe_ctx->stream_res.tg,
+                               calculate_vready_offset_for_group(pipe_ctx),
+                               pipe_ctx->pipe_dlg_param.vstartup_start,
+                               pipe_ctx->pipe_dlg_param.vupdate_offset,
+                               pipe_ctx->pipe_dlg_param.vupdate_width);
+
+               pipe_ctx->stream_res.tg->funcs->set_vtg_params(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
+
+               if (hws->funcs.setup_vupdate_interrupt)
+                       hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
+
+               hws->funcs.blank_pixel_data(dc, pipe_ctx, blank);
+       }
+
+       if (pipe_ctx->plane_state->update_flags.bits.full_update)
+               dcn10_enable_plane(dc, pipe_ctx, context);
+
+       dcn10_update_dchubp_dpp(dc, pipe_ctx, context);
+
+       hws->funcs.set_hdr_multiplier(pipe_ctx);
+
+       if (pipe_ctx->plane_state->update_flags.bits.full_update ||
+                       pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+                       pipe_ctx->plane_state->update_flags.bits.gamma_change)
+               hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
+
+       /* dcn10_translate_regamma_to_hw_format takes 750us to finish
+        * only do gamma programming for full update.
+        * TODO: This can be further optimized/cleaned up
+        * Always call this for now since it does memcmp inside before
+        * doing heavy calculation and programming
+        */
+       if (pipe_ctx->plane_state->update_flags.bits.full_update)
+               hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
+}
+
+void dcn10_wait_for_pending_cleared(struct dc *dc,
+               struct dc_state *context)
+{
+               struct pipe_ctx *pipe_ctx;
+               struct timing_generator *tg;
+               int i;
+
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       pipe_ctx = &context->res_ctx.pipe_ctx[i];
+                       tg = pipe_ctx->stream_res.tg;
+
+                       /*
+                        * Only wait for top pipe's tg penindg bit
+                        * Also skip if pipe is disabled.
+                        */
+                       if (pipe_ctx->top_pipe ||
+                           !pipe_ctx->stream || !pipe_ctx->plane_state ||
+                           !tg->funcs->is_tg_enabled(tg))
+                               continue;
+
+                       /*
+                        * Wait for VBLANK then VACTIVE to ensure we get VUPDATE.
+                        * For some reason waiting for OTG_UPDATE_PENDING cleared
+                        * seems to not trigger the update right away, and if we
+                        * lock again before VUPDATE then we don't get a separated
+                        * operation.
+                        */
+                       pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
+                       pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+               }
+}
+
+void dcn10_post_unlock_program_front_end(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe_ctx->top_pipe &&
+                       !pipe_ctx->prev_odm_pipe &&
+                       pipe_ctx->stream) {
+                       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+                       if (context->stream_status[i].plane_count == 0)
+                               false_optc_underflow_wa(dc, pipe_ctx->stream, tg);
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
+                       dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) {
+                       dc->hwss.optimize_bandwidth(dc, context);
+                       break;
+               }
+
+       if (dc->hwseq->wa.DEGVIDCN10_254)
+               hubbub1_wm_change_req_wa(dc->res_pool->hubbub);
+}
+
+static void dcn10_stereo_hw_frame_pack_wa(struct dc *dc, struct dc_state *context)
+{
+       uint8_t i;
+
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->streams[i]->timing.timing_3d_format
+                               == TIMING_3D_FORMAT_HW_FRAME_PACKING) {
+                       /*
+                        * Disable stutter
+                        */
+                       hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, false);
+                       break;
+               }
+       }
+}
+
+void dcn10_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       int min_fclk_khz, min_dcfclk_khz, socclk_khz;
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+
+       if (context->stream_count == 0)
+               context->bw_ctx.bw.dcn.clk.phyclk_khz = 0;
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       false);
+
+       dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
+                       &context->bw_ctx.bw.dcn.watermarks,
+                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
+                       true);
+       dcn10_stereo_hw_frame_pack_wa(dc, context);
+
+       if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
+               DC_FP_START();
+               dcn_get_soc_clks(
+                       dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
+               DC_FP_END();
+               dcn_bw_notify_pplib_of_wm_ranges(
+                       dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
+       }
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+}
+
+void dcn10_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       int min_fclk_khz, min_dcfclk_khz, socclk_khz;
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+
+       if (context->stream_count == 0)
+               context->bw_ctx.bw.dcn.clk.phyclk_khz = 0;
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       true);
+
+       hubbub->funcs->program_watermarks(hubbub,
+                       &context->bw_ctx.bw.dcn.watermarks,
+                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
+                       true);
+
+       dcn10_stereo_hw_frame_pack_wa(dc, context);
+
+       if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
+               DC_FP_START();
+               dcn_get_soc_clks(
+                       dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
+               DC_FP_END();
+               dcn_bw_notify_pplib_of_wm_ranges(
+                       dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
+       }
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+}
+
+void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
+               int num_pipes, struct dc_crtc_timing_adjust adjust)
+{
+       int i = 0;
+       struct drr_params params = {0};
+       // DRR set trigger event mapped to OTG_TRIG_A (bit 11) for manual control flow
+       unsigned int event_triggers = 0x800;
+       // Note DRR trigger events are generated regardless of whether num frames met.
+       unsigned int num_frames = 2;
+
+       params.vertical_total_max = adjust.v_total_max;
+       params.vertical_total_min = adjust.v_total_min;
+       params.vertical_total_mid = adjust.v_total_mid;
+       params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num;
+       /* TODO: If multiple pipes are to be supported, you need
+        * some GSL stuff. Static screen triggers may be programmed differently
+        * as well.
+        */
+       for (i = 0; i < num_pipes; i++) {
+               if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) {
+                       if (pipe_ctx[i]->stream_res.tg->funcs->set_drr)
+                               pipe_ctx[i]->stream_res.tg->funcs->set_drr(
+                                       pipe_ctx[i]->stream_res.tg, &params);
+                       if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
+                               if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control)
+                                       pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
+                                               pipe_ctx[i]->stream_res.tg,
+                                               event_triggers, num_frames);
+               }
+       }
+}
+
+void dcn10_get_position(struct pipe_ctx **pipe_ctx,
+               int num_pipes,
+               struct crtc_position *position)
+{
+       int i = 0;
+
+       /* TODO: handle pipes > 1
+        */
+       for (i = 0; i < num_pipes; i++)
+               pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
+}
+
+void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
+               int num_pipes, const struct dc_static_screen_params *params)
+{
+       unsigned int i;
+       unsigned int triggers = 0;
+
+       if (params->triggers.surface_update)
+               triggers |= 0x80;
+       if (params->triggers.cursor_update)
+               triggers |= 0x2;
+       if (params->triggers.force_trigger)
+               triggers |= 0x1;
+
+       for (i = 0; i < num_pipes; i++)
+               pipe_ctx[i]->stream_res.tg->funcs->
+                       set_static_screen_control(pipe_ctx[i]->stream_res.tg,
+                                       triggers, params->num_frames);
+}
+
+static void dcn10_config_stereo_parameters(
+               struct dc_stream_state *stream, struct crtc_stereo_flags *flags)
+{
+       enum view_3d_format view_format = stream->view_format;
+       enum dc_timing_3d_format timing_3d_format =\
+                       stream->timing.timing_3d_format;
+       bool non_stereo_timing = false;
+
+       if (timing_3d_format == TIMING_3D_FORMAT_NONE ||
+               timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE ||
+               timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM)
+               non_stereo_timing = true;
+
+       if (non_stereo_timing == false &&
+               view_format == VIEW_3D_FORMAT_FRAME_SEQUENTIAL) {
+
+               flags->PROGRAM_STEREO         = 1;
+               flags->PROGRAM_POLARITY       = 1;
+               if (timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE ||
+                       timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
+                       timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
+                       timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
+
+                       if (stream->link && stream->link->ddc) {
+                               enum display_dongle_type dongle = \
+                                               stream->link->ddc->dongle_type;
+
+                               if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
+                                       dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
+                                       dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
+                                       flags->DISABLE_STEREO_DP_SYNC = 1;
+                       }
+               }
+               flags->RIGHT_EYE_POLARITY =\
+                               stream->timing.flags.RIGHT_EYE_3D_POLARITY;
+               if (timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
+                       flags->FRAME_PACKED = 1;
+       }
+
+       return;
+}
+
+void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
+{
+       struct crtc_stereo_flags flags = { 0 };
+       struct dc_stream_state *stream = pipe_ctx->stream;
+
+       dcn10_config_stereo_parameters(stream, &flags);
+
+       if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
+               if (!dc_set_generic_gpio_for_stereo(true, dc->ctx->gpio_service))
+                       dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
+       } else {
+               dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
+       }
+
+       pipe_ctx->stream_res.opp->funcs->opp_program_stereo(
+               pipe_ctx->stream_res.opp,
+               flags.PROGRAM_STEREO == 1,
+               &stream->timing);
+
+       pipe_ctx->stream_res.tg->funcs->program_stereo(
+               pipe_ctx->stream_res.tg,
+               &stream->timing,
+               &flags);
+
+       return;
+}
+
+static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
+{
+       int i;
+
+       for (i = 0; i < res_pool->pipe_count; i++) {
+               if (res_pool->hubps[i]->inst == mpcc_inst)
+                       return res_pool->hubps[i];
+       }
+       ASSERT(false);
+       return NULL;
+}
+
+void dcn10_wait_for_mpcc_disconnect(
+               struct dc *dc,
+               struct resource_pool *res_pool,
+               struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       int mpcc_inst;
+
+       if (dc->debug.sanity_checks) {
+               hws->funcs.verify_allow_pstate_change_high(dc);
+       }
+
+       if (!pipe_ctx->stream_res.opp)
+               return;
+
+       for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
+               if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
+                       struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
+
+                       if (pipe_ctx->stream_res.tg &&
+                               pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg))
+                               res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
+                       pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
+                       hubp->funcs->set_blank(hubp, true);
+               }
+       }
+
+       if (dc->debug.sanity_checks) {
+               hws->funcs.verify_allow_pstate_change_high(dc);
+       }
+
+}
+
+bool dcn10_dummy_display_power_gating(
+       struct dc *dc,
+       uint8_t controller_id,
+       struct dc_bios *dcb,
+       enum pipe_gating_control power_gating)
+{
+       return true;
+}
+
+void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       bool flip_pending;
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
+
+       if (plane_state == NULL)
+               return;
+
+       flip_pending = pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending(
+                                       pipe_ctx->plane_res.hubp);
+
+       plane_state->status.is_flip_pending = plane_state->status.is_flip_pending || flip_pending;
+
+       if (!flip_pending)
+               plane_state->status.current_address = plane_state->status.requested_address;
+
+       if (plane_state->status.current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+                       tg->funcs->is_stereo_left_eye) {
+               plane_state->status.is_right_eye =
+                               !tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
+       }
+
+       if (dc->hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied) {
+               struct dce_hwseq *hwseq = dc->hwseq;
+               struct timing_generator *tg = dc->res_pool->timing_generators[0];
+               unsigned int cur_frame = tg->funcs->get_frame_count(tg);
+
+               if (cur_frame != hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied_on_frame) {
+                       struct hubbub *hubbub = dc->res_pool->hubbub;
+
+                       hubbub->funcs->allow_self_refresh_control(hubbub, !dc->debug.disable_stutter);
+                       hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied = false;
+               }
+       }
+}
+
+void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
+{
+       struct hubbub *hubbub = hws->ctx->dc->res_pool->hubbub;
+
+       /* In DCN, this programming sequence is owned by the hubbub */
+       hubbub->funcs->update_dchub(hubbub, dh_data);
+}
+
+static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *test_pipe, *split_pipe;
+       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
+       struct rect r1 = scl_data->recout, r2, r2_half;
+       int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
+       int cur_layer = pipe_ctx->plane_state->layer_index;
+
+       /**
+        * Disable the cursor if there's another pipe above this with a
+        * plane that contains this pipe's viewport to prevent double cursor
+        * and incorrect scaling artifacts.
+        */
+       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
+            test_pipe = test_pipe->top_pipe) {
+               // Skip invisible layer and pipe-split plane on same layer
+               if (!test_pipe->plane_state ||
+                   !test_pipe->plane_state->visible ||
+                   test_pipe->plane_state->layer_index == cur_layer)
+                       continue;
+
+               r2 = test_pipe->plane_res.scl_data.recout;
+               r2_r = r2.x + r2.width;
+               r2_b = r2.y + r2.height;
+               split_pipe = test_pipe;
+
+               /**
+                * There is another half plane on same layer because of
+                * pipe-split, merge together per same height.
+                */
+               for (split_pipe = pipe_ctx->top_pipe; split_pipe;
+                    split_pipe = split_pipe->top_pipe)
+                       if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
+                               r2_half = split_pipe->plane_res.scl_data.recout;
+                               r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
+                               r2.width = r2.width + r2_half.width;
+                               r2_r = r2.x + r2.width;
+                               break;
+                       }
+
+               if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
+                       return true;
+       }
+
+       return false;
+}
+
+void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+       struct dc_cursor_mi_param param = {
+               .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
+               .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz,
+               .viewport = pipe_ctx->plane_res.scl_data.viewport,
+               .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
+               .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
+               .rotation = pipe_ctx->plane_state->rotation,
+               .mirror = pipe_ctx->plane_state->horizontal_mirror
+       };
+       bool pipe_split_on = false;
+       bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
+               (pipe_ctx->prev_odm_pipe != NULL);
+
+       int x_plane = pipe_ctx->plane_state->dst_rect.x;
+       int y_plane = pipe_ctx->plane_state->dst_rect.y;
+       int x_pos = pos_cpy.x;
+       int y_pos = pos_cpy.y;
+
+       if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) {
+               if ((pipe_ctx->plane_state->src_rect.width != pipe_ctx->plane_res.scl_data.viewport.width) ||
+                       (pipe_ctx->plane_state->src_rect.height != pipe_ctx->plane_res.scl_data.viewport.height)) {
+                       pipe_split_on = true;
+               }
+       }
+
+       /**
+        * DC cursor is stream space, HW cursor is plane space and drawn
+        * as part of the framebuffer.
+        *
+        * Cursor position can't be negative, but hotspot can be used to
+        * shift cursor out of the plane bounds. Hotspot must be smaller
+        * than the cursor size.
+        */
+
+       /**
+        * Translate cursor from stream space to plane space.
+        *
+        * If the cursor is scaled then we need to scale the position
+        * to be in the approximately correct place. We can't do anything
+        * about the actual size being incorrect, that's a limitation of
+        * the hardware.
+        */
+       if (param.rotation == ROTATION_ANGLE_90 || param.rotation == ROTATION_ANGLE_270) {
+               x_pos = (x_pos - x_plane) * pipe_ctx->plane_state->src_rect.height /
+                               pipe_ctx->plane_state->dst_rect.width;
+               y_pos = (y_pos - y_plane) * pipe_ctx->plane_state->src_rect.width /
+                               pipe_ctx->plane_state->dst_rect.height;
+       } else {
+               x_pos = (x_pos - x_plane) * pipe_ctx->plane_state->src_rect.width /
+                               pipe_ctx->plane_state->dst_rect.width;
+               y_pos = (y_pos - y_plane) * pipe_ctx->plane_state->src_rect.height /
+                               pipe_ctx->plane_state->dst_rect.height;
+       }
+
+       /**
+        * If the cursor's source viewport is clipped then we need to
+        * translate the cursor to appear in the correct position on
+        * the screen.
+        *
+        * This translation isn't affected by scaling so it needs to be
+        * done *after* we adjust the position for the scale factor.
+        *
+        * This is only done by opt-in for now since there are still
+        * some usecases like tiled display that might enable the
+        * cursor on both streams while expecting dc to clip it.
+        */
+       if (pos_cpy.translate_by_source) {
+               x_pos += pipe_ctx->plane_state->src_rect.x;
+               y_pos += pipe_ctx->plane_state->src_rect.y;
+       }
+
+       /**
+        * If the position is negative then we need to add to the hotspot
+        * to shift the cursor outside the plane.
+        */
+
+       if (x_pos < 0) {
+               pos_cpy.x_hotspot -= x_pos;
+               x_pos = 0;
+       }
+
+       if (y_pos < 0) {
+               pos_cpy.y_hotspot -= y_pos;
+               y_pos = 0;
+       }
+
+       pos_cpy.x = (uint32_t)x_pos;
+       pos_cpy.y = (uint32_t)y_pos;
+
+       if (pipe_ctx->plane_state->address.type
+                       == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+               pos_cpy.enable = false;
+
+       if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
+               pos_cpy.enable = false;
+
+
+       if (param.rotation == ROTATION_ANGLE_0) {
+               int viewport_width =
+                       pipe_ctx->plane_res.scl_data.viewport.width;
+               int viewport_x =
+                       pipe_ctx->plane_res.scl_data.viewport.x;
+
+               if (param.mirror) {
+                       if (pipe_split_on || odm_combine_on) {
+                               if (pos_cpy.x >= viewport_width + viewport_x) {
+                                       pos_cpy.x = 2 * viewport_width
+                                                       - pos_cpy.x + 2 * viewport_x;
+                               } else {
+                                       uint32_t temp_x = pos_cpy.x;
+
+                                       pos_cpy.x = 2 * viewport_x - pos_cpy.x;
+                                       if (temp_x >= viewport_x +
+                                               (int)hubp->curs_attr.width || pos_cpy.x
+                                               <= (int)hubp->curs_attr.width +
+                                               pipe_ctx->plane_state->src_rect.x) {
+                                               pos_cpy.x = temp_x + viewport_width;
+                                       }
+                               }
+                       } else {
+                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
+                       }
+               }
+       }
+       // Swap axis and mirror horizontally
+       else if (param.rotation == ROTATION_ANGLE_90) {
+               uint32_t temp_x = pos_cpy.x;
+
+               pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
+                               (pos_cpy.y - pipe_ctx->plane_res.scl_data.viewport.x) + pipe_ctx->plane_res.scl_data.viewport.x;
+               pos_cpy.y = temp_x;
+       }
+       // Swap axis and mirror vertically
+       else if (param.rotation == ROTATION_ANGLE_270) {
+               uint32_t temp_y = pos_cpy.y;
+               int viewport_height =
+                       pipe_ctx->plane_res.scl_data.viewport.height;
+               int viewport_y =
+                       pipe_ctx->plane_res.scl_data.viewport.y;
+
+               /**
+                * Display groups that are 1xnY, have pos_cpy.x > 2 * viewport.height
+                * For pipe split cases:
+                * - apply offset of viewport.y to normalize pos_cpy.x
+                * - calculate the pos_cpy.y as before
+                * - shift pos_cpy.y back by same offset to get final value
+                * - since we iterate through both pipes, use the lower
+                *   viewport.y for offset
+                * For non pipe split cases, use the same calculation for
+                *  pos_cpy.y as the 180 degree rotation case below,
+                *  but use pos_cpy.x as our input because we are rotating
+                *  270 degrees
+                */
+               if (pipe_split_on || odm_combine_on) {
+                       int pos_cpy_x_offset;
+                       int other_pipe_viewport_y;
+
+                       if (pipe_split_on) {
+                               if (pipe_ctx->bottom_pipe) {
+                                       other_pipe_viewport_y =
+                                               pipe_ctx->bottom_pipe->plane_res.scl_data.viewport.y;
+                               } else {
+                                       other_pipe_viewport_y =
+                                               pipe_ctx->top_pipe->plane_res.scl_data.viewport.y;
+                               }
+                       } else {
+                               if (pipe_ctx->next_odm_pipe) {
+                                       other_pipe_viewport_y =
+                                               pipe_ctx->next_odm_pipe->plane_res.scl_data.viewport.y;
+                               } else {
+                                       other_pipe_viewport_y =
+                                               pipe_ctx->prev_odm_pipe->plane_res.scl_data.viewport.y;
+                               }
+                       }
+                       pos_cpy_x_offset = (viewport_y > other_pipe_viewport_y) ?
+                               other_pipe_viewport_y : viewport_y;
+                       pos_cpy.x -= pos_cpy_x_offset;
+                       if (pos_cpy.x > viewport_height) {
+                               pos_cpy.x = pos_cpy.x - viewport_height;
+                               pos_cpy.y = viewport_height - pos_cpy.x;
+                       } else {
+                               pos_cpy.y = 2 * viewport_height - pos_cpy.x;
+                       }
+                       pos_cpy.y += pos_cpy_x_offset;
+               } else {
+                       pos_cpy.y = (2 * viewport_y) + viewport_height - pos_cpy.x;
+               }
+               pos_cpy.x = temp_y;
+       }
+       // Mirror horizontally and vertically
+       else if (param.rotation == ROTATION_ANGLE_180) {
+               int viewport_width =
+                       pipe_ctx->plane_res.scl_data.viewport.width;
+               int viewport_x =
+                       pipe_ctx->plane_res.scl_data.viewport.x;
+
+               if (!param.mirror) {
+                       if (pipe_split_on || odm_combine_on) {
+                               if (pos_cpy.x >= viewport_width + viewport_x) {
+                                       pos_cpy.x = 2 * viewport_width
+                                                       - pos_cpy.x + 2 * viewport_x;
+                               } else {
+                                       uint32_t temp_x = pos_cpy.x;
+
+                                       pos_cpy.x = 2 * viewport_x - pos_cpy.x;
+                                       if (temp_x >= viewport_x +
+                                               (int)hubp->curs_attr.width || pos_cpy.x
+                                               <= (int)hubp->curs_attr.width +
+                                               pipe_ctx->plane_state->src_rect.x) {
+                                               pos_cpy.x = 2 * viewport_width - temp_x;
+                                       }
+                               }
+                       } else {
+                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
+                       }
+               }
+
+               /**
+                * Display groups that are 1xnY, have pos_cpy.y > viewport.height
+                * Calculation:
+                *   delta_from_bottom = viewport.y + viewport.height - pos_cpy.y
+                *   pos_cpy.y_new = viewport.y + delta_from_bottom
+                * Simplify it as:
+                *   pos_cpy.y = viewport.y * 2 + viewport.height - pos_cpy.y
+                */
+               pos_cpy.y = (2 * pipe_ctx->plane_res.scl_data.viewport.y) +
+                       pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
+       }
+
+       hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
+}
+
+void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+       pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+                       pipe_ctx->plane_res.hubp, attributes);
+       pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+               pipe_ctx->plane_res.dpp, attributes);
+}
+
+void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
+{
+       uint32_t sdr_white_level = pipe_ctx->stream->cursor_attributes.sdr_white_level;
+       struct fixed31_32 multiplier;
+       struct dpp_cursor_attributes opt_attr = { 0 };
+       uint32_t hw_scale = 0x3c00; // 1.0 default multiplier
+       struct custom_float_format fmt;
+
+       if (!pipe_ctx->plane_res.dpp->funcs->set_optional_cursor_attributes)
+               return;
+
+       fmt.exponenta_bits = 5;
+       fmt.mantissa_bits = 10;
+       fmt.sign = true;
+
+       if (sdr_white_level > 80) {
+               multiplier = dc_fixpt_from_fraction(sdr_white_level, 80);
+               convert_to_custom_float_format(multiplier, &fmt, &hw_scale);
+       }
+
+       opt_attr.scale = hw_scale;
+       opt_attr.bias = 0;
+
+       pipe_ctx->plane_res.dpp->funcs->set_optional_cursor_attributes(
+                       pipe_ctx->plane_res.dpp, &opt_attr);
+}
+
+/*
+ * apply_front_porch_workaround  TODO FPGA still need?
+ *
+ * This is a workaround for a bug that has existed since R5xx and has not been
+ * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
+ */
+static void apply_front_porch_workaround(
+       struct dc_crtc_timing *timing)
+{
+       if (timing->flags.INTERLACE == 1) {
+               if (timing->v_front_porch < 2)
+                       timing->v_front_porch = 2;
+       } else {
+               if (timing->v_front_porch < 1)
+                       timing->v_front_porch = 1;
+       }
+}
+
+int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx)
+{
+       const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
+       struct dc_crtc_timing patched_crtc_timing;
+       int vesa_sync_start;
+       int asic_blank_end;
+       int interlace_factor;
+
+       patched_crtc_timing = *dc_crtc_timing;
+       apply_front_porch_workaround(&patched_crtc_timing);
+
+       interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1;
+
+       vesa_sync_start = patched_crtc_timing.v_addressable +
+                       patched_crtc_timing.v_border_bottom +
+                       patched_crtc_timing.v_front_porch;
+
+       asic_blank_end = (patched_crtc_timing.v_total -
+                       vesa_sync_start -
+                       patched_crtc_timing.v_border_top)
+                       * interlace_factor;
+
+       return asic_blank_end -
+                       pipe_ctx->pipe_dlg_param.vstartup_start + 1;
+}
+
+void dcn10_calc_vupdate_position(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               uint32_t *start_line,
+               uint32_t *end_line)
+{
+       const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+       int vupdate_pos = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+
+       if (vupdate_pos >= 0)
+               *start_line = vupdate_pos - ((vupdate_pos / timing->v_total) * timing->v_total);
+       else
+               *start_line = vupdate_pos + ((-vupdate_pos / timing->v_total) + 1) * timing->v_total - 1;
+       *end_line = (*start_line + 2) % timing->v_total;
+}
+
+static void dcn10_cal_vline_position(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               uint32_t *start_line,
+               uint32_t *end_line)
+{
+       const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+       int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
+
+       if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
+               if (vline_pos > 0)
+                       vline_pos--;
+               else if (vline_pos < 0)
+                       vline_pos++;
+
+               vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+               if (vline_pos >= 0)
+                       *start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total);
+               else
+                       *start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1;
+               *end_line = (*start_line + 2) % timing->v_total;
+       } else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) {
+               // vsync is line 0 so start_line is just the requested line offset
+               *start_line = vline_pos;
+               *end_line = (*start_line + 2) % timing->v_total;
+       } else
+               ASSERT(0);
+}
+
+void dcn10_setup_periodic_interrupt(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx)
+{
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       uint32_t start_line = 0;
+       uint32_t end_line = 0;
+
+       dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line);
+
+       tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
+}
+
+void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       int start_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+
+       if (start_line < 0) {
+               ASSERT(0);
+               start_line = 0;
+       }
+
+       if (tg->funcs->setup_vertical_interrupt2)
+               tg->funcs->setup_vertical_interrupt2(tg, start_line);
+}
+
+void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings)
+{
+       struct encoder_unblank_param params = {0};
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dce_hwseq *hws = link->dc->hwseq;
+
+       /* only 3 items below are used by unblank */
+       params.timing = pipe_ctx->stream->timing;
+
+       params.link_settings.link_rate = link_settings->link_rate;
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               if (params.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+                       params.timing.pix_clk_100hz /= 2;
+               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
+       }
+
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+               hws->funcs.edp_backlight_control(link, true);
+       }
+}
+
+void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
+                               const uint8_t *custom_sdp_message,
+                               unsigned int sdp_message_size)
+{
+       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               pipe_ctx->stream_res.stream_enc->funcs->send_immediate_sdp_message(
+                               pipe_ctx->stream_res.stream_enc,
+                               custom_sdp_message,
+                               sdp_message_size);
+       }
+}
+enum dc_status dcn10_set_clock(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       uint32_t clk_khz,
+                       uint32_t stepping)
+{
+       struct dc_state *context = dc->current_state;
+       struct dc_clock_config clock_cfg = {0};
+       struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk;
+
+       if (!dc->clk_mgr || !dc->clk_mgr->funcs->get_clock)
+               return DC_FAIL_UNSUPPORTED_1;
+
+       dc->clk_mgr->funcs->get_clock(dc->clk_mgr,
+               context, clock_type, &clock_cfg);
+
+       if (clk_khz > clock_cfg.max_clock_khz)
+               return DC_FAIL_CLK_EXCEED_MAX;
+
+       if (clk_khz < clock_cfg.min_clock_khz)
+               return DC_FAIL_CLK_BELOW_MIN;
+
+       if (clk_khz < clock_cfg.bw_requirequired_clock_khz)
+               return DC_FAIL_CLK_BELOW_CFG_REQUIRED;
+
+       /*update internal request clock for update clock use*/
+       if (clock_type == DC_CLOCK_TYPE_DISPCLK)
+               current_clocks->dispclk_khz = clk_khz;
+       else if (clock_type == DC_CLOCK_TYPE_DPPCLK)
+               current_clocks->dppclk_khz = clk_khz;
+       else
+               return DC_ERROR_UNEXPECTED;
+
+       if (dc->clk_mgr->funcs->update_clocks)
+                               dc->clk_mgr->funcs->update_clocks(dc->clk_mgr,
+                               context, true);
+       return DC_OK;
+
+}
+
+void dcn10_get_clock(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg)
+{
+       struct dc_state *context = dc->current_state;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+                               dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg);
+
+}
+
+void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits)
+{
+       struct resource_pool *pool = dc->res_pool;
+       int i;
+
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct hubp *hubp = pool->hubps[i];
+               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
+
+               hubp->funcs->hubp_read_state(hubp);
+
+               if (!s->blank_en)
+                       dcc_en_bits[i] = s->dcc_en ? 1 : 0;
+       }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
new file mode 100644 (file)
index 0000000..ef6d56d
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+* Copyright 2016-2020 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_HWSS_DCN10_H__
+#define __DC_HWSS_DCN10_H__
+
+#include "core_types.h"
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dcn10_hw_sequencer_construct(struct dc *dc);
+
+int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx);
+void dcn10_calc_vupdate_position(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               uint32_t *start_line,
+               uint32_t *end_line);
+void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
+enum dc_status dcn10_enable_stream_timing(
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context,
+               struct dc *dc);
+void dcn10_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn10_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn10_pipe_control_lock(
+       struct dc *dc,
+       struct pipe_ctx *pipe,
+       bool lock);
+void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
+void dcn10_blank_pixel_data(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool blank);
+void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings);
+void dcn10_program_output_csc(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum dc_color_space colorspace,
+               uint16_t *matrix,
+               int opp_id);
+bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream);
+bool dcn10_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                       const struct dc_plane_state *plane_state);
+void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn10_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn10_lock_all_pipes(
+               struct dc *dc,
+               struct dc_state *context,
+               bool lock);
+void dcn10_post_unlock_program_front_end(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn10_hubp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int hubp_inst,
+               bool power_on);
+void dcn10_dpp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dpp_inst,
+               bool power_on);
+void dcn10_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable);
+void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn10_disable_vga(
+       struct dce_hwseq *hws);
+void dcn10_program_pipe(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context);
+void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx);
+void dcn10_init_hw(struct dc *dc);
+void dcn10_init_pipes(struct dc *dc, struct dc_state *context);
+void dcn10_power_down_on_boot(struct dc *dc);
+enum dc_status dce110_apply_ctx_to_hw(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data);
+void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx);
+void dce110_power_down(struct dc *dc);
+void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context);
+void dcn10_enable_timing_synchronization(
+               struct dc *dc,
+               int group_index,
+               int group_size,
+               struct pipe_ctx *grouped_pipes[]);
+void dcn10_enable_vblanks_synchronization(
+               struct dc *dc,
+               int group_index,
+               int group_size,
+               struct pipe_ctx *grouped_pipes[]);
+void dcn10_enable_per_frame_crtc_position_reset(
+               struct dc *dc,
+               int group_size,
+               struct pipe_ctx *grouped_pipes[]);
+void dce110_update_info_frame(struct pipe_ctx *pipe_ctx);
+void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
+               const uint8_t *custom_sdp_message,
+               unsigned int sdp_message_size);
+void dce110_blank_stream(struct pipe_ctx *pipe_ctx);
+void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx);
+void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx);
+bool dcn10_dummy_display_power_gating(
+               struct dc *dc,
+               uint8_t controller_id,
+               struct dc_bios *dcb,
+               enum pipe_gating_control power_gating);
+void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
+               int num_pipes, struct dc_crtc_timing_adjust adjust);
+void dcn10_get_position(struct pipe_ctx **pipe_ctx,
+               int num_pipes,
+               struct crtc_position *position);
+void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
+               int num_pipes, const struct dc_static_screen_params *params);
+void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc);
+void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
+void dcn10_log_hw_state(struct dc *dc,
+               struct dc_log_buffer_ctx *log_ctx);
+void dcn10_get_hw_state(struct dc *dc,
+               char *pBuf,
+               unsigned int bufSize,
+               unsigned int mask);
+void dcn10_clear_status_bits(struct dc *dc, unsigned int mask);
+void dcn10_wait_for_mpcc_disconnect(
+               struct dc *dc,
+               struct resource_pool *res_pool,
+               struct pipe_ctx *pipe_ctx);
+void dce110_edp_backlight_control(
+               struct dc_link *link,
+               bool enable);
+void dce110_edp_wait_for_T12(
+               struct dc_link *link);
+void dce110_edp_power_control(
+               struct dc_link *link,
+               bool power_up);
+void dce110_edp_wait_for_hpd_ready(
+               struct dc_link *link,
+               bool power_up);
+void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx);
+void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
+void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx);
+void dcn10_setup_periodic_interrupt(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx);
+enum dc_status dcn10_set_clock(struct dc *dc,
+               enum dc_clock_type clock_type,
+               uint32_t clk_khz,
+               uint32_t stepping);
+void dcn10_get_clock(struct dc *dc,
+               enum dc_clock_type clock_type,
+               struct dc_clock_config *clock_cfg);
+bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn10_bios_golden_init(struct dc *dc);
+void dcn10_plane_atomic_power_down(struct dc *dc,
+               struct dpp *dpp,
+               struct hubp *hubp);
+bool dcn10_disconnect_pipes(
+               struct dc *dc,
+               struct dc_state *context);
+
+void dcn10_wait_for_pending_cleared(struct dc *dc,
+               struct dc_state *context);
+void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx);
+void dcn10_verify_allow_pstate_change_high(struct dc *dc);
+
+void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits);
+
+void dcn10_update_visual_confirm_color(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               int mpcc_id);
+
+#endif /* __DC_HWSS_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
new file mode 100644 (file)
index 0000000..d8c02f8
--- /dev/null
@@ -0,0 +1,2941 @@
+/*
+ * 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 <linux/delay.h>
+
+#include "dm_services.h"
+#include "basics/dc_common.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dcn20/dcn20_resource.h"
+#include "dcn20_hwseq.h"
+#include "dce/dce_hwseq.h"
+#include "dcn20/dcn20_dsc.h"
+#include "dcn20/dcn20_optc.h"
+#include "abm.h"
+#include "clk_mgr.h"
+#include "dmcu.h"
+#include "hubp.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "mcif_wb.h"
+#include "dchubbub.h"
+#include "reg_helper.h"
+#include "dcn10/dcn10_cm_common.h"
+#include "vm_helper.h"
+#include "dccg.h"
+#include "dc_dmub_srv.h"
+#include "dce/dmub_hw_lock_mgr.h"
+#include "hw_sequencer.h"
+#include "dpcd_defs.h"
+#include "inc/link_enc_cfg.h"
+#include "link_hwss.h"
+#include "link.h"
+
+#define DC_LOGGER \
+       dc_logger
+#define DC_LOGGER_INIT(logger) \
+       struct dal_logger *dc_logger = logger
+
+#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
+
+static int find_free_gsl_group(const struct dc *dc)
+{
+       if (dc->res_pool->gsl_groups.gsl_0 == 0)
+               return 1;
+       if (dc->res_pool->gsl_groups.gsl_1 == 0)
+               return 2;
+       if (dc->res_pool->gsl_groups.gsl_2 == 0)
+               return 3;
+
+       return 0;
+}
+
+/* NOTE: This is not a generic setup_gsl function (hence the suffix as_lock)
+ * This is only used to lock pipes in pipe splitting case with immediate flip
+ * Ordinary MPC/OTG locks suppress VUPDATE which doesn't help with immediate,
+ * so we get tearing with freesync since we cannot flip multiple pipes
+ * atomically.
+ * We use GSL for this:
+ * - immediate flip: find first available GSL group if not already assigned
+ *                   program gsl with that group, set current OTG as master
+ *                   and always us 0x4 = AND of flip_ready from all pipes
+ * - vsync flip: disable GSL if used
+ *
+ * Groups in stream_res are stored as +1 from HW registers, i.e.
+ * gsl_0 <=> pipe_ctx->stream_res.gsl_group == 1
+ * Using a magic value like -1 would require tracking all inits/resets
+ */
+ void dcn20_setup_gsl_group_as_lock(
+               const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool enable)
+{
+       struct gsl_params gsl;
+       int group_idx;
+
+       memset(&gsl, 0, sizeof(struct gsl_params));
+
+       if (enable) {
+               /* return if group already assigned since GSL was set up
+                * for vsync flip, we would unassign so it can't be "left over"
+                */
+               if (pipe_ctx->stream_res.gsl_group > 0)
+                       return;
+
+               group_idx = find_free_gsl_group(dc);
+               ASSERT(group_idx != 0);
+               pipe_ctx->stream_res.gsl_group = group_idx;
+
+               /* set gsl group reg field and mark resource used */
+               switch (group_idx) {
+               case 1:
+                       gsl.gsl0_en = 1;
+                       dc->res_pool->gsl_groups.gsl_0 = 1;
+                       break;
+               case 2:
+                       gsl.gsl1_en = 1;
+                       dc->res_pool->gsl_groups.gsl_1 = 1;
+                       break;
+               case 3:
+                       gsl.gsl2_en = 1;
+                       dc->res_pool->gsl_groups.gsl_2 = 1;
+                       break;
+               default:
+                       BREAK_TO_DEBUGGER();
+                       return; // invalid case
+               }
+               gsl.gsl_master_en = 1;
+       } else {
+               group_idx = pipe_ctx->stream_res.gsl_group;
+               if (group_idx == 0)
+                       return; // if not in use, just return
+
+               pipe_ctx->stream_res.gsl_group = 0;
+
+               /* unset gsl group reg field and mark resource free */
+               switch (group_idx) {
+               case 1:
+                       gsl.gsl0_en = 0;
+                       dc->res_pool->gsl_groups.gsl_0 = 0;
+                       break;
+               case 2:
+                       gsl.gsl1_en = 0;
+                       dc->res_pool->gsl_groups.gsl_1 = 0;
+                       break;
+               case 3:
+                       gsl.gsl2_en = 0;
+                       dc->res_pool->gsl_groups.gsl_2 = 0;
+                       break;
+               default:
+                       BREAK_TO_DEBUGGER();
+                       return;
+               }
+               gsl.gsl_master_en = 0;
+       }
+
+       /* at this point we want to program whether it's to enable or disable */
+       if (pipe_ctx->stream_res.tg->funcs->set_gsl != NULL &&
+               pipe_ctx->stream_res.tg->funcs->set_gsl_source_select != NULL) {
+               pipe_ctx->stream_res.tg->funcs->set_gsl(
+                       pipe_ctx->stream_res.tg,
+                       &gsl);
+
+               pipe_ctx->stream_res.tg->funcs->set_gsl_source_select(
+                       pipe_ctx->stream_res.tg, group_idx,     enable ? 4 : 0);
+       } else
+               BREAK_TO_DEBUGGER();
+}
+
+void dcn20_set_flip_control_gsl(
+               struct pipe_ctx *pipe_ctx,
+               bool flip_immediate)
+{
+       if (pipe_ctx && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_control_surface_gsl)
+               pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_control_surface_gsl(
+                               pipe_ctx->plane_res.hubp, flip_immediate);
+
+}
+
+void dcn20_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable)
+{
+       bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
+
+       if (enable)
+               force_on = false;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       /* DCHUBP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
+       if (REG(DOMAIN8_PG_CONFIG))
+               REG_UPDATE(DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
+       if (REG(DOMAIN10_PG_CONFIG))
+               REG_UPDATE(DOMAIN10_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
+
+       /* DPP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
+       if (REG(DOMAIN9_PG_CONFIG))
+               REG_UPDATE(DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
+       if (REG(DOMAIN11_PG_CONFIG))
+               REG_UPDATE(DOMAIN11_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
+
+       /* DCS0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, force_on);
+       if (REG(DOMAIN19_PG_CONFIG))
+               REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, force_on);
+       if (REG(DOMAIN20_PG_CONFIG))
+               REG_UPDATE(DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, force_on);
+       if (REG(DOMAIN21_PG_CONFIG))
+               REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on);
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+
+}
+
+void dcn20_dccg_init(struct dce_hwseq *hws)
+{
+       /*
+        * set MICROSECOND_TIME_BASE_DIV
+        * 100Mhz refclk -> 0x120264
+        * 27Mhz refclk -> 0x12021b
+        * 48Mhz refclk -> 0x120230
+        *
+        */
+       REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264);
+
+       /*
+        * set MILLISECOND_TIME_BASE_DIV
+        * 100Mhz refclk -> 0x1186a0
+        * 27Mhz refclk -> 0x106978
+        * 48Mhz refclk -> 0x10bb80
+        *
+        */
+       REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0);
+
+       /* This value is dependent on the hardware pipeline delay so set once per SOC */
+       REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c);
+}
+
+void dcn20_disable_vga(
+       struct dce_hwseq *hws)
+{
+       REG_WRITE(D1VGA_CONTROL, 0);
+       REG_WRITE(D2VGA_CONTROL, 0);
+       REG_WRITE(D3VGA_CONTROL, 0);
+       REG_WRITE(D4VGA_CONTROL, 0);
+       REG_WRITE(D5VGA_CONTROL, 0);
+       REG_WRITE(D6VGA_CONTROL, 0);
+}
+
+void dcn20_program_triple_buffer(
+       const struct dc *dc,
+       struct pipe_ctx *pipe_ctx,
+       bool enable_triple_buffer)
+{
+       if (pipe_ctx->plane_res.hubp && pipe_ctx->plane_res.hubp->funcs) {
+               pipe_ctx->plane_res.hubp->funcs->hubp_enable_tripleBuffer(
+                       pipe_ctx->plane_res.hubp,
+                       enable_triple_buffer);
+       }
+}
+
+/* Blank pixel data during initialization */
+void dcn20_init_blank(
+               struct dc *dc,
+               struct timing_generator *tg)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       enum dc_color_space color_space;
+       struct tg_color black_color = {0};
+       struct output_pixel_processor *opp = NULL;
+       struct output_pixel_processor *bottom_opp = NULL;
+       uint32_t num_opps, opp_id_src0, opp_id_src1;
+       uint32_t otg_active_width, otg_active_height;
+
+       /* program opp dpg blank color */
+       color_space = COLOR_SPACE_SRGB;
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       /* get the OTG active size */
+       tg->funcs->get_otg_active_size(tg,
+                       &otg_active_width,
+                       &otg_active_height);
+
+       /* get the OPTC source */
+       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+
+       if (opp_id_src0 >= dc->res_pool->res_cap->num_opp) {
+               ASSERT(false);
+               return;
+       }
+       opp = dc->res_pool->opps[opp_id_src0];
+
+       /* don't override the blank pattern if already enabled with the correct one. */
+       if (opp->funcs->dpg_is_blanked && opp->funcs->dpg_is_blanked(opp))
+               return;
+
+       if (num_opps == 2) {
+               otg_active_width = otg_active_width / 2;
+
+               if (opp_id_src1 >= dc->res_pool->res_cap->num_opp) {
+                       ASSERT(false);
+                       return;
+               }
+               bottom_opp = dc->res_pool->opps[opp_id_src1];
+       }
+
+       opp->funcs->opp_set_disp_pattern_generator(
+                       opp,
+                       CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+                       CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+                       COLOR_DEPTH_UNDEFINED,
+                       &black_color,
+                       otg_active_width,
+                       otg_active_height,
+                       0);
+
+       if (num_opps == 2) {
+               bottom_opp->funcs->opp_set_disp_pattern_generator(
+                               bottom_opp,
+                               CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+                               CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+                               COLOR_DEPTH_UNDEFINED,
+                               &black_color,
+                               otg_active_width,
+                               otg_active_height,
+                               0);
+       }
+
+       hws->funcs.wait_for_blank_complete(opp);
+}
+
+void dcn20_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_dsc_power_gate)
+               return;
+
+       if (REG(DOMAIN16_PG_CONFIG) == 0)
+               return;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_UPDATE(DOMAIN16_PG_CONFIG,
+                               DOMAIN16_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN16_PG_STATUS,
+                               DOMAIN16_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DSC1 */
+               REG_UPDATE(DOMAIN17_PG_CONFIG,
+                               DOMAIN17_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN17_PG_STATUS,
+                               DOMAIN17_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DSC2 */
+               REG_UPDATE(DOMAIN18_PG_CONFIG,
+                               DOMAIN18_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN18_PG_STATUS,
+                               DOMAIN18_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DSC3 */
+               REG_UPDATE(DOMAIN19_PG_CONFIG,
+                               DOMAIN19_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN19_PG_STATUS,
+                               DOMAIN19_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 4: /* DSC4 */
+               REG_UPDATE(DOMAIN20_PG_CONFIG,
+                               DOMAIN20_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN20_PG_STATUS,
+                               DOMAIN20_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 5: /* DSC5 */
+               REG_UPDATE(DOMAIN21_PG_CONFIG,
+                               DOMAIN21_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN21_PG_STATUS,
+                               DOMAIN21_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+void dcn20_dpp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dpp_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+
+       if (hws->ctx->dc->debug.disable_dpp_power_gate)
+               return;
+       if (REG(DOMAIN1_PG_CONFIG) == 0)
+               return;
+
+       switch (dpp_inst) {
+       case 0: /* DPP0 */
+               REG_UPDATE(DOMAIN1_PG_CONFIG,
+                               DOMAIN1_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN1_PG_STATUS,
+                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DPP1 */
+               REG_UPDATE(DOMAIN3_PG_CONFIG,
+                               DOMAIN3_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN3_PG_STATUS,
+                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DPP2 */
+               REG_UPDATE(DOMAIN5_PG_CONFIG,
+                               DOMAIN5_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN5_PG_STATUS,
+                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DPP3 */
+               REG_UPDATE(DOMAIN7_PG_CONFIG,
+                               DOMAIN7_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN7_PG_STATUS,
+                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 4: /* DPP4 */
+               REG_UPDATE(DOMAIN9_PG_CONFIG,
+                               DOMAIN9_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN9_PG_STATUS,
+                               DOMAIN9_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 5: /* DPP5 */
+               /*
+                * Do not power gate DPP5, should be left at HW default, power on permanently.
+                * PG on Pipe5 is De-featured, attempting to put it to PG state may result in hard
+                * reset.
+                * REG_UPDATE(DOMAIN11_PG_CONFIG,
+                *              DOMAIN11_POWER_GATE, power_gate);
+                *
+                * REG_WAIT(DOMAIN11_PG_STATUS,
+                *              DOMAIN11_PGFSM_PWR_STATUS, pwr_status,
+                *              1, 1000);
+                */
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+
+void dcn20_hubp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int hubp_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
+               return;
+       if (REG(DOMAIN0_PG_CONFIG) == 0)
+               return;
+
+       switch (hubp_inst) {
+       case 0: /* DCHUBP0 */
+               REG_UPDATE(DOMAIN0_PG_CONFIG,
+                               DOMAIN0_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN0_PG_STATUS,
+                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DCHUBP1 */
+               REG_UPDATE(DOMAIN2_PG_CONFIG,
+                               DOMAIN2_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN2_PG_STATUS,
+                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DCHUBP2 */
+               REG_UPDATE(DOMAIN4_PG_CONFIG,
+                               DOMAIN4_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN4_PG_STATUS,
+                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DCHUBP3 */
+               REG_UPDATE(DOMAIN6_PG_CONFIG,
+                               DOMAIN6_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN6_PG_STATUS,
+                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 4: /* DCHUBP4 */
+               REG_UPDATE(DOMAIN8_PG_CONFIG,
+                               DOMAIN8_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN8_PG_STATUS,
+                               DOMAIN8_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 5: /* DCHUBP5 */
+               /*
+                * Do not power gate DCHUB5, should be left at HW default, power on permanently.
+                * PG on Pipe5 is De-featured, attempting to put it to PG state may result in hard
+                * reset.
+                * REG_UPDATE(DOMAIN10_PG_CONFIG,
+                *              DOMAIN10_POWER_GATE, power_gate);
+                *
+                * REG_WAIT(DOMAIN10_PG_STATUS,
+                *              DOMAIN10_PGFSM_PWR_STATUS, pwr_status,
+                *              1, 1000);
+                */
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+
+/* disable HW used by plane.
+ * note:  cannot disable until disconnect is complete
+ */
+void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+
+       dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
+
+       /* In flip immediate with pipe splitting case GSL is used for
+        * synchronization so we must disable it when the plane is disabled.
+        */
+       if (pipe_ctx->stream_res.gsl_group != 0)
+               dcn20_setup_gsl_group_as_lock(dc, pipe_ctx, false);
+
+       if (hubp->funcs->hubp_update_mall_sel)
+               hubp->funcs->hubp_update_mall_sel(hubp, 0, false);
+
+       dc->hwss.set_flip_control_gsl(pipe_ctx, false);
+
+       hubp->funcs->hubp_clk_cntl(hubp, false);
+
+       dpp->funcs->dpp_dppclk_control(dpp, false, false);
+
+       hubp->power_gated = true;
+
+       hws->funcs.plane_atomic_power_down(dc,
+                       pipe_ctx->plane_res.dpp,
+                       pipe_ctx->plane_res.hubp);
+
+       pipe_ctx->stream = NULL;
+       memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
+       memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
+       pipe_ctx->top_pipe = NULL;
+       pipe_ctx->bottom_pipe = NULL;
+       pipe_ctx->prev_odm_pipe = NULL;
+       pipe_ctx->next_odm_pipe = NULL;
+       pipe_ctx->plane_state = NULL;
+}
+
+
+void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       bool is_phantom = pipe_ctx->plane_state && pipe_ctx->plane_state->is_phantom;
+       struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL;
+
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
+               return;
+
+       dcn20_plane_atomic_disable(dc, pipe_ctx);
+
+       /* Turn back off the phantom OTG after the phantom plane is fully disabled
+        */
+       if (is_phantom)
+               if (tg && tg->funcs->disable_phantom_crtc)
+                       tg->funcs->disable_phantom_crtc(tg);
+
+       DC_LOG_DC("Power down front end %d\n",
+                                       pipe_ctx->pipe_idx);
+}
+
+void dcn20_disable_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank)
+{
+       dcn20_blank_pixel_data(dc, pipe_ctx, blank);
+}
+
+static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
+               int opp_cnt)
+{
+       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
+       int flow_ctrl_cnt;
+
+       if (opp_cnt >= 2)
+               hblank_halved = true;
+
+       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
+                       stream->timing.h_border_left -
+                       stream->timing.h_border_right;
+
+       if (hblank_halved)
+               flow_ctrl_cnt /= 2;
+
+       /* ODM combine 4:1 case */
+       if (opp_cnt == 4)
+               flow_ctrl_cnt /= 2;
+
+       return flow_ctrl_cnt;
+}
+
+static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
+{
+       switch (link->link_enc->transmitter) {
+       case TRANSMITTER_UNIPHY_A:
+               return PHYD32CLKA;
+       case TRANSMITTER_UNIPHY_B:
+               return PHYD32CLKB;
+       case TRANSMITTER_UNIPHY_C:
+               return PHYD32CLKC;
+       case TRANSMITTER_UNIPHY_D:
+               return PHYD32CLKD;
+       case TRANSMITTER_UNIPHY_E:
+               return PHYD32CLKE;
+       default:
+               return PHYD32CLKA;
+       }
+}
+
+static int get_odm_segment_count(struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
+       int count = 1;
+
+       while (odm_pipe != NULL) {
+               count++;
+               odm_pipe = odm_pipe->next_odm_pipe;
+       }
+
+       return count;
+}
+
+enum dc_status dcn20_enable_stream_timing(
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context,
+               struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct drr_params params = {0};
+       unsigned int event_triggers = 0;
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 1;
+       int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst };
+       bool interlace = stream->timing.flags.INTERLACE;
+       int i;
+       struct mpc_dwb_flow_control flow_control;
+       struct mpc *mpc = dc->res_pool->mpc;
+       bool rate_control_2x_pclk = (interlace || optc2_is_two_pixels_per_containter(&stream->timing));
+       unsigned int k1_div = PIXEL_RATE_DIV_NA;
+       unsigned int k2_div = PIXEL_RATE_DIV_NA;
+
+       if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
+               hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
+
+               dc->res_pool->dccg->funcs->set_pixel_rate_div(
+                       dc->res_pool->dccg,
+                       pipe_ctx->stream_res.tg->inst,
+                       k1_div, k2_div);
+       }
+       /* by upper caller loop, pipe0 is parent pipe and be called first.
+        * back end is set up by for pipe0. Other children pipe share back end
+        * with pipe 0. No program is needed.
+        */
+       if (pipe_ctx->top_pipe != NULL)
+               return DC_OK;
+
+       /* TODO check if timing_changed, disable stream if timing changed */
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               opp_inst[opp_cnt] = odm_pipe->stream_res.opp->inst;
+               opp_cnt++;
+       }
+
+       if (opp_cnt > 1)
+               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
+                               pipe_ctx->stream_res.tg,
+                               opp_inst, opp_cnt,
+                               &pipe_ctx->stream->timing);
+
+       /* HW program guide assume display already disable
+        * by unplug sequence. OTG assume stop.
+        */
+       pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, true);
+
+       if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
+                       pipe_ctx->clock_source,
+                       &pipe_ctx->stream_res.pix_clk_params,
+                       dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                       &pipe_ctx->pll_settings)) {
+               BREAK_TO_DEBUGGER();
+               return DC_ERROR_UNEXPECTED;
+       }
+
+       if (dc_is_hdmi_tmds_signal(stream->signal)) {
+               stream->link->phy_state.symclk_ref_cnts.otg = 1;
+               if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+               else
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+       }
+
+       if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal)))
+               dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx);
+
+       pipe_ctx->stream_res.tg->funcs->program_timing(
+                       pipe_ctx->stream_res.tg,
+                       &stream->timing,
+                       pipe_ctx->pipe_dlg_param.vready_offset,
+                       pipe_ctx->pipe_dlg_param.vstartup_start,
+                       pipe_ctx->pipe_dlg_param.vupdate_offset,
+                       pipe_ctx->pipe_dlg_param.vupdate_width,
+                       pipe_ctx->stream->signal,
+                       true);
+
+       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
+       flow_control.flow_ctrl_mode = 0;
+       flow_control.flow_ctrl_cnt0 = 0x80;
+       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(stream, opp_cnt);
+       if (mpc->funcs->set_out_rate_control) {
+               for (i = 0; i < opp_cnt; ++i) {
+                       mpc->funcs->set_out_rate_control(
+                                       mpc, opp_inst[i],
+                                       true,
+                                       rate_control_2x_pclk,
+                                       &flow_control);
+               }
+       }
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
+                               odm_pipe->stream_res.opp,
+                               true);
+
+       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+                       pipe_ctx->stream_res.opp,
+                       true);
+
+       hws->funcs.blank_pixel_data(dc, pipe_ctx, true);
+
+       /* VTG is  within DCHUB command block. DCFCLK is always on */
+       if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc(pipe_ctx->stream_res.tg)) {
+               BREAK_TO_DEBUGGER();
+               return DC_ERROR_UNEXPECTED;
+       }
+
+       hws->funcs.wait_for_blank_complete(pipe_ctx->stream_res.opp);
+
+       params.vertical_total_min = stream->adjust.v_total_min;
+       params.vertical_total_max = stream->adjust.v_total_max;
+       params.vertical_total_mid = stream->adjust.v_total_mid;
+       params.vertical_total_mid_frame_num = stream->adjust.v_total_mid_frame_num;
+       if (pipe_ctx->stream_res.tg->funcs->set_drr)
+               pipe_ctx->stream_res.tg->funcs->set_drr(
+                       pipe_ctx->stream_res.tg, &params);
+
+       // DRR should set trigger event to monitor surface update event
+       if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
+               event_triggers = 0x80;
+       /* Event triggers and num frames initialized for DRR, but can be
+        * later updated for PSR use. Note DRR trigger events are generated
+        * regardless of whether num frames met.
+        */
+       if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
+               pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
+                               pipe_ctx->stream_res.tg, event_triggers, 2);
+
+       /* TODO program crtc source select for non-virtual signal*/
+       /* TODO program FMT */
+       /* TODO setup link_enc */
+       /* TODO set stream attributes */
+       /* TODO program audio */
+       /* TODO enable stream if timing changed */
+       /* TODO unblank stream if DP */
+
+       if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+               if (pipe_ctx->stream_res.tg && pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)
+                       pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg);
+       }
+
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               struct dccg *dccg = dc->res_pool->dccg;
+               struct timing_generator *tg = pipe_ctx->stream_res.tg;
+               struct dtbclk_dto_params dto_params = {0};
+
+               if (dccg->funcs->set_dtbclk_p_src)
+                       dccg->funcs->set_dtbclk_p_src(dccg, DTBCLK0, tg->inst);
+
+               dto_params.otg_inst = tg->inst;
+               dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
+               dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
+               dto_params.timing = &pipe_ctx->stream->timing;
+               dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
+               dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+       }
+
+       return DC_OK;
+}
+
+void dcn20_program_output_csc(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum dc_color_space colorspace,
+               uint16_t *matrix,
+               int opp_id)
+{
+       struct mpc *mpc = dc->res_pool->mpc;
+       enum mpc_output_csc_mode ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+
+       if (mpc->funcs->power_on_mpc_mem_pwr)
+               mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, true);
+
+       if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
+               if (mpc->funcs->set_output_csc != NULL)
+                       mpc->funcs->set_output_csc(mpc,
+                                       opp_id,
+                                       matrix,
+                                       ocsc_mode);
+       } else {
+               if (mpc->funcs->set_ocsc_default != NULL)
+                       mpc->funcs->set_ocsc_default(mpc,
+                                       opp_id,
+                                       colorspace,
+                                       ocsc_mode);
+       }
+}
+
+bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream)
+{
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+       struct pwl_params *params = NULL;
+       /*
+        * program OGAM only for the top pipe
+        * if there is a pipe split then fix diagnostic is required:
+        * how to pass OGAM parameter for stream.
+        * if programming for all pipes is required then remove condition
+        * pipe_ctx->top_pipe == NULL ,but then fix the diagnostic.
+        */
+       if (mpc->funcs->power_on_mpc_mem_pwr)
+               mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, true);
+       if (pipe_ctx->top_pipe == NULL
+                       && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
+               if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
+                       params = &stream->out_transfer_func->pwl;
+               else if (pipe_ctx->stream->out_transfer_func->type ==
+                       TF_TYPE_DISTRIBUTED_POINTS &&
+                       cm_helper_translate_curve_to_hw_format(dc->ctx,
+                       stream->out_transfer_func,
+                       &mpc->blender_params, false))
+                       params = &mpc->blender_params;
+               /*
+                * there is no ROM
+                */
+               if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
+                       BREAK_TO_DEBUGGER();
+       }
+       /*
+        * if above if is not executed then 'params' equal to 0 and set in bypass
+        */
+       mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+
+       return true;
+}
+
+bool dcn20_set_blend_lut(
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       bool result = true;
+       struct pwl_params *blend_lut = NULL;
+
+       if (plane_state->blend_tf) {
+               if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
+                       blend_lut = &plane_state->blend_tf->pwl;
+               else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                       plane_state->blend_tf,
+                                       &dpp_base->regamma_params, false);
+                       blend_lut = &dpp_base->regamma_params;
+               }
+       }
+       result = dpp_base->funcs->dpp_program_blnd_lut(dpp_base, blend_lut);
+
+       return result;
+}
+
+bool dcn20_set_shaper_3dlut(
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       bool result = true;
+       struct pwl_params *shaper_lut = NULL;
+
+       if (plane_state->in_shaper_func) {
+               if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL)
+                       shaper_lut = &plane_state->in_shaper_func->pwl;
+               else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                       plane_state->in_shaper_func,
+                                       &dpp_base->shaper_params, true);
+                       shaper_lut = &dpp_base->shaper_params;
+               }
+       }
+
+       result = dpp_base->funcs->dpp_program_shaper_lut(dpp_base, shaper_lut);
+       if (plane_state->lut3d_func &&
+               plane_state->lut3d_func->state.bits.initialized == 1)
+               result = dpp_base->funcs->dpp_program_3dlut(dpp_base,
+                                                               &plane_state->lut3d_func->lut_3d);
+       else
+               result = dpp_base->funcs->dpp_program_3dlut(dpp_base, NULL);
+
+       return result;
+}
+
+bool dcn20_set_input_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       const struct dc_transfer_func *tf = NULL;
+       bool result = true;
+       bool use_degamma_ram = false;
+
+       if (dpp_base == NULL || plane_state == NULL)
+               return false;
+
+       hws->funcs.set_shaper_3dlut(pipe_ctx, plane_state);
+       hws->funcs.set_blend_lut(pipe_ctx, plane_state);
+
+       if (plane_state->in_transfer_func)
+               tf = plane_state->in_transfer_func;
+
+
+       if (tf == NULL) {
+               dpp_base->funcs->dpp_set_degamma(dpp_base,
+                               IPP_DEGAMMA_MODE_BYPASS);
+               return true;
+       }
+
+       if (tf->type == TF_TYPE_HWPWL || tf->type == TF_TYPE_DISTRIBUTED_POINTS)
+               use_degamma_ram = true;
+
+       if (use_degamma_ram == true) {
+               if (tf->type == TF_TYPE_HWPWL)
+                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
+                                       &tf->pwl);
+               else if (tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm_helper_translate_curve_to_degamma_hw_format(tf,
+                                       &dpp_base->degamma_params);
+                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
+                               &dpp_base->degamma_params);
+               }
+               return true;
+       }
+       /* handle here the optimized cases when de-gamma ROM could be used.
+        *
+        */
+       if (tf->type == TF_TYPE_PREDEFINED) {
+               switch (tf->tf) {
+               case TRANSFER_FUNCTION_SRGB:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base,
+                                       IPP_DEGAMMA_MODE_HW_sRGB);
+                       break;
+               case TRANSFER_FUNCTION_BT709:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base,
+                                       IPP_DEGAMMA_MODE_HW_xvYCC);
+                       break;
+               case TRANSFER_FUNCTION_LINEAR:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base,
+                                       IPP_DEGAMMA_MODE_BYPASS);
+                       break;
+               case TRANSFER_FUNCTION_PQ:
+                       dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_USER_PWL);
+                       cm_helper_translate_curve_to_degamma_hw_format(tf, &dpp_base->degamma_params);
+                       dpp_base->funcs->dpp_program_degamma_pwl(dpp_base, &dpp_base->degamma_params);
+                       result = true;
+                       break;
+               default:
+                       result = false;
+                       break;
+               }
+       } else if (tf->type == TF_TYPE_BYPASS)
+               dpp_base->funcs->dpp_set_degamma(dpp_base,
+                               IPP_DEGAMMA_MODE_BYPASS);
+       else {
+               /*
+                * if we are here, we did not handle correctly.
+                * fix is required for this use case
+                */
+               BREAK_TO_DEBUGGER();
+               dpp_base->funcs->dpp_set_degamma(dpp_base,
+                               IPP_DEGAMMA_MODE_BYPASS);
+       }
+
+       return result;
+}
+
+void dcn20_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 1;
+       int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst };
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               opp_inst[opp_cnt] = odm_pipe->stream_res.opp->inst;
+               opp_cnt++;
+       }
+
+       if (opp_cnt > 1)
+               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
+                               pipe_ctx->stream_res.tg,
+                               opp_inst, opp_cnt,
+                               &pipe_ctx->stream->timing);
+       else
+               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+}
+
+void dcn20_blank_pixel_data(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool blank)
+{
+       struct tg_color black_color = {0};
+       struct stream_resource *stream_res = &pipe_ctx->stream_res;
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       enum dc_color_space color_space = stream->output_color_space;
+       enum controller_dp_test_pattern test_pattern = CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR;
+       enum controller_dp_color_space test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
+       struct pipe_ctx *odm_pipe;
+       int odm_cnt = 1;
+       int h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
+       int v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
+       int odm_slice_width, last_odm_slice_width, offset = 0;
+
+       if (stream->link->test_pattern_enabled)
+               return;
+
+       /* get opp dpg blank color */
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               odm_cnt++;
+       odm_slice_width = h_active / odm_cnt;
+       last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
+
+       if (blank) {
+               dc->hwss.set_abm_immediate_disable(pipe_ctx);
+
+               if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
+                       test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
+                       test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
+               }
+       } else {
+               test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
+       }
+
+       odm_pipe = pipe_ctx;
+
+       while (odm_pipe->next_odm_pipe) {
+               dc->hwss.set_disp_pattern_generator(dc,
+                               odm_pipe,
+                               test_pattern,
+                               test_pattern_color_space,
+                               stream->timing.display_color_depth,
+                               &black_color,
+                               odm_slice_width,
+                               v_active,
+                               offset);
+               offset += odm_slice_width;
+               odm_pipe = odm_pipe->next_odm_pipe;
+       }
+
+       dc->hwss.set_disp_pattern_generator(dc,
+                       odm_pipe,
+                       test_pattern,
+                       test_pattern_color_space,
+                       stream->timing.display_color_depth,
+                       &black_color,
+                       last_odm_slice_width,
+                       v_active,
+                       offset);
+
+       if (!blank)
+               if (stream_res->abm) {
+                       dc->hwss.set_pipe(pipe_ctx);
+                       stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
+               }
+}
+
+
+static void dcn20_power_on_plane_resources(
+       struct dce_hwseq *hws,
+       struct pipe_ctx *pipe_ctx)
+{
+       DC_LOGGER_INIT(hws->ctx->logger);
+
+       if (hws->funcs.dpp_root_clock_control)
+               hws->funcs.dpp_root_clock_control(hws, pipe_ctx->plane_res.dpp->inst, true);
+
+       if (REG(DC_IP_REQUEST_CNTL)) {
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+                               IP_REQUEST_EN, 1);
+
+               if (hws->funcs.dpp_pg_control)
+                       hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true);
+
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true);
+
+               REG_SET(DC_IP_REQUEST_CNTL, 0,
+                               IP_REQUEST_EN, 0);
+               DC_LOG_DEBUG(
+                               "Un-gated front end for pipe %d\n", pipe_ctx->plane_res.hubp->inst);
+       }
+}
+
+static void dcn20_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                              struct dc_state *context)
+{
+       //if (dc->debug.sanity_checks) {
+       //      dcn10_verify_allow_pstate_change_high(dc);
+       //}
+       dcn20_power_on_plane_resources(dc->hwseq, pipe_ctx);
+
+       /* enable DCFCLK current DCHUB */
+       pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
+
+       /* initialize HUBP on power up */
+       pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp);
+
+       /* make sure OPP_PIPE_CLOCK_EN = 1 */
+       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+                       pipe_ctx->stream_res.opp,
+                       true);
+
+/* TODO: enable/disable in dm as per update type.
+       if (plane_state) {
+               DC_LOG_DC(dc->ctx->logger,
+                               "Pipe:%d 0x%x: addr hi:0x%x, "
+                               "addr low:0x%x, "
+                               "src: %d, %d, %d,"
+                               " %d; dst: %d, %d, %d, %d;\n",
+                               pipe_ctx->pipe_idx,
+                               plane_state,
+                               plane_state->address.grph.addr.high_part,
+                               plane_state->address.grph.addr.low_part,
+                               plane_state->src_rect.x,
+                               plane_state->src_rect.y,
+                               plane_state->src_rect.width,
+                               plane_state->src_rect.height,
+                               plane_state->dst_rect.x,
+                               plane_state->dst_rect.y,
+                               plane_state->dst_rect.width,
+                               plane_state->dst_rect.height);
+
+               DC_LOG_DC(dc->ctx->logger,
+                               "Pipe %d: width, height, x, y         format:%d\n"
+                               "viewport:%d, %d, %d, %d\n"
+                               "recout:  %d, %d, %d, %d\n",
+                               pipe_ctx->pipe_idx,
+                               plane_state->format,
+                               pipe_ctx->plane_res.scl_data.viewport.width,
+                               pipe_ctx->plane_res.scl_data.viewport.height,
+                               pipe_ctx->plane_res.scl_data.viewport.x,
+                               pipe_ctx->plane_res.scl_data.viewport.y,
+                               pipe_ctx->plane_res.scl_data.recout.width,
+                               pipe_ctx->plane_res.scl_data.recout.height,
+                               pipe_ctx->plane_res.scl_data.recout.x,
+                               pipe_ctx->plane_res.scl_data.recout.y);
+               print_rq_dlg_ttu(dc, pipe_ctx);
+       }
+*/
+       if (dc->vm_pa_config.valid) {
+               struct vm_system_aperture_param apt;
+
+               apt.sys_default.quad_part = 0;
+
+               apt.sys_low.quad_part = dc->vm_pa_config.system_aperture.start_addr;
+               apt.sys_high.quad_part = dc->vm_pa_config.system_aperture.end_addr;
+
+               // Program system aperture settings
+               pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
+       }
+
+       if (!pipe_ctx->top_pipe
+               && pipe_ctx->plane_state
+               && pipe_ctx->plane_state->flip_int_enabled
+               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
+                       pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
+
+//     if (dc->debug.sanity_checks) {
+//             dcn10_verify_allow_pstate_change_high(dc);
+//     }
+}
+
+void dcn20_pipe_control_lock(
+       struct dc *dc,
+       struct pipe_ctx *pipe,
+       bool lock)
+{
+       struct pipe_ctx *temp_pipe;
+       bool flip_immediate = false;
+
+       /* use TG master update lock to lock everything on the TG
+        * therefore only top pipe need to lock
+        */
+       if (!pipe || pipe->top_pipe)
+               return;
+
+       if (pipe->plane_state != NULL)
+               flip_immediate = pipe->plane_state->flip_immediate;
+
+       if  (pipe->stream_res.gsl_group > 0) {
+           temp_pipe = pipe->bottom_pipe;
+           while (!flip_immediate && temp_pipe) {
+                   if (temp_pipe->plane_state != NULL)
+                           flip_immediate = temp_pipe->plane_state->flip_immediate;
+                   temp_pipe = temp_pipe->bottom_pipe;
+           }
+       }
+
+       if (flip_immediate && lock) {
+               const int TIMEOUT_FOR_FLIP_PENDING_US = 100000;
+               unsigned int polling_interval_us = 1;
+               int i;
+
+               temp_pipe = pipe;
+               while (temp_pipe) {
+                       if (temp_pipe->plane_state && temp_pipe->plane_state->flip_immediate) {
+                               for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING_US / polling_interval_us; ++i) {
+                                       if (!temp_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(temp_pipe->plane_res.hubp))
+                                               break;
+                                       udelay(polling_interval_us);
+                               }
+
+                               /* no reason it should take this long for immediate flips */
+                               ASSERT(i != TIMEOUT_FOR_FLIP_PENDING_US);
+                       }
+                       temp_pipe = temp_pipe->bottom_pipe;
+               }
+       }
+
+       /* In flip immediate and pipe splitting case, we need to use GSL
+        * for synchronization. Only do setup on locking and on flip type change.
+        */
+       if (lock && (pipe->bottom_pipe != NULL || !flip_immediate))
+               if ((flip_immediate && pipe->stream_res.gsl_group == 0) ||
+                   (!flip_immediate && pipe->stream_res.gsl_group > 0))
+                       dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate);
+
+       if (pipe->plane_state != NULL)
+               flip_immediate = pipe->plane_state->flip_immediate;
+
+       temp_pipe = pipe->bottom_pipe;
+       while (flip_immediate && temp_pipe) {
+           if (temp_pipe->plane_state != NULL)
+               flip_immediate = temp_pipe->plane_state->flip_immediate;
+           temp_pipe = temp_pipe->bottom_pipe;
+       }
+
+       if (!lock && pipe->stream_res.gsl_group > 0 && pipe->plane_state &&
+               !flip_immediate)
+           dcn20_setup_gsl_group_as_lock(dc, pipe, false);
+
+       if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) {
+               union dmub_hw_lock_flags hw_locks = { 0 };
+               struct dmub_hw_lock_inst_flags inst_flags = { 0 };
+
+               hw_locks.bits.lock_pipe = 1;
+               inst_flags.otg_inst =  pipe->stream_res.tg->inst;
+
+               if (pipe->plane_state != NULL)
+                       hw_locks.bits.triple_buffer_lock = pipe->plane_state->triplebuffer_flips;
+
+               dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
+                                       lock,
+                                       &hw_locks,
+                                       &inst_flags);
+       } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
+               if (lock)
+                       pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
+               else
+                       pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
+       } else {
+               if (lock)
+                       pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
+               else
+                       pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
+       }
+}
+
+static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx *new_pipe)
+{
+       new_pipe->update_flags.raw = 0;
+
+       /* If non-phantom pipe is being transitioned to a phantom pipe,
+        * set disable and return immediately. This is because the pipe
+        * that was previously in use must be fully disabled before we
+        * can "enable" it as a phantom pipe (since the OTG will certainly
+        * be different). The post_unlock sequence will set the correct
+        * update flags to enable the phantom pipe.
+        */
+       if (old_pipe->plane_state && !old_pipe->plane_state->is_phantom &&
+                       new_pipe->plane_state && new_pipe->plane_state->is_phantom) {
+               new_pipe->update_flags.bits.disable = 1;
+               return;
+       }
+
+       /* Exit on unchanged, unused pipe */
+       if (!old_pipe->plane_state && !new_pipe->plane_state)
+               return;
+       /* Detect pipe enable/disable */
+       if (!old_pipe->plane_state && new_pipe->plane_state) {
+               new_pipe->update_flags.bits.enable = 1;
+               new_pipe->update_flags.bits.mpcc = 1;
+               new_pipe->update_flags.bits.dppclk = 1;
+               new_pipe->update_flags.bits.hubp_interdependent = 1;
+               new_pipe->update_flags.bits.hubp_rq_dlg_ttu = 1;
+               new_pipe->update_flags.bits.unbounded_req = 1;
+               new_pipe->update_flags.bits.gamut_remap = 1;
+               new_pipe->update_flags.bits.scaler = 1;
+               new_pipe->update_flags.bits.viewport = 1;
+               new_pipe->update_flags.bits.det_size = 1;
+               if (!new_pipe->top_pipe && !new_pipe->prev_odm_pipe) {
+                       new_pipe->update_flags.bits.odm = 1;
+                       new_pipe->update_flags.bits.global_sync = 1;
+               }
+               return;
+       }
+
+       /* For SubVP we need to unconditionally enable because any phantom pipes are
+        * always removed then newly added for every full updates whenever SubVP is in use.
+        * The remove-add sequence of the phantom pipe always results in the pipe
+        * being blanked in enable_stream_timing (DPG).
+        */
+       if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
+               new_pipe->update_flags.bits.enable = 1;
+
+       /* Phantom pipes are effectively disabled, if the pipe was previously phantom
+        * we have to enable
+        */
+       if (old_pipe->plane_state && old_pipe->plane_state->is_phantom &&
+                       new_pipe->plane_state && !new_pipe->plane_state->is_phantom)
+               new_pipe->update_flags.bits.enable = 1;
+
+       if (old_pipe->plane_state && !new_pipe->plane_state) {
+               new_pipe->update_flags.bits.disable = 1;
+               return;
+       }
+
+       /* Detect plane change */
+       if (old_pipe->plane_state != new_pipe->plane_state) {
+               new_pipe->update_flags.bits.plane_changed = true;
+       }
+
+       /* Detect top pipe only changes */
+       if (resource_is_pipe_type(new_pipe, OTG_MASTER)) {
+               /* Detect odm changes */
+               if (resource_is_odm_topology_changed(new_pipe, old_pipe))
+                       new_pipe->update_flags.bits.odm = 1;
+
+               /* Detect global sync changes */
+               if (old_pipe->pipe_dlg_param.vready_offset != new_pipe->pipe_dlg_param.vready_offset
+                               || old_pipe->pipe_dlg_param.vstartup_start != new_pipe->pipe_dlg_param.vstartup_start
+                               || old_pipe->pipe_dlg_param.vupdate_offset != new_pipe->pipe_dlg_param.vupdate_offset
+                               || old_pipe->pipe_dlg_param.vupdate_width != new_pipe->pipe_dlg_param.vupdate_width)
+                       new_pipe->update_flags.bits.global_sync = 1;
+       }
+
+       if (old_pipe->det_buffer_size_kb != new_pipe->det_buffer_size_kb)
+               new_pipe->update_flags.bits.det_size = 1;
+
+       /*
+        * Detect opp / tg change, only set on change, not on enable
+        * Assume mpcc inst = pipe index, if not this code needs to be updated
+        * since mpcc is what is affected by these. In fact all of our sequence
+        * makes this assumption at the moment with how hubp reset is matched to
+        * same index mpcc reset.
+        */
+       if (old_pipe->stream_res.opp != new_pipe->stream_res.opp)
+               new_pipe->update_flags.bits.opp_changed = 1;
+       if (old_pipe->stream_res.tg != new_pipe->stream_res.tg)
+               new_pipe->update_flags.bits.tg_changed = 1;
+
+       /*
+        * Detect mpcc blending changes, only dpp inst and opp matter here,
+        * mpccs getting removed/inserted update connected ones during their own
+        * programming
+        */
+       if (old_pipe->plane_res.dpp != new_pipe->plane_res.dpp
+                       || old_pipe->stream_res.opp != new_pipe->stream_res.opp)
+               new_pipe->update_flags.bits.mpcc = 1;
+
+       /* Detect dppclk change */
+       if (old_pipe->plane_res.bw.dppclk_khz != new_pipe->plane_res.bw.dppclk_khz)
+               new_pipe->update_flags.bits.dppclk = 1;
+
+       /* Check for scl update */
+       if (memcmp(&old_pipe->plane_res.scl_data, &new_pipe->plane_res.scl_data, sizeof(struct scaler_data)))
+                       new_pipe->update_flags.bits.scaler = 1;
+       /* Check for vp update */
+       if (memcmp(&old_pipe->plane_res.scl_data.viewport, &new_pipe->plane_res.scl_data.viewport, sizeof(struct rect))
+                       || memcmp(&old_pipe->plane_res.scl_data.viewport_c,
+                               &new_pipe->plane_res.scl_data.viewport_c, sizeof(struct rect)))
+               new_pipe->update_flags.bits.viewport = 1;
+
+       /* Detect dlg/ttu/rq updates */
+       {
+               struct _vcs_dpi_display_dlg_regs_st old_dlg_attr = old_pipe->dlg_regs;
+               struct _vcs_dpi_display_ttu_regs_st old_ttu_attr = old_pipe->ttu_regs;
+               struct _vcs_dpi_display_dlg_regs_st *new_dlg_attr = &new_pipe->dlg_regs;
+               struct _vcs_dpi_display_ttu_regs_st *new_ttu_attr = &new_pipe->ttu_regs;
+
+               /* Detect pipe interdependent updates */
+               if (old_dlg_attr.dst_y_prefetch != new_dlg_attr->dst_y_prefetch ||
+                               old_dlg_attr.vratio_prefetch != new_dlg_attr->vratio_prefetch ||
+                               old_dlg_attr.vratio_prefetch_c != new_dlg_attr->vratio_prefetch_c ||
+                               old_dlg_attr.dst_y_per_vm_vblank != new_dlg_attr->dst_y_per_vm_vblank ||
+                               old_dlg_attr.dst_y_per_row_vblank != new_dlg_attr->dst_y_per_row_vblank ||
+                               old_dlg_attr.dst_y_per_vm_flip != new_dlg_attr->dst_y_per_vm_flip ||
+                               old_dlg_attr.dst_y_per_row_flip != new_dlg_attr->dst_y_per_row_flip ||
+                               old_dlg_attr.refcyc_per_meta_chunk_vblank_l != new_dlg_attr->refcyc_per_meta_chunk_vblank_l ||
+                               old_dlg_attr.refcyc_per_meta_chunk_vblank_c != new_dlg_attr->refcyc_per_meta_chunk_vblank_c ||
+                               old_dlg_attr.refcyc_per_meta_chunk_flip_l != new_dlg_attr->refcyc_per_meta_chunk_flip_l ||
+                               old_dlg_attr.refcyc_per_line_delivery_pre_l != new_dlg_attr->refcyc_per_line_delivery_pre_l ||
+                               old_dlg_attr.refcyc_per_line_delivery_pre_c != new_dlg_attr->refcyc_per_line_delivery_pre_c ||
+                               old_ttu_attr.refcyc_per_req_delivery_pre_l != new_ttu_attr->refcyc_per_req_delivery_pre_l ||
+                               old_ttu_attr.refcyc_per_req_delivery_pre_c != new_ttu_attr->refcyc_per_req_delivery_pre_c ||
+                               old_ttu_attr.refcyc_per_req_delivery_pre_cur0 != new_ttu_attr->refcyc_per_req_delivery_pre_cur0 ||
+                               old_ttu_attr.refcyc_per_req_delivery_pre_cur1 != new_ttu_attr->refcyc_per_req_delivery_pre_cur1 ||
+                               old_ttu_attr.min_ttu_vblank != new_ttu_attr->min_ttu_vblank ||
+                               old_ttu_attr.qos_level_flip != new_ttu_attr->qos_level_flip) {
+                       old_dlg_attr.dst_y_prefetch = new_dlg_attr->dst_y_prefetch;
+                       old_dlg_attr.vratio_prefetch = new_dlg_attr->vratio_prefetch;
+                       old_dlg_attr.vratio_prefetch_c = new_dlg_attr->vratio_prefetch_c;
+                       old_dlg_attr.dst_y_per_vm_vblank = new_dlg_attr->dst_y_per_vm_vblank;
+                       old_dlg_attr.dst_y_per_row_vblank = new_dlg_attr->dst_y_per_row_vblank;
+                       old_dlg_attr.dst_y_per_vm_flip = new_dlg_attr->dst_y_per_vm_flip;
+                       old_dlg_attr.dst_y_per_row_flip = new_dlg_attr->dst_y_per_row_flip;
+                       old_dlg_attr.refcyc_per_meta_chunk_vblank_l = new_dlg_attr->refcyc_per_meta_chunk_vblank_l;
+                       old_dlg_attr.refcyc_per_meta_chunk_vblank_c = new_dlg_attr->refcyc_per_meta_chunk_vblank_c;
+                       old_dlg_attr.refcyc_per_meta_chunk_flip_l = new_dlg_attr->refcyc_per_meta_chunk_flip_l;
+                       old_dlg_attr.refcyc_per_line_delivery_pre_l = new_dlg_attr->refcyc_per_line_delivery_pre_l;
+                       old_dlg_attr.refcyc_per_line_delivery_pre_c = new_dlg_attr->refcyc_per_line_delivery_pre_c;
+                       old_ttu_attr.refcyc_per_req_delivery_pre_l = new_ttu_attr->refcyc_per_req_delivery_pre_l;
+                       old_ttu_attr.refcyc_per_req_delivery_pre_c = new_ttu_attr->refcyc_per_req_delivery_pre_c;
+                       old_ttu_attr.refcyc_per_req_delivery_pre_cur0 = new_ttu_attr->refcyc_per_req_delivery_pre_cur0;
+                       old_ttu_attr.refcyc_per_req_delivery_pre_cur1 = new_ttu_attr->refcyc_per_req_delivery_pre_cur1;
+                       old_ttu_attr.min_ttu_vblank = new_ttu_attr->min_ttu_vblank;
+                       old_ttu_attr.qos_level_flip = new_ttu_attr->qos_level_flip;
+                       new_pipe->update_flags.bits.hubp_interdependent = 1;
+               }
+               /* Detect any other updates to ttu/rq/dlg */
+               if (memcmp(&old_dlg_attr, &new_pipe->dlg_regs, sizeof(old_dlg_attr)) ||
+                               memcmp(&old_ttu_attr, &new_pipe->ttu_regs, sizeof(old_ttu_attr)) ||
+                               memcmp(&old_pipe->rq_regs, &new_pipe->rq_regs, sizeof(old_pipe->rq_regs)))
+                       new_pipe->update_flags.bits.hubp_rq_dlg_ttu = 1;
+       }
+
+       if (old_pipe->unbounded_req != new_pipe->unbounded_req)
+               new_pipe->update_flags.bits.unbounded_req = 1;
+}
+
+static void dcn20_update_dchubp_dpp(
+       struct dc *dc,
+       struct pipe_ctx *pipe_ctx,
+       struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       struct dccg *dccg = dc->res_pool->dccg;
+       bool viewport_changed = false;
+
+       if (pipe_ctx->update_flags.bits.dppclk)
+               dpp->funcs->dpp_dppclk_control(dpp, false, true);
+
+       if (pipe_ctx->update_flags.bits.enable)
+               dccg->funcs->update_dpp_dto(dccg, dpp->inst, pipe_ctx->plane_res.bw.dppclk_khz);
+
+       /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
+        * VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
+        * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
+        */
+       if (pipe_ctx->update_flags.bits.hubp_rq_dlg_ttu) {
+               hubp->funcs->hubp_vtg_sel(hubp, pipe_ctx->stream_res.tg->inst);
+
+               hubp->funcs->hubp_setup(
+                       hubp,
+                       &pipe_ctx->dlg_regs,
+                       &pipe_ctx->ttu_regs,
+                       &pipe_ctx->rq_regs,
+                       &pipe_ctx->pipe_dlg_param);
+       }
+
+       if (pipe_ctx->update_flags.bits.unbounded_req && hubp->funcs->set_unbounded_requesting)
+               hubp->funcs->set_unbounded_requesting(hubp, pipe_ctx->unbounded_req);
+
+       if (pipe_ctx->update_flags.bits.hubp_interdependent)
+               hubp->funcs->hubp_setup_interdependent(
+                       hubp,
+                       &pipe_ctx->dlg_regs,
+                       &pipe_ctx->ttu_regs);
+
+       if (pipe_ctx->update_flags.bits.enable ||
+                       pipe_ctx->update_flags.bits.plane_changed ||
+                       plane_state->update_flags.bits.bpp_change ||
+                       plane_state->update_flags.bits.input_csc_change ||
+                       plane_state->update_flags.bits.color_space_change ||
+                       plane_state->update_flags.bits.coeff_reduction_change) {
+               struct dc_bias_and_scale bns_params = {0};
+
+               // program the input csc
+               dpp->funcs->dpp_setup(dpp,
+                               plane_state->format,
+                               EXPANSION_MODE_ZERO,
+                               plane_state->input_csc_color_matrix,
+                               plane_state->color_space,
+                               NULL);
+
+               if (dpp->funcs->dpp_program_bias_and_scale) {
+                       //TODO :for CNVC set scale and bias registers if necessary
+                       build_prescale_params(&bns_params, plane_state);
+                       dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
+               }
+       }
+
+       if (pipe_ctx->update_flags.bits.mpcc
+                       || pipe_ctx->update_flags.bits.plane_changed
+                       || plane_state->update_flags.bits.global_alpha_change
+                       || plane_state->update_flags.bits.per_pixel_alpha_change) {
+               // MPCC inst is equal to pipe index in practice
+               hws->funcs.update_mpcc(dc, pipe_ctx);
+       }
+
+       if (pipe_ctx->update_flags.bits.scaler ||
+                       plane_state->update_flags.bits.scaling_change ||
+                       plane_state->update_flags.bits.position_change ||
+                       plane_state->update_flags.bits.per_pixel_alpha_change ||
+                       pipe_ctx->stream->update_flags.bits.scaling) {
+               pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->plane_state->per_pixel_alpha;
+               ASSERT(pipe_ctx->plane_res.scl_data.lb_params.depth == LB_PIXEL_DEPTH_36BPP);
+               /* scaler configuration */
+               pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
+                               pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
+       }
+
+       if (pipe_ctx->update_flags.bits.viewport ||
+                       (context == dc->current_state && plane_state->update_flags.bits.position_change) ||
+                       (context == dc->current_state && plane_state->update_flags.bits.scaling_change) ||
+                       (context == dc->current_state && pipe_ctx->stream->update_flags.bits.scaling)) {
+
+               hubp->funcs->mem_program_viewport(
+                       hubp,
+                       &pipe_ctx->plane_res.scl_data.viewport,
+                       &pipe_ctx->plane_res.scl_data.viewport_c);
+               viewport_changed = true;
+       }
+
+       /* Any updates are handled in dc interface, just need to apply existing for plane enable */
+       if ((pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed ||
+                       pipe_ctx->update_flags.bits.scaler || viewport_changed == true) &&
+                       pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
+               dc->hwss.set_cursor_position(pipe_ctx);
+               dc->hwss.set_cursor_attribute(pipe_ctx);
+
+               if (dc->hwss.set_cursor_sdr_white_level)
+                       dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
+       }
+
+       /* Any updates are handled in dc interface, just need
+        * to apply existing for plane enable / opp change */
+       if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed
+                       || pipe_ctx->update_flags.bits.plane_changed
+                       || pipe_ctx->stream->update_flags.bits.gamut_remap
+                       || plane_state->update_flags.bits.gamut_remap_change
+                       || pipe_ctx->stream->update_flags.bits.out_csc) {
+               /* dpp/cm gamut remap*/
+               dc->hwss.program_gamut_remap(pipe_ctx);
+
+               /*call the dcn2 method which uses mpc csc*/
+               dc->hwss.program_output_csc(dc,
+                               pipe_ctx,
+                               pipe_ctx->stream->output_color_space,
+                               pipe_ctx->stream->csc_color_matrix.matrix,
+                               hubp->opp_id);
+       }
+
+       if (pipe_ctx->update_flags.bits.enable ||
+                       pipe_ctx->update_flags.bits.plane_changed ||
+                       pipe_ctx->update_flags.bits.opp_changed ||
+                       plane_state->update_flags.bits.pixel_format_change ||
+                       plane_state->update_flags.bits.horizontal_mirror_change ||
+                       plane_state->update_flags.bits.rotation_change ||
+                       plane_state->update_flags.bits.swizzle_change ||
+                       plane_state->update_flags.bits.dcc_change ||
+                       plane_state->update_flags.bits.bpp_change ||
+                       plane_state->update_flags.bits.scaling_change ||
+                       plane_state->update_flags.bits.plane_size_change) {
+               struct plane_size size = plane_state->plane_size;
+
+               size.surface_size = pipe_ctx->plane_res.scl_data.viewport;
+               hubp->funcs->hubp_program_surface_config(
+                       hubp,
+                       plane_state->format,
+                       &plane_state->tiling_info,
+                       &size,
+                       plane_state->rotation,
+                       &plane_state->dcc,
+                       plane_state->horizontal_mirror,
+                       0);
+               hubp->power_gated = false;
+       }
+
+       if (pipe_ctx->update_flags.bits.enable ||
+               pipe_ctx->update_flags.bits.plane_changed ||
+               plane_state->update_flags.bits.addr_update) {
+               if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) &&
+                               pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN) {
+                       union block_sequence_params params;
+
+                       params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
+                       params.subvp_save_surf_addr.addr = &pipe_ctx->plane_state->address;
+                       params.subvp_save_surf_addr.subvp_index = pipe_ctx->subvp_index;
+                       hwss_subvp_save_surf_addr(&params);
+               }
+               hws->funcs.update_plane_addr(dc, pipe_ctx);
+       }
+
+       if (pipe_ctx->update_flags.bits.enable)
+               hubp->funcs->set_blank(hubp, false);
+       /* If the stream paired with this plane is phantom, the plane is also phantom */
+       if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM
+                       && hubp->funcs->phantom_hubp_post_enable)
+               hubp->funcs->phantom_hubp_post_enable(hubp);
+}
+
+static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
+{
+       struct pipe_ctx *other_pipe;
+       int vready_offset = pipe->pipe_dlg_param.vready_offset;
+
+       /* Always use the largest vready_offset of all connected pipes */
+       for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+       for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+       for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+       for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
+               if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
+                       vready_offset = other_pipe->pipe_dlg_param.vready_offset;
+       }
+
+       return vready_offset;
+}
+
+static void dcn20_program_pipe(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* Only need to unblank on top pipe */
+       if (resource_is_pipe_type(pipe_ctx, OTG_MASTER)) {
+               if (pipe_ctx->update_flags.bits.enable ||
+                               pipe_ctx->update_flags.bits.odm ||
+                               pipe_ctx->stream->update_flags.bits.abm_level)
+                       hws->funcs.blank_pixel_data(dc, pipe_ctx,
+                                       !pipe_ctx->plane_state ||
+                                       !pipe_ctx->plane_state->visible);
+       }
+
+       /* Only update TG on top pipe */
+       if (pipe_ctx->update_flags.bits.global_sync && !pipe_ctx->top_pipe
+                       && !pipe_ctx->prev_odm_pipe) {
+               pipe_ctx->stream_res.tg->funcs->program_global_sync(
+                               pipe_ctx->stream_res.tg,
+                               calculate_vready_offset_for_group(pipe_ctx),
+                               pipe_ctx->pipe_dlg_param.vstartup_start,
+                               pipe_ctx->pipe_dlg_param.vupdate_offset,
+                               pipe_ctx->pipe_dlg_param.vupdate_width);
+
+               if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM)
+                       pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+
+               pipe_ctx->stream_res.tg->funcs->set_vtg_params(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
+
+               if (hws->funcs.setup_vupdate_interrupt)
+                       hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
+       }
+
+       if (pipe_ctx->update_flags.bits.odm)
+               hws->funcs.update_odm(dc, context, pipe_ctx);
+
+       if (pipe_ctx->update_flags.bits.enable) {
+               if (hws->funcs.enable_plane)
+                       hws->funcs.enable_plane(dc, pipe_ctx, context);
+               else
+                       dcn20_enable_plane(dc, pipe_ctx, context);
+
+               if (dc->res_pool->hubbub->funcs->force_wm_propagate_to_pipes)
+                       dc->res_pool->hubbub->funcs->force_wm_propagate_to_pipes(dc->res_pool->hubbub);
+       }
+
+       if (dc->res_pool->hubbub->funcs->program_det_size && pipe_ctx->update_flags.bits.det_size)
+               dc->res_pool->hubbub->funcs->program_det_size(
+                       dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->det_buffer_size_kb);
+
+       if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
+               dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
+
+       if (pipe_ctx->update_flags.bits.enable
+                       || pipe_ctx->plane_state->update_flags.bits.hdr_mult)
+               hws->funcs.set_hdr_multiplier(pipe_ctx);
+
+       if (pipe_ctx->update_flags.bits.enable ||
+           pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+           pipe_ctx->plane_state->update_flags.bits.gamma_change ||
+           pipe_ctx->plane_state->update_flags.bits.lut_3d)
+               hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
+
+       /* dcn10_translate_regamma_to_hw_format takes 750us to finish
+        * only do gamma programming for powering on, internal memcmp to avoid
+        * updating on slave planes
+        */
+       if (pipe_ctx->update_flags.bits.enable ||
+                       pipe_ctx->update_flags.bits.plane_changed ||
+                       pipe_ctx->stream->update_flags.bits.out_tf ||
+                       pipe_ctx->plane_state->update_flags.bits.output_tf_change)
+               hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
+
+       /* If the pipe has been enabled or has a different opp, we
+        * should reprogram the fmt. This deals with cases where
+        * interation between mpc and odm combine on different streams
+        * causes a different pipe to be chosen to odm combine with.
+        */
+       if (pipe_ctx->update_flags.bits.enable
+           || pipe_ctx->update_flags.bits.opp_changed) {
+
+               pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
+                       pipe_ctx->stream_res.opp,
+                       COLOR_SPACE_YCBCR601,
+                       pipe_ctx->stream->timing.display_color_depth,
+                       pipe_ctx->stream->signal);
+
+               pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
+                       pipe_ctx->stream_res.opp,
+                       &pipe_ctx->stream->bit_depth_params,
+                       &pipe_ctx->stream->clamping);
+       }
+
+       /* Set ABM pipe after other pipe configurations done */
+       if (pipe_ctx->plane_state->visible) {
+               if (pipe_ctx->stream_res.abm) {
+                       dc->hwss.set_pipe(pipe_ctx);
+                       pipe_ctx->stream_res.abm->funcs->set_abm_level(pipe_ctx->stream_res.abm,
+                               pipe_ctx->stream->abm_level);
+               }
+       }
+}
+
+void dcn20_program_front_end_for_ctx(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       if (resource_is_pipe_topology_changed(dc->current_state, context))
+               resource_log_pipe_topology_update(dc, context);
+
+       if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+                       if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->plane_state) {
+                               ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
+                               /*turn off triple buffer for full update*/
+                               dc->hwss.program_triplebuffer(
+                                               dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
+                       }
+               }
+       }
+
+       /* Set pipe update flags and lock pipes */
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i],
+                               &context->res_ctx.pipe_ctx[i]);
+
+       /* When disabling phantom pipes, turn on phantom OTG first (so we can get double
+        * buffer updates properly)
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct dc_stream_state *stream = dc->current_state->res_ctx.pipe_ctx[i].stream;
+
+               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable && stream &&
+                       dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
+
+                       if (tg->funcs->enable_crtc) {
+                               if (dc->hwss.blank_phantom) {
+                                       int main_pipe_width, main_pipe_height;
+
+                                       main_pipe_width = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.width;
+                                       main_pipe_height = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.height;
+                                       dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
+                               }
+                               tg->funcs->enable_crtc(tg);
+                       }
+               }
+       }
+       /* OTG blank before disabling all front ends */
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
+                               && !context->res_ctx.pipe_ctx[i].top_pipe
+                               && !context->res_ctx.pipe_ctx[i].prev_odm_pipe
+                               && context->res_ctx.pipe_ctx[i].stream)
+                       hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);
+
+
+       /* Disconnect mpcc */
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
+                               || context->res_ctx.pipe_ctx[i].update_flags.bits.opp_changed) {
+                       struct hubbub *hubbub = dc->res_pool->hubbub;
+
+                       /* Phantom pipe DET should be 0, but if a pipe in use is being transitioned to phantom
+                        * then we want to do the programming here (effectively it's being disabled). If we do
+                        * the programming later the DET won't be updated until the OTG for the phantom pipe is
+                        * turned on (i.e. in an MCLK switch) which can come in too late and cause issues with
+                        * DET allocation.
+                        */
+                       if (hubbub->funcs->program_det_size && (context->res_ctx.pipe_ctx[i].update_flags.bits.disable ||
+                                       (context->res_ctx.pipe_ctx[i].plane_state && context->res_ctx.pipe_ctx[i].plane_state->is_phantom)))
+                               hubbub->funcs->program_det_size(hubbub, dc->current_state->res_ctx.pipe_ctx[i].plane_res.hubp->inst, 0);
+                       hws->funcs.plane_atomic_disconnect(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
+                       DC_LOG_DC("Reset mpcc for pipe %d\n", dc->current_state->res_ctx.pipe_ctx[i].pipe_idx);
+               }
+
+       /*
+        * Program all updated pipes, order matters for mpcc setup. Start with
+        * top pipe and program all pipes that follow in order
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->plane_state && !pipe->top_pipe) {
+                       while (pipe) {
+                               if (hws->funcs.program_pipe)
+                                       hws->funcs.program_pipe(dc, pipe, context);
+                               else {
+                                       /* Don't program phantom pipes in the regular front end programming sequence.
+                                        * There is an MPO transition case where a pipe being used by a video plane is
+                                        * transitioned directly to be a phantom pipe when closing the MPO video. However
+                                        * the phantom pipe will program a new HUBP_VTG_SEL (update takes place right away),
+                                        * but the MPO still exists until the double buffered update of the main pipe so we
+                                        * will get a frame of underflow if the phantom pipe is programmed here.
+                                        */
+                                       if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_PHANTOM)
+                                               dcn20_program_pipe(dc, pipe, context);
+                               }
+
+                               pipe = pipe->bottom_pipe;
+                       }
+               }
+               /* Program secondary blending tree and writeback pipes */
+               pipe = &context->res_ctx.pipe_ctx[i];
+               if (!pipe->top_pipe && !pipe->prev_odm_pipe
+                               && pipe->stream && pipe->stream->num_wb_info > 0
+                               && (pipe->update_flags.raw || (pipe->plane_state && pipe->plane_state->update_flags.raw)
+                                       || pipe->stream->update_flags.raw)
+                               && hws->funcs.program_all_writeback_pipes_in_tree)
+                       hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context);
+
+               /* Avoid underflow by check of pipe line read when adding 2nd plane. */
+               if (hws->wa.wait_hubpret_read_start_during_mpo_transition &&
+                       !pipe->top_pipe &&
+                       pipe->stream &&
+                       pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start &&
+                       dc->current_state->stream_status[0].plane_count == 1 &&
+                       context->stream_status[0].plane_count > 1) {
+                       pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
+               }
+
+               /* when dynamic ODM is active, pipes must be reconfigured when all planes are
+                * disabled, as some transitions will leave software and hardware state
+                * mismatched.
+                */
+               if (dc->debug.enable_single_display_2to1_odm_policy &&
+                       pipe->stream &&
+                       pipe->update_flags.bits.disable &&
+                       !pipe->prev_odm_pipe &&
+                       hws->funcs.update_odm)
+                       hws->funcs.update_odm(dc, context, pipe);
+       }
+}
+
+void dcn20_post_unlock_program_front_end(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+       const unsigned int TIMEOUT_FOR_PIPE_ENABLE_US = 100000;
+       unsigned int polling_interval_us = 1;
+       struct dce_hwseq *hwseq = dc->hwseq;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
+                       dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
+
+       /*
+        * If we are enabling a pipe, we need to wait for pending clear as this is a critical
+        * part of the enable operation otherwise, DM may request an immediate flip which
+        * will cause HW to perform an "immediate enable" (as opposed to "vsync enable") which
+        * is unsupported on DCN.
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               // Don't check flip pending on phantom pipes
+               if (pipe->plane_state && !pipe->top_pipe && pipe->update_flags.bits.enable &&
+                               pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+                       struct hubp *hubp = pipe->plane_res.hubp;
+                       int j = 0;
+                       for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_US / polling_interval_us
+                                       && hubp->funcs->hubp_is_flip_pending(hubp); j++)
+                               udelay(polling_interval_us);
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->plane_state && !pipe->top_pipe) {
+                       /* Program phantom pipe here to prevent a frame of underflow in the MPO transition
+                        * case (if a pipe being used for a video plane transitions to a phantom pipe, it
+                        * can underflow due to HUBP_VTG_SEL programming if done in the regular front end
+                        * programming sequence).
+                        */
+                       while (pipe) {
+                               if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                                       /* When turning on the phantom pipe we want to run through the
+                                        * entire enable sequence, so apply all the "enable" flags.
+                                        */
+                                       if (dc->hwss.apply_update_flags_for_phantom)
+                                               dc->hwss.apply_update_flags_for_phantom(pipe);
+                                       if (dc->hwss.update_phantom_vp_position)
+                                               dc->hwss.update_phantom_vp_position(dc, context, pipe);
+                                       dcn20_program_pipe(dc, pipe, context);
+                               }
+                               pipe = pipe->bottom_pipe;
+                       }
+               }
+       }
+
+       /* P-State support transitions:
+        * Natural -> FPO:              P-State disabled in prepare, force disallow anytime is safe
+        * FPO -> Natural:              Unforce anytime after FW disable is safe (P-State will assert naturally)
+        * Unsupported -> FPO:  P-State enabled in optimize, force disallow anytime is safe
+        * FPO -> Unsupported:  P-State disabled in prepare, unforce disallow anytime is safe
+        * FPO <-> SubVP:               Force disallow is maintained on the FPO / SubVP pipes
+        */
+       if (hwseq && hwseq->funcs.update_force_pstate)
+               dc->hwseq->funcs.update_force_pstate(dc, context);
+
+       /* Only program the MALL registers after all the main and phantom pipes
+        * are done programming.
+        */
+       if (hwseq->funcs.program_mall_pipe_config)
+               hwseq->funcs.program_mall_pipe_config(dc, context);
+
+       /* WA to apply WM setting*/
+       if (hwseq->wa.DEGVIDCN21)
+               dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub);
+
+
+       /* WA for stutter underflow during MPO transitions when adding 2nd plane */
+       if (hwseq->wa.disallow_self_refresh_during_multi_plane_transition) {
+
+               if (dc->current_state->stream_status[0].plane_count == 1 &&
+                               context->stream_status[0].plane_count > 1) {
+
+                       struct timing_generator *tg = dc->res_pool->timing_generators[0];
+
+                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, false);
+
+                       hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied = true;
+                       hwseq->wa_state.disallow_self_refresh_during_multi_plane_transition_applied_on_frame = tg->funcs->get_frame_count(tg);
+               }
+       }
+}
+
+void dcn20_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       unsigned int compbuf_size_kb = 0;
+       unsigned int cache_wm_a = context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns;
+       unsigned int i;
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       false);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               // At optimize don't restore the original watermark value
+               if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
+                       context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
+                       break;
+               }
+       }
+
+       /* program dchubbub watermarks:
+        * For assigning wm_optimized_required, use |= operator since we don't want
+        * to clear the value if the optimize has not happened yet
+        */
+       dc->wm_optimized_required |= hubbub->funcs->program_watermarks(hubbub,
+                                       &context->bw_ctx.bw.dcn.watermarks,
+                                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
+                                       false);
+
+       // Restore the real watermark so we can commit the value to DMCUB
+       // DMCUB uses the "original" watermark value in SubVP MCLK switch
+       context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = cache_wm_a;
+
+       /* decrease compbuf size */
+       if (hubbub->funcs->program_compbuf_size) {
+               if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) {
+                       compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes;
+                       dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
+               } else {
+                       compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb;
+                       dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
+               }
+
+               hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false);
+       }
+}
+
+void dcn20_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       int i;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               // At optimize don't need  to restore the original watermark value
+               if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
+                       context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
+                       break;
+               }
+       }
+
+       /* program dchubbub watermarks */
+       hubbub->funcs->program_watermarks(hubbub,
+                                       &context->bw_ctx.bw.dcn.watermarks,
+                                       dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
+                                       true);
+
+       if (dc->clk_mgr->dc_mode_softmax_enabled)
+               if (dc->clk_mgr->clks.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
+                               context->bw_ctx.bw.dcn.clk.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
+                       dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
+
+       /* increase compbuf size */
+       if (hubbub->funcs->program_compbuf_size)
+               hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
+
+       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
+               dc_dmub_srv_p_state_delegate(dc,
+                       true, context);
+               context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
+               dc->clk_mgr->clks.fw_based_mclk_switching = true;
+       } else {
+               dc->clk_mgr->clks.fw_based_mclk_switching = false;
+       }
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       true);
+       if (context->bw_ctx.bw.dcn.clk.zstate_support == DCN_ZSTATE_SUPPORT_ALLOW) {
+               for (i = 0; i < dc->res_pool->pipe_count; ++i) {
+                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+                       if (pipe_ctx->stream && pipe_ctx->plane_res.hubp->funcs->program_extended_blank
+                               && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max
+                               && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)
+                                       pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp,
+                                               pipe_ctx->dlg_regs.min_dst_y_next_start);
+               }
+       }
+}
+
+bool dcn20_update_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* recalculate DML parameters */
+       if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false))
+               return false;
+
+       /* apply updated bandwidth parameters */
+       dc->hwss.prepare_bandwidth(dc, context);
+
+       /* update hubp configs for all pipes */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->plane_state == NULL)
+                       continue;
+
+               if (pipe_ctx->top_pipe == NULL) {
+                       bool blank = !is_pipe_tree_visible(pipe_ctx);
+
+                       pipe_ctx->stream_res.tg->funcs->program_global_sync(
+                                       pipe_ctx->stream_res.tg,
+                                       calculate_vready_offset_for_group(pipe_ctx),
+                                       pipe_ctx->pipe_dlg_param.vstartup_start,
+                                       pipe_ctx->pipe_dlg_param.vupdate_offset,
+                                       pipe_ctx->pipe_dlg_param.vupdate_width);
+
+                       pipe_ctx->stream_res.tg->funcs->set_vtg_params(
+                                       pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, false);
+
+                       if (pipe_ctx->prev_odm_pipe == NULL)
+                               hws->funcs.blank_pixel_data(dc, pipe_ctx, blank);
+
+                       if (hws->funcs.setup_vupdate_interrupt)
+                               hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
+               }
+
+               pipe_ctx->plane_res.hubp->funcs->hubp_setup(
+                               pipe_ctx->plane_res.hubp,
+                                       &pipe_ctx->dlg_regs,
+                                       &pipe_ctx->ttu_regs,
+                                       &pipe_ctx->rq_regs,
+                                       &pipe_ctx->pipe_dlg_param);
+       }
+
+       return true;
+}
+
+void dcn20_enable_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context)
+{
+       struct dwbc *dwb;
+       struct mcif_wb *mcif_wb;
+       struct timing_generator *optc;
+
+       ASSERT(wb_info->dwb_pipe_inst < MAX_DWB_PIPES);
+       ASSERT(wb_info->wb_enabled);
+       dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
+       mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst];
+
+       /* set the OPTC source mux */
+       optc = dc->res_pool->timing_generators[dwb->otg_inst];
+       optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst);
+       /* set MCIF_WB buffer and arbitration configuration */
+       mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height);
+       mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]);
+       /* Enable MCIF_WB */
+       mcif_wb->funcs->enable_mcif(mcif_wb);
+       /* Enable DWB */
+       dwb->funcs->enable(dwb, &wb_info->dwb_params);
+       /* TODO: add sequence to enable/disable warmup */
+}
+
+void dcn20_disable_writeback(
+               struct dc *dc,
+               unsigned int dwb_pipe_inst)
+{
+       struct dwbc *dwb;
+       struct mcif_wb *mcif_wb;
+
+       ASSERT(dwb_pipe_inst < MAX_DWB_PIPES);
+       dwb = dc->res_pool->dwbc[dwb_pipe_inst];
+       mcif_wb = dc->res_pool->mcif_wb[dwb_pipe_inst];
+
+       dwb->funcs->disable(dwb);
+       mcif_wb->funcs->disable_mcif(mcif_wb);
+}
+
+bool dcn20_wait_for_blank_complete(
+               struct output_pixel_processor *opp)
+{
+       int counter;
+
+       for (counter = 0; counter < 1000; counter++) {
+               if (opp->funcs->dpg_is_blanked(opp))
+                       break;
+
+               udelay(100);
+       }
+
+       if (counter == 1000) {
+               dm_error("DC: failed to blank crtc!\n");
+               return false;
+       }
+
+       return true;
+}
+
+bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx)
+{
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+
+       if (!hubp)
+               return false;
+       return hubp->funcs->dmdata_status_done(hubp);
+}
+
+void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+
+       if (pipe_ctx->stream_res.dsc) {
+               struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
+
+               hws->funcs.dsc_pg_control(hws, pipe_ctx->stream_res.dsc->inst, true);
+               while (odm_pipe) {
+                       hws->funcs.dsc_pg_control(hws, odm_pipe->stream_res.dsc->inst, true);
+                       odm_pipe = odm_pipe->next_odm_pipe;
+               }
+       }
+}
+
+void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+
+       if (pipe_ctx->stream_res.dsc) {
+               struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
+
+               hws->funcs.dsc_pg_control(hws, pipe_ctx->stream_res.dsc->inst, false);
+               while (odm_pipe) {
+                       hws->funcs.dsc_pg_control(hws, odm_pipe->stream_res.dsc->inst, false);
+                       odm_pipe = odm_pipe->next_odm_pipe;
+               }
+       }
+}
+
+void dcn20_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_dmdata_attributes attr = { 0 };
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+
+       attr.dmdata_mode = DMDATA_HW_MODE;
+       attr.dmdata_size =
+               dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;
+       attr.address.quad_part =
+                       pipe_ctx->stream->dmdata_address.quad_part;
+       attr.dmdata_dl_delta = 0;
+       attr.dmdata_qos_mode = 0;
+       attr.dmdata_qos_level = 0;
+       attr.dmdata_repeat = 1; /* always repeat */
+       attr.dmdata_updated = 1;
+       attr.dmdata_sw_data = NULL;
+
+       hubp->funcs->dmdata_set_attributes(hubp, &attr);
+}
+
+void dcn20_init_vm_ctx(
+               struct dce_hwseq *hws,
+               struct dc *dc,
+               struct dc_virtual_addr_space_config *va_config,
+               int vmid)
+{
+       struct dcn_hubbub_virt_addr_config config;
+
+       if (vmid == 0) {
+               ASSERT(0); /* VMID cannot be 0 for vm context */
+               return;
+       }
+
+       config.page_table_start_addr = va_config->page_table_start_addr;
+       config.page_table_end_addr = va_config->page_table_end_addr;
+       config.page_table_block_size = va_config->page_table_block_size_in_bytes;
+       config.page_table_depth = va_config->page_table_depth;
+       config.page_table_base_addr = va_config->page_table_base_addr;
+
+       dc->res_pool->hubbub->funcs->init_vm_ctx(dc->res_pool->hubbub, &config, vmid);
+}
+
+int dcn20_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
+{
+       struct dcn_hubbub_phys_addr_config config;
+
+       config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
+       config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
+       config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
+       config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
+       config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
+       config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
+       config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
+       config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
+       config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
+       config.page_table_default_page_addr = pa_config->page_table_default_page_addr;
+
+       return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
+}
+
+static bool patch_address_for_sbs_tb_stereo(
+               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
+{
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       bool sec_split = pipe_ctx->top_pipe &&
+                       pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
+       if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+                       (pipe_ctx->stream->timing.timing_3d_format ==
+                       TIMING_3D_FORMAT_SIDE_BY_SIDE ||
+                       pipe_ctx->stream->timing.timing_3d_format ==
+                       TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
+               *addr = plane_state->address.grph_stereo.left_addr;
+               plane_state->address.grph_stereo.left_addr =
+                               plane_state->address.grph_stereo.right_addr;
+               return true;
+       }
+
+       if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
+                       plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
+               plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
+               plane_state->address.grph_stereo.right_addr =
+                               plane_state->address.grph_stereo.left_addr;
+               plane_state->address.grph_stereo.right_meta_addr =
+                               plane_state->address.grph_stereo.left_meta_addr;
+       }
+       return false;
+}
+
+void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       bool addr_patched = false;
+       PHYSICAL_ADDRESS_LOC addr;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+
+       if (plane_state == NULL)
+               return;
+
+       addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
+
+       // Call Helper to track VMID use
+       vm_helper_mark_vmid_used(dc->vm_helper, plane_state->address.vmid, pipe_ctx->plane_res.hubp->inst);
+
+       pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
+                       pipe_ctx->plane_res.hubp,
+                       &plane_state->address,
+                       plane_state->flip_immediate);
+
+       plane_state->status.requested_address = plane_state->address;
+
+       if (plane_state->flip_immediate)
+               plane_state->status.current_address = plane_state->address;
+
+       if (addr_patched)
+               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
+}
+
+void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings)
+{
+       struct encoder_unblank_param params = {0};
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dce_hwseq *hws = link->dc->hwseq;
+       struct pipe_ctx *odm_pipe;
+
+       params.opp_cnt = 1;
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               params.opp_cnt++;
+       }
+       /* only 3 items below are used by unblank */
+       params.timing = pipe_ctx->stream->timing;
+
+       params.link_settings.link_rate = link_settings->link_rate;
+
+       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
+               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
+                               pipe_ctx->stream_res.hpo_dp_stream_enc,
+                               pipe_ctx->stream_res.tg->inst);
+       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1)
+                       params.timing.pix_clk_100hz /= 2;
+               pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine(
+                               pipe_ctx->stream_res.stream_enc, params.opp_cnt > 1);
+               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
+       }
+
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+               hws->funcs.edp_backlight_control(link, true);
+       }
+}
+
+void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       int start_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+
+       if (start_line < 0)
+               start_line = 0;
+
+       if (tg->funcs->setup_vertical_interrupt2)
+               tg->funcs->setup_vertical_interrupt2(tg, start_line);
+}
+
+static void dcn20_reset_back_end_for_pipe(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context)
+{
+       int i;
+       struct dc_link *link = pipe_ctx->stream->link;
+       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+
+       DC_LOGGER_INIT(dc->ctx->logger);
+       if (pipe_ctx->stream_res.stream_enc == NULL) {
+               pipe_ctx->stream = NULL;
+               return;
+       }
+
+       /* DPMS may already disable or */
+       /* dpms_off status is incorrect due to fastboot
+        * feature. When system resume from S4 with second
+        * screen only, the dpms_off would be true but
+        * VBIOS lit up eDP, so check link status too.
+        */
+       if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+               dc->link_srv->set_dpms_off(pipe_ctx);
+       else if (pipe_ctx->stream_res.audio)
+               dc->hwss.disable_audio_stream(pipe_ctx);
+
+       /* free acquired resources */
+       if (pipe_ctx->stream_res.audio) {
+               /*disable az_endpoint*/
+               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+               /*free audio*/
+               if (dc->caps.dynamic_audio == true) {
+                       /*we have to dynamic arbitrate the audio endpoints*/
+                       /*we free the resource, need reset is_audio_acquired*/
+                       update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
+                                       pipe_ctx->stream_res.audio, false);
+                       pipe_ctx->stream_res.audio = NULL;
+               }
+       }
+
+       /* by upper caller loop, parent pipe: pipe0, will be reset last.
+        * back end share by all pipes and will be disable only when disable
+        * parent pipe.
+        */
+       if (pipe_ctx->top_pipe == NULL) {
+
+               dc->hwss.set_abm_immediate_disable(pipe_ctx);
+
+               pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
+
+               pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+               if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
+                       pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
+                                       pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+
+               if (pipe_ctx->stream_res.tg->funcs->set_drr)
+                       pipe_ctx->stream_res.tg->funcs->set_drr(
+                                       pipe_ctx->stream_res.tg, NULL);
+               /* TODO - convert symclk_ref_cnts for otg to a bit map to solve
+                * the case where the same symclk is shared across multiple otg
+                * instances
+                */
+               link->phy_state.symclk_ref_cnts.otg = 0;
+               if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) {
+                       link_hwss->disable_link_output(link,
+                                       &pipe_ctx->link_res, pipe_ctx->stream->signal);
+                       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (&dc->current_state->res_ctx.pipe_ctx[i] == pipe_ctx)
+                       break;
+
+       if (i == dc->res_pool->pipe_count)
+               return;
+
+       pipe_ctx->stream = NULL;
+       DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
+                                       pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
+}
+
+void dcn20_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* Reset Back End*/
+       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
+               struct pipe_ctx *pipe_ctx_old =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe_ctx_old->stream)
+                       continue;
+
+               if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
+                       continue;
+
+               if (!pipe_ctx->stream ||
+                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
+
+                       dcn20_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
+                       if (hws->funcs.enable_stream_gating)
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
+                       if (old_clk)
+                               old_clk->funcs->cs_power_down(old_clk);
+               }
+       }
+}
+
+void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct mpcc_blnd_cfg blnd_cfg = {0};
+       bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha;
+       int mpcc_id;
+       struct mpcc *new_mpcc;
+       struct mpc *mpc = dc->res_pool->mpc;
+       struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
+
+       blnd_cfg.overlap_only = false;
+       blnd_cfg.global_gain = 0xff;
+
+       if (per_pixel_alpha) {
+               blnd_cfg.pre_multiplied_alpha = pipe_ctx->plane_state->pre_multiplied_alpha;
+               if (pipe_ctx->plane_state->global_alpha) {
+                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN;
+                       blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value;
+               } else {
+                       blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
+               }
+       } else {
+               blnd_cfg.pre_multiplied_alpha = false;
+               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
+       }
+
+       if (pipe_ctx->plane_state->global_alpha)
+               blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
+       else
+               blnd_cfg.global_alpha = 0xff;
+
+       blnd_cfg.background_color_bpc = 4;
+       blnd_cfg.bottom_gain_mode = 0;
+       blnd_cfg.top_gain = 0x1f000;
+       blnd_cfg.bottom_inside_gain = 0x1f000;
+       blnd_cfg.bottom_outside_gain = 0x1f000;
+
+       if (pipe_ctx->plane_state->format
+                       == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA)
+               blnd_cfg.pre_multiplied_alpha = false;
+
+       /*
+        * TODO: remove hack
+        * Note: currently there is a bug in init_hw such that
+        * on resume from hibernate, BIOS sets up MPCC0, and
+        * we do mpcc_remove but the mpcc cannot go to idle
+        * after remove. This cause us to pick mpcc1 here,
+        * which causes a pstate hang for yet unknown reason.
+        */
+       mpcc_id = hubp->inst;
+
+       /* If there is no full update, don't need to touch MPC tree*/
+       if (!pipe_ctx->plane_state->update_flags.bits.full_update &&
+               !pipe_ctx->update_flags.bits.mpcc) {
+               mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
+               dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
+               return;
+       }
+
+       /* check if this MPCC is already being used */
+       new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
+       /* remove MPCC if being used */
+       if (new_mpcc != NULL)
+               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, new_mpcc);
+       else
+               if (dc->debug.sanity_checks)
+                       mpc->funcs->assert_mpcc_idle_before_connect(
+                                       dc->res_pool->mpc, mpcc_id);
+
+       /* Call MPC to insert new plane */
+       new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
+                       mpc_tree_params,
+                       &blnd_cfg,
+                       NULL,
+                       NULL,
+                       hubp->inst,
+                       mpcc_id);
+       dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
+
+       ASSERT(new_mpcc != NULL);
+       hubp->opp_id = pipe_ctx->stream_res.opp->inst;
+       hubp->mpcc_id = mpcc_id;
+}
+
+void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
+{
+       enum dc_lane_count lane_count =
+               pipe_ctx->stream->link->cur_link_settings.lane_count;
+
+       struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+       struct dc_link *link = pipe_ctx->stream->link;
+
+       uint32_t active_total_with_borders;
+       uint32_t early_control = 0;
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
+       struct dtbclk_dto_params dto_params = {0};
+       struct dccg *dccg = dc->res_pool->dccg;
+       enum phyd32clk_clock_source phyd32clk;
+       int dp_hpo_inst;
+       struct dce_hwseq *hws = dc->hwseq;
+       unsigned int k1_div = PIXEL_RATE_DIV_NA;
+       unsigned int k2_div = PIXEL_RATE_DIV_NA;
+
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               if (dc->hwseq->funcs.setup_hpo_hw_control)
+                       dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
+       }
+
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
+               dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
+
+               phyd32clk = get_phyd32clk_src(link);
+               dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+
+               dto_params.otg_inst = tg->inst;
+               dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
+               dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
+               dto_params.timing = &pipe_ctx->stream->timing;
+               dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
+               dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+       }
+       if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
+               hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
+
+               dc->res_pool->dccg->funcs->set_pixel_rate_div(
+                       dc->res_pool->dccg,
+                       pipe_ctx->stream_res.tg->inst,
+                       k1_div, k2_div);
+       }
+
+       link_hwss->setup_stream_encoder(pipe_ctx);
+
+       if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
+               if (dc->hwss.program_dmdata_engine)
+                       dc->hwss.program_dmdata_engine(pipe_ctx);
+       }
+
+       dc->hwss.update_info_frame(pipe_ctx);
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal))
+               dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
+
+       /* enable early control to avoid corruption on DP monitor*/
+       active_total_with_borders =
+                       timing->h_addressable
+                               + timing->h_border_left
+                               + timing->h_border_right;
+
+       if (lane_count != 0)
+               early_control = active_total_with_borders % lane_count;
+
+       if (early_control == 0)
+               early_control = lane_count;
+
+       tg->funcs->set_early_control(tg, early_control);
+
+       if (dc->hwseq->funcs.set_pixels_per_cycle)
+               dc->hwseq->funcs.set_pixels_per_cycle(pipe_ctx);
+}
+
+void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_stream_state    *stream     = pipe_ctx->stream;
+       struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
+       bool                       enable     = false;
+       struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
+       enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
+                                                       ? dmdata_dp
+                                                       : dmdata_hdmi;
+
+       /* if using dynamic meta, don't set up generic infopackets */
+       if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
+               pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
+               enable = true;
+       }
+
+       if (!hubp)
+               return;
+
+       if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
+               return;
+
+       stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
+                                               hubp->inst, mode);
+}
+
+void dcn20_fpga_init_hw(struct dc *dc)
+{
+       int i, j;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct resource_pool *res_pool = dc->res_pool;
+       struct dc_state  *context = dc->current_state;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       // Initialize the dccg
+       if (res_pool->dccg->funcs->dccg_init)
+               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       //Enable ability to power gate / don't force power on permanently
+       hws->funcs.enable_power_gating_plane(hws, true);
+
+       // Specific to FPGA dccg and registers
+       REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
+       REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
+
+       hws->funcs.dccg_init(hws);
+
+       REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
+       REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
+       if (REG(REFCLK_CNTL))
+               REG_WRITE(REFCLK_CNTL, 0);
+       //
+
+
+       /* Blank pixel data with OPP DPG */
+       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       dcn20_init_blank(dc, tg);
+       }
+
+       for (i = 0; i < res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       tg->funcs->lock(tg);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct dpp *dpp = res_pool->dpps[i];
+
+               dpp->funcs->dpp_reset(dpp);
+       }
+
+       /* Reset all MPCC muxes */
+       res_pool->mpc->funcs->mpc_init(res_pool->mpc);
+
+       /* initialize OPP mpc_tree parameter */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
+               res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+               for (j = 0; j < MAX_PIPES; j++)
+                       res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = dc->res_pool->hubps[i];
+               struct dpp *dpp = dc->res_pool->dpps[i];
+
+               pipe_ctx->stream_res.tg = tg;
+               pipe_ctx->pipe_idx = i;
+
+               pipe_ctx->plane_res.hubp = hubp;
+               pipe_ctx->plane_res.dpp = dpp;
+               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+               hubp->mpcc_id = dpp->inst;
+               hubp->opp_id = OPP_ID_INVALID;
+               hubp->power_gated = false;
+               pipe_ctx->stream_res.opp = NULL;
+
+               hubp->funcs->hubp_init(hubp);
+
+               //dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+               //dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+               dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+               pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
+               /*to do*/
+               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
+       }
+
+       /* initialize DWB pointer to MCIF_WB */
+       for (i = 0; i < res_pool->res_cap->num_dwb; i++)
+               res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
+
+       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       tg->funcs->unlock(tg);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               dc->hwss.disable_plane(dc, pipe_ctx);
+
+               pipe_ctx->stream_res.tg = NULL;
+               pipe_ctx->plane_res.hubp = NULL;
+       }
+
+       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+               tg->funcs->tg_init(tg);
+       }
+
+       if (dc->res_pool->hubbub->funcs->init_crb)
+               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+}
+
+void dcn20_set_disp_pattern_generator(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum controller_dp_test_pattern test_pattern,
+               enum controller_dp_color_space color_space,
+               enum dc_color_depth color_depth,
+               const struct tg_color *solid_color,
+               int width, int height, int offset)
+{
+       pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern,
+                       color_space, color_depth, solid_color, width, height, offset);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h
new file mode 100644 (file)
index 0000000..ab02e4e
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+* 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 __DC_HWSS_DCN20_H__
+#define __DC_HWSS_DCN20_H__
+
+#include "hw_sequencer_private.h"
+
+bool dcn20_set_blend_lut(
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
+bool dcn20_set_shaper_3dlut(
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
+void dcn20_program_front_end_for_ctx(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn20_post_unlock_program_front_end(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
+bool dcn20_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                       const struct dc_plane_state *plane_state);
+bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                       const struct dc_stream_state *stream);
+void dcn20_program_output_csc(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum dc_color_space colorspace,
+               uint16_t *matrix,
+               int opp_id);
+void dcn20_enable_stream(struct pipe_ctx *pipe_ctx);
+void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings);
+void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn20_disable_pixel_data(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool blank);
+void dcn20_blank_pixel_data(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool blank);
+void dcn20_pipe_control_lock(
+       struct dc *dc,
+       struct pipe_ctx *pipe,
+       bool lock);
+void dcn20_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn20_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+bool dcn20_update_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+void dcn20_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context);
+enum dc_status dcn20_enable_stream_timing(
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context,
+               struct dc *dc);
+void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn20_init_blank(
+               struct dc *dc,
+               struct timing_generator *tg);
+void dcn20_disable_vga(
+       struct dce_hwseq *hws);
+void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn20_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable);
+void dcn20_dpp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dpp_inst,
+               bool power_on);
+void dcn20_hubp_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int hubp_inst,
+               bool power_on);
+void dcn20_program_triple_buffer(
+       const struct dc *dc,
+       struct pipe_ctx *pipe_ctx,
+       bool enable_triple_buffer);
+void dcn20_enable_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context);
+void dcn20_disable_writeback(
+               struct dc *dc,
+               unsigned int dwb_pipe_inst);
+void dcn20_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
+bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx);
+void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx);
+void dcn20_set_dmdata_attributes(struct pipe_ctx *pipe_ctx);
+void dcn20_init_vm_ctx(
+               struct dce_hwseq *hws,
+               struct dc *dc,
+               struct dc_virtual_addr_space_config *va_config,
+               int vmid);
+void dcn20_set_flip_control_gsl(
+               struct pipe_ctx *pipe_ctx,
+               bool flip_immediate);
+void dcn20_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on);
+void dcn20_fpga_init_hw(struct dc *dc);
+bool dcn20_wait_for_blank_complete(
+               struct output_pixel_processor *opp);
+void dcn20_dccg_init(struct dce_hwseq *hws);
+int dcn20_init_sys_ctx(struct dce_hwseq *hws,
+               struct dc *dc,
+               struct dc_phy_addr_space_config *pa_config);
+
+void dcn20_set_disp_pattern_generator(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum controller_dp_test_pattern test_pattern,
+               enum controller_dp_color_space color_space,
+               enum dc_color_depth color_depth,
+               const struct tg_color *solid_color,
+               int width, int height, int offset);
+
+void dcn20_setup_gsl_group_as_lock(
+               const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool enable);
+
+#endif /* __DC_HWSS_DCN20_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
new file mode 100644 (file)
index 0000000..d3fe609
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+ * 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 "dm_services.h"
+#include "basics/dc_common.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dcn201_hwseq.h"
+#include "dcn201/dcn201_optc.h"
+#include "dce/dce_hwseq.h"
+#include "hubp.h"
+#include "dchubbub.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "dccg.h"
+#include "clk_mgr.h"
+#include "reg_helper.h"
+
+#define CTX \
+       hws->ctx
+
+#define REG(reg)\
+       hws->regs->reg
+
+#define DC_LOGGER \
+       dc->ctx->logger
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+
+static bool patch_address_for_sbs_tb_stereo(
+               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
+{
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       bool sec_split = pipe_ctx->top_pipe &&
+               pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
+
+       if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+               (pipe_ctx->stream->timing.timing_3d_format ==
+                       TIMING_3D_FORMAT_SIDE_BY_SIDE ||
+               pipe_ctx->stream->timing.timing_3d_format ==
+                       TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
+               *addr = plane_state->address.grph_stereo.left_addr;
+               plane_state->address.grph_stereo.left_addr =
+                       plane_state->address.grph_stereo.right_addr;
+               return true;
+       } else {
+               if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
+                       plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
+                       plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
+                       plane_state->address.grph_stereo.right_addr =
+                       plane_state->address.grph_stereo.left_addr;
+                       plane_state->address.grph_stereo.right_meta_addr =
+                       plane_state->address.grph_stereo.left_meta_addr;
+               }
+       }
+       return false;
+}
+
+static bool gpu_addr_to_uma(struct dce_hwseq *hwseq,
+               PHYSICAL_ADDRESS_LOC *addr)
+{
+       bool is_in_uma;
+
+       if (hwseq->fb_base.quad_part <= addr->quad_part &&
+                       addr->quad_part < hwseq->fb_top.quad_part) {
+               addr->quad_part -= hwseq->fb_base.quad_part;
+               addr->quad_part += hwseq->fb_offset.quad_part;
+               is_in_uma = true;
+       } else if (hwseq->fb_offset.quad_part <= addr->quad_part &&
+                       addr->quad_part <= hwseq->uma_top.quad_part) {
+               is_in_uma = true;
+       } else {
+               is_in_uma = false;
+       }
+       return is_in_uma;
+}
+
+static void plane_address_in_gpu_space_to_uma(struct dce_hwseq *hwseq,
+               struct dc_plane_address *addr)
+{
+       switch (addr->type) {
+       case PLN_ADDR_TYPE_GRAPHICS:
+               gpu_addr_to_uma(hwseq, &addr->grph.addr);
+               gpu_addr_to_uma(hwseq, &addr->grph.meta_addr);
+               break;
+       case PLN_ADDR_TYPE_GRPH_STEREO:
+               gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_addr);
+               gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_meta_addr);
+               gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_addr);
+               gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_meta_addr);
+               break;
+       case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
+               gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_addr);
+               gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_meta_addr);
+               gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_addr);
+               gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_meta_addr);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       bool addr_patched = false;
+       PHYSICAL_ADDRESS_LOC addr;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_plane_address uma;
+
+       if (plane_state == NULL)
+               return;
+
+       uma = plane_state->address;
+       addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
+
+       plane_address_in_gpu_space_to_uma(hws, &uma);
+
+       pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
+                       pipe_ctx->plane_res.hubp,
+                       &uma,
+                       plane_state->flip_immediate);
+
+       plane_state->status.requested_address = plane_state->address;
+
+       if (plane_state->flip_immediate)
+               plane_state->status.current_address = plane_state->address;
+
+       if (addr_patched)
+               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
+}
+
+/* Blank pixel data during initialization */
+void dcn201_init_blank(
+               struct dc *dc,
+               struct timing_generator *tg)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       enum dc_color_space color_space;
+       struct tg_color black_color = {0};
+       struct output_pixel_processor *opp = NULL;
+       uint32_t num_opps, opp_id_src0, opp_id_src1;
+       uint32_t otg_active_width, otg_active_height;
+
+       /* program opp dpg blank color */
+       color_space = COLOR_SPACE_SRGB;
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       /* get the OTG active size */
+       tg->funcs->get_otg_active_size(tg,
+                       &otg_active_width,
+                       &otg_active_height);
+
+       /* get the OPTC source */
+       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+       ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
+       opp = dc->res_pool->opps[opp_id_src0];
+
+       opp->funcs->opp_set_disp_pattern_generator(
+                       opp,
+                       CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+                       CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+                       COLOR_DEPTH_UNDEFINED,
+                       &black_color,
+                       otg_active_width,
+                       otg_active_height,
+                       0);
+
+       hws->funcs.wait_for_blank_complete(opp);
+}
+
+static void read_mmhub_vm_setup(struct dce_hwseq *hws)
+{
+       uint32_t fb_base = REG_READ(MC_VM_FB_LOCATION_BASE);
+       uint32_t fb_top = REG_READ(MC_VM_FB_LOCATION_TOP);
+       uint32_t fb_offset = REG_READ(MC_VM_FB_OFFSET);
+
+       /* MC_VM_FB_LOCATION_TOP is in pages, actual top should add 1 */
+       fb_top++;
+
+       /* bit 23:0 in register map to bit 47:24 in address */
+       hws->fb_base.low_part = fb_base;
+       hws->fb_base.quad_part <<= 24;
+
+       hws->fb_top.low_part  = fb_top;
+       hws->fb_top.quad_part <<= 24;
+       hws->fb_offset.low_part = fb_offset;
+       hws->fb_offset.quad_part <<= 24;
+
+       hws->uma_top.quad_part = hws->fb_top.quad_part
+                       - hws->fb_base.quad_part + hws->fb_offset.quad_part;
+}
+
+void dcn201_init_hw(struct dc *dc)
+{
+       int i, j;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct resource_pool *res_pool = dc->res_pool;
+       struct dc_state  *context = dc->current_state;
+
+       if (res_pool->dccg->funcs->dccg_init)
+               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       hws->funcs.bios_golden_init(dc);
+
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (res_pool->dccg && res_pool->hubbub) {
+                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+               } else {
+                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+               }
+       } else
+               ASSERT_CRITICAL(false);
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+       }
+       if (hws->fb_offset.quad_part == 0)
+               read_mmhub_vm_setup(hws);
+
+       /* Blank pixel data with OPP DPG */
+       for (i = 0; i < res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = res_pool->timing_generators[i];
+
+               if (tg->funcs->is_tg_enabled(tg)) {
+                       dcn201_init_blank(dc, tg);
+               }
+       }
+
+       for (i = 0; i < res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = res_pool->timing_generators[i];
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       tg->funcs->lock(tg);
+       }
+
+       for (i = 0; i < res_pool->pipe_count; i++) {
+               struct dpp *dpp = res_pool->dpps[i];
+
+               dpp->funcs->dpp_reset(dpp);
+       }
+
+       /* Reset all MPCC muxes */
+       res_pool->mpc->funcs->mpc_init(res_pool->mpc);
+
+       /* initialize OPP mpc_tree parameter */
+       for (i = 0; i < res_pool->res_cap->num_opp; i++) {
+               res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
+               res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+               for (j = 0; j < MAX_PIPES; j++)
+                       res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
+       }
+
+       for (i = 0; i < res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = res_pool->timing_generators[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = res_pool->hubps[i];
+               struct dpp *dpp = res_pool->dpps[i];
+
+               pipe_ctx->stream_res.tg = tg;
+               pipe_ctx->pipe_idx = i;
+
+               pipe_ctx->plane_res.hubp = hubp;
+               pipe_ctx->plane_res.dpp = dpp;
+               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+               hubp->mpcc_id = dpp->inst;
+               hubp->opp_id = OPP_ID_INVALID;
+               hubp->power_gated = false;
+               pipe_ctx->stream_res.opp = NULL;
+
+               hubp->funcs->hubp_init(hubp);
+
+               res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+               pipe_ctx->stream_res.opp = res_pool->opps[i];
+               /*To do: number of MPCC != number of opp*/
+               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
+       }
+
+       /* initialize DWB pointer to MCIF_WB */
+       for (i = 0; i < res_pool->res_cap->num_dwb; i++)
+               res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
+
+       for (i = 0; i < res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = res_pool->timing_generators[i];
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       tg->funcs->unlock(tg);
+       }
+
+       for (i = 0; i < res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               dc->hwss.disable_plane(dc, pipe_ctx);
+
+               pipe_ctx->stream_res.tg = NULL;
+               pipe_ctx->plane_res.hubp = NULL;
+       }
+
+       for (i = 0; i < res_pool->timing_generator_count; i++) {
+               struct timing_generator *tg = res_pool->timing_generators[i];
+
+               tg->funcs->tg_init(tg);
+       }
+
+       for (i = 0; i < res_pool->audio_count; i++) {
+               struct audio *audio = res_pool->audios[i];
+
+               audio->funcs->hw_init(audio);
+       }
+
+       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
+       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+       if (!dc->debug.disable_clock_gate) {
+               /* enable all DCN clock gating */
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+       }
+}
+
+/* trigger HW to start disconnect plane from stream on the next vsync */
+void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       int dpp_id = pipe_ctx->plane_res.dpp->inst;
+       struct mpc *mpc = dc->res_pool->mpc;
+       struct mpc_tree *mpc_tree_params;
+       struct mpcc *mpcc_to_remove = NULL;
+       struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
+       bool mpcc_removed = false;
+
+       mpc_tree_params = &(opp->mpc_tree_params);
+
+       /* check if this plane is being used by an MPCC in the secondary blending chain */
+       if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
+               mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
+
+       /* remove MPCC from secondary if being used */
+       if (mpcc_to_remove != NULL && mpc->funcs->remove_mpcc_from_secondary) {
+               mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove);
+               mpcc_removed = true;
+       }
+
+       /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
+       mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
+       if (mpcc_to_remove != NULL) {
+               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
+               mpcc_removed = true;
+       }
+
+       /*Already reset*/
+       if (mpcc_removed == false)
+               return;
+
+       if (opp != NULL)
+               opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+
+       dc->optimized_required = true;
+
+       if (hubp->funcs->hubp_disconnect)
+               hubp->funcs->hubp_disconnect(hubp);
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+}
+
+void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct mpcc_blnd_cfg blnd_cfg;
+       bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
+       int mpcc_id, dpp_id;
+       struct mpcc *new_mpcc;
+       struct mpcc *remove_mpcc = NULL;
+       struct mpc *mpc = dc->res_pool->mpc;
+       struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
+
+       if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
+               get_hdr_visual_confirm_color(
+                               pipe_ctx, &blnd_cfg.black_color);
+       } else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
+               get_surface_visual_confirm_color(
+                               pipe_ctx, &blnd_cfg.black_color);
+       } else {
+               color_space_to_black_color(
+                               dc, pipe_ctx->stream->output_color_space,
+                               &blnd_cfg.black_color);
+       }
+
+       if (per_pixel_alpha)
+               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
+       else
+               blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
+
+       blnd_cfg.overlap_only = false;
+
+       if (pipe_ctx->plane_state->global_alpha_value)
+               blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
+       else
+               blnd_cfg.global_alpha = 0xff;
+
+       blnd_cfg.global_gain = 0xff;
+       blnd_cfg.background_color_bpc = 4;
+       blnd_cfg.bottom_gain_mode = 0;
+       blnd_cfg.top_gain = 0x1f000;
+       blnd_cfg.bottom_inside_gain = 0x1f000;
+       blnd_cfg.bottom_outside_gain = 0x1f000;
+       /*the input to MPCC is RGB*/
+       blnd_cfg.black_color.color_b_cb = 0;
+       blnd_cfg.black_color.color_g_y = 0;
+       blnd_cfg.black_color.color_r_cr = 0;
+
+       /* DCN1.0 has output CM before MPC which seems to screw with
+        * pre-multiplied alpha. This is a w/a hopefully unnecessary for DCN2.
+        */
+       blnd_cfg.pre_multiplied_alpha = per_pixel_alpha;
+
+       /*
+        * TODO: remove hack
+        * Note: currently there is a bug in init_hw such that
+        * on resume from hibernate, BIOS sets up MPCC0, and
+        * we do mpcc_remove but the mpcc cannot go to idle
+        * after remove. This cause us to pick mpcc1 here,
+        * which causes a pstate hang for yet unknown reason.
+        */
+       dpp_id = hubp->inst;
+       mpcc_id = dpp_id;
+
+       /* If there is no full update, don't need to touch MPC tree*/
+       if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
+               dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
+               mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
+               return;
+       }
+
+       /* check if this plane is being used by an MPCC in the secondary blending chain */
+       if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
+               remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
+
+       /* remove MPCC from secondary if being used */
+       if (remove_mpcc != NULL && mpc->funcs->remove_mpcc_from_secondary)
+               mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc);
+
+       /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
+       remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
+       /* remove MPCC if being used */
+
+       if (remove_mpcc != NULL)
+               mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc);
+       else
+               if (dc->debug.sanity_checks)
+                       mpc->funcs->assert_mpcc_idle_before_connect(
+                                       dc->res_pool->mpc, mpcc_id);
+
+       /* Call MPC to insert new plane */
+       dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
+       new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
+                       mpc_tree_params,
+                       &blnd_cfg,
+                       NULL,
+                       NULL,
+                       dpp_id,
+                       mpcc_id);
+
+       ASSERT(new_mpcc != NULL);
+       hubp->opp_id = pipe_ctx->stream_res.opp->inst;
+       hubp->mpcc_id = mpcc_id;
+}
+
+void dcn201_pipe_control_lock(
+       struct dc *dc,
+       struct pipe_ctx *pipe,
+       bool lock)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       /* use TG master update lock to lock everything on the TG
+        * therefore only top pipe need to lock
+        */
+       if (pipe->top_pipe)
+               return;
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+
+       if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
+               if (lock)
+                       pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
+               else
+                       pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
+       } else {
+               if (lock)
+                       pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
+               else
+                       pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
+       }
+
+       if (dc->debug.sanity_checks)
+               hws->funcs.verify_allow_pstate_change_high(dc);
+}
+
+void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+       gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, &attributes->address);
+
+       pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+                       pipe_ctx->plane_res.hubp, attributes);
+       pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+               pipe_ctx->plane_res.dpp, attributes);
+}
+
+void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_dmdata_attributes attr = { 0 };
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+
+       gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq,
+                       &pipe_ctx->stream->dmdata_address);
+
+       attr.dmdata_mode = DMDATA_HW_MODE;
+       attr.dmdata_size =
+               dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;
+       attr.address.quad_part =
+                       pipe_ctx->stream->dmdata_address.quad_part;
+       attr.dmdata_dl_delta = 0;
+       attr.dmdata_qos_mode = 0;
+       attr.dmdata_qos_level = 0;
+       attr.dmdata_repeat = 1; /* always repeat */
+       attr.dmdata_updated = 1;
+       attr.dmdata_sw_data = NULL;
+
+       hubp->funcs->dmdata_set_attributes(hubp, &attr);
+}
+
+void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings)
+{
+       struct encoder_unblank_param params = { { 0 } };
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dce_hwseq *hws = link->dc->hwseq;
+
+       /* only 3 items below are used by unblank */
+       params.timing = pipe_ctx->stream->timing;
+
+       params.link_settings.link_rate = link_settings->link_rate;
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               /*check whether it is half the rate*/
+               if (optc201_is_two_pixels_per_containter(&stream->timing))
+                       params.timing.pix_clk_100hz /= 2;
+
+               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
+       }
+
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+               hws->funcs.edp_backlight_control(link, true);
+       }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h
new file mode 100644 (file)
index 0000000..26cd62b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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_HWSS_DCN201_H__
+#define __DC_HWSS_DCN201_H__
+
+#include "hw_sequencer_private.h"
+
+void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx);
+void dcn201_init_hw(struct dc *dc);
+void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings);
+void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
+void dcn201_pipe_control_lock(
+       struct dc *dc,
+       struct pipe_ctx *pipe,
+       bool lock);
+void dcn201_init_blank(
+               struct dc *dc,
+               struct timing_generator *tg);
+#endif /* __DC_HWSS_DCN201_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
new file mode 100644 (file)
index 0000000..467812c
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * 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 "dm_services.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dce/dce_hwseq.h"
+#include "dce110/dce110_hwseq.h"
+#include "dcn21_hwseq.h"
+#include "vmid.h"
+#include "reg_helper.h"
+#include "hw/clk_mgr.h"
+#include "dc_dmub_srv.h"
+#include "abm.h"
+#include "link.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#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
+
+/* Temporary read settings, future will get values from kmd directly */
+static void mmhub_update_page_table_config(struct dcn_hubbub_phys_addr_config *config,
+               struct dce_hwseq *hws)
+{
+       uint32_t page_table_base_hi;
+       uint32_t page_table_base_lo;
+
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
+                       PAGE_DIRECTORY_ENTRY_HI32, &page_table_base_hi);
+       REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
+                       PAGE_DIRECTORY_ENTRY_LO32, &page_table_base_lo);
+
+       config->gart_config.page_table_base_addr = ((uint64_t)page_table_base_hi << 32) | page_table_base_lo;
+
+}
+
+int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
+{
+       struct dcn_hubbub_phys_addr_config config;
+
+       config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
+       config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
+       config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
+       config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
+       config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
+       config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
+       config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
+       config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
+       config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
+
+       mmhub_update_page_table_config(&config, hws);
+
+       return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
+}
+
+// work around for Renoir s0i3, if register is programmed, bypass golden init.
+
+bool dcn21_s0i3_golden_init_wa(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       uint32_t value = 0;
+
+       value = REG_READ(MICROSECOND_TIME_BASE_DIV);
+
+       return value != 0x00120464;
+}
+
+void dcn21_exit_optimized_pwr_state(
+               const struct dc *dc,
+               struct dc_state *context)
+{
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       false);
+}
+
+void dcn21_optimize_pwr_state(
+               const struct dc *dc,
+               struct dc_state *context)
+{
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       context,
+                       true);
+}
+
+/* If user hotplug a HDMI monitor while in monitor off,
+ * OS will do a mode set (with output timing) but keep output off.
+ * In this case DAL will ask vbios to power up the pll in the PHY.
+ * If user unplug the monitor (while we are on monitor off) or
+ * system attempt to enter modern standby (which we will disable PLL),
+ * PHY will hang on the next mode set attempt.
+ * if enable PLL follow by disable PLL (without executing lane enable/disable),
+ * RDPCS_PHY_DP_MPLLB_STATE remains 1,
+ * which indicate that PLL disable attempt actually didn't go through.
+ * As a workaround, insert PHY lane enable/disable before PLL disable.
+ */
+void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx)
+{
+       if (!pipe_ctx->stream->dpms_off)
+               return;
+
+       pipe_ctx->stream->dpms_off = false;
+       pipe_ctx->stream->ctx->dc->link_srv->set_dpms_on(context, pipe_ctx);
+       pipe_ctx->stream->ctx->dc->link_srv->set_dpms_off(pipe_ctx);
+       pipe_ctx->stream->dpms_off = true;
+}
+
+static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst)
+{
+       union dmub_rb_cmd cmd;
+       struct dc_context *dc = abm->ctx;
+       uint32_t ramping_boundary = 0xFFFF;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
+       cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE;
+       cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst;
+       cmd.abm_set_pipe.abm_set_pipe_data.set_pipe_option = option;
+       cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst;
+       cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
+       cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
+
+       dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+
+       return true;
+}
+
+static void dmub_abm_set_backlight(struct dc_context *dc, uint32_t backlight_pwm_u16_16,
+                                                                       uint32_t frame_ramp, uint32_t panel_inst)
+{
+       union dmub_rb_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.abm_set_backlight.header.type = DMUB_CMD__ABM;
+       cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT;
+       cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp;
+       cmd.abm_set_backlight.abm_set_backlight_data.backlight_user_level = backlight_pwm_u16_16;
+       cmd.abm_set_backlight.abm_set_backlight_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
+       cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst);
+       cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
+
+       dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
+void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
+{
+       struct abm *abm = pipe_ctx->stream_res.abm;
+       uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
+       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
+
+       struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
+
+       if (dmcu) {
+               dce110_set_abm_immediate_disable(pipe_ctx);
+               return;
+       }
+
+       if (abm && panel_cntl) {
+               if (abm->funcs && abm->funcs->set_pipe_ex) {
+                       abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE,
+                       panel_cntl->inst);
+               } else {
+                       dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE, panel_cntl->inst);
+               }
+               panel_cntl->funcs->store_backlight_level(panel_cntl);
+       }
+}
+
+void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
+{
+       struct abm *abm = pipe_ctx->stream_res.abm;
+       uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
+       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
+       struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
+
+       if (dmcu) {
+               dce110_set_pipe(pipe_ctx);
+               return;
+       }
+
+       if (abm && panel_cntl) {
+               if (abm->funcs && abm->funcs->set_pipe_ex) {
+                       abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+               } else {
+                       dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+               }
+       }
+}
+
+bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
+               uint32_t backlight_pwm_u16_16,
+               uint32_t frame_ramp)
+{
+       struct dc_context *dc = pipe_ctx->stream->ctx;
+       struct abm *abm = pipe_ctx->stream_res.abm;
+       struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
+
+       if (dc->dc->res_pool->dmcu) {
+               dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp);
+               return true;
+       }
+
+       if (abm != NULL) {
+               uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
+
+               if (abm && panel_cntl) {
+                       if (abm->funcs && abm->funcs->set_pipe_ex) {
+                               abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+                       } else {
+                               dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+                       }
+               }
+       }
+
+       if (abm && abm->funcs && abm->funcs->set_backlight_level_pwm)
+               abm->funcs->set_backlight_level_pwm(abm, backlight_pwm_u16_16,
+                       frame_ramp, 0, panel_cntl->inst);
+       else
+               dmub_abm_set_backlight(dc, backlight_pwm_u16_16, frame_ramp, panel_cntl->inst);
+
+       return true;
+}
+
+bool dcn21_is_abm_supported(struct dc *dc,
+               struct dc_state *context, struct dc_stream_state *stream)
+{
+       int i;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream == stream &&
+                               (pipe_ctx->prev_odm_pipe == NULL && pipe_ctx->next_odm_pipe == NULL))
+                       return true;
+       }
+       return false;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.h
new file mode 100644 (file)
index 0000000..9cee9bd
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+* 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 __DC_HWSS_DCN21_H__
+#define __DC_HWSS_DCN21_H__
+
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+int dcn21_init_sys_ctx(struct dce_hwseq *hws,
+               struct dc *dc,
+               struct dc_phy_addr_space_config *pa_config);
+
+bool dcn21_s0i3_golden_init_wa(struct dc *dc);
+
+void dcn21_exit_optimized_pwr_state(
+               const struct dc *dc,
+               struct dc_state *context);
+
+void dcn21_optimize_pwr_state(
+               const struct dc *dc,
+               struct dc_state *context);
+
+void dcn21_PLAT_58856_wa(struct dc_state *context,
+               struct pipe_ctx *pipe_ctx);
+
+void dcn21_set_pipe(struct pipe_ctx *pipe_ctx);
+void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
+bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
+               uint32_t backlight_pwm_u16_16,
+               uint32_t frame_ramp);
+bool dcn21_is_abm_supported(struct dc *dc,
+               struct dc_state *context, struct dc_stream_state *stream);
+
+#endif /* __DC_HWSS_DCN21_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
new file mode 100644 (file)
index 0000000..9247a8e
--- /dev/null
@@ -0,0 +1,1047 @@
+/*
+ * Copyright 2020 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 "dm_services.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dcn30_hwseq.h"
+#include "dccg.h"
+#include "dce/dce_hwseq.h"
+#include "dcn30/dcn30_mpc.h"
+#include "dcn30/dcn30_dpp.h"
+#include "dcn10/dcn10_cm_common.h"
+#include "dcn30/dcn30_cm_common.h"
+#include "reg_helper.h"
+#include "abm.h"
+#include "clk_mgr.h"
+#include "hubp.h"
+#include "dchubbub.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "mcif_wb.h"
+#include "dc_dmub_srv.h"
+#include "link_hwss.h"
+#include "dpcd_defs.h"
+#include "dcn20/dcn20_hwseq.h"
+#include "dcn30/dcn30_resource.h"
+#include "link.h"
+
+
+
+
+#define DC_LOGGER_INIT(logger)
+
+#define CTX \
+       hws->ctx
+#define REG(reg)\
+       hws->regs->reg
+#define DC_LOGGER \
+               dc->ctx->logger
+
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+
+bool dcn30_set_blend_lut(
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       bool result = true;
+       struct pwl_params *blend_lut = NULL;
+
+       if (plane_state->blend_tf) {
+               if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
+                       blend_lut = &plane_state->blend_tf->pwl;
+               else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm3_helper_translate_curve_to_hw_format(
+                                       plane_state->blend_tf, &dpp_base->regamma_params, false);
+                       blend_lut = &dpp_base->regamma_params;
+               }
+       }
+       result = dpp_base->funcs->dpp_program_blnd_lut(dpp_base, blend_lut);
+
+       return result;
+}
+
+static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
+                                      const struct dc_stream_state *stream)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+       bool result = false;
+       int acquired_rmu = 0;
+       int mpcc_id_projected = 0;
+
+       const struct pwl_params *shaper_lut = NULL;
+       //get the shaper lut params
+       if (stream->func_shaper) {
+               if (stream->func_shaper->type == TF_TYPE_HWPWL) {
+                       shaper_lut = &stream->func_shaper->pwl;
+               } else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm_helper_translate_curve_to_hw_format(stream->ctx, stream->func_shaper,
+                                                              &dpp_base->shaper_params, true);
+                       shaper_lut = &dpp_base->shaper_params;
+               }
+       }
+
+       if (stream->lut3d_func &&
+           stream->lut3d_func->state.bits.initialized == 1 &&
+           stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
+               if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
+                       mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux;
+               else if (stream->lut3d_func->state.bits.rmu_mux_num == 1)
+                       mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu1_mux;
+               else if (stream->lut3d_func->state.bits.rmu_mux_num == 2)
+                       mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu2_mux;
+               if (mpcc_id_projected != mpcc_id)
+                       BREAK_TO_DEBUGGER();
+               /* find the reason why logical layer assigned a different
+                * mpcc_id into acquire_post_bldn_3dlut
+                */
+               acquired_rmu = mpc->funcs->acquire_rmu(mpc, mpcc_id,
+                                                      stream->lut3d_func->state.bits.rmu_mux_num);
+               if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
+                       BREAK_TO_DEBUGGER();
+
+               result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
+                                                  stream->lut3d_func->state.bits.rmu_mux_num);
+               result = mpc->funcs->program_shaper(mpc, shaper_lut,
+                                                   stream->lut3d_func->state.bits.rmu_mux_num);
+       } else {
+               // loop through the available mux and release the requested mpcc_id
+               mpc->funcs->release_rmu(mpc, mpcc_id);
+       }
+
+       return result;
+}
+
+bool dcn30_set_input_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       enum dc_transfer_func_predefined tf;
+       bool result = true;
+       struct pwl_params *params = NULL;
+
+       if (dpp_base == NULL || plane_state == NULL)
+               return false;
+
+       tf = TRANSFER_FUNCTION_UNITY;
+
+       if (plane_state->in_transfer_func &&
+               plane_state->in_transfer_func->type == TF_TYPE_PREDEFINED)
+               tf = plane_state->in_transfer_func->tf;
+
+       dpp_base->funcs->dpp_set_pre_degam(dpp_base, tf);
+
+       if (plane_state->in_transfer_func) {
+               if (plane_state->in_transfer_func->type == TF_TYPE_HWPWL)
+                       params = &plane_state->in_transfer_func->pwl;
+               else if (plane_state->in_transfer_func->type == TF_TYPE_DISTRIBUTED_POINTS &&
+                       cm3_helper_translate_curve_to_hw_format(plane_state->in_transfer_func,
+                                       &dpp_base->degamma_params, false))
+                       params = &dpp_base->degamma_params;
+       }
+
+       result = dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
+
+       if (pipe_ctx->stream_res.opp && pipe_ctx->stream_res.opp->ctx) {
+               if (dpp_base->funcs->dpp_program_blnd_lut)
+                       hws->funcs.set_blend_lut(pipe_ctx, plane_state);
+               if (dpp_base->funcs->dpp_program_shaper_lut &&
+                               dpp_base->funcs->dpp_program_3dlut)
+                       hws->funcs.set_shaper_3dlut(pipe_ctx, plane_state);
+       }
+
+       return result;
+}
+
+void dcn30_program_gamut_remap(struct pipe_ctx *pipe_ctx)
+{
+       int i = 0;
+       struct dpp_grph_csc_adjustment dpp_adjust;
+       struct mpc_grph_gamut_adjustment mpc_adjust;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+
+       memset(&dpp_adjust, 0, sizeof(dpp_adjust));
+       dpp_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+       if (pipe_ctx->plane_state &&
+           pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) {
+               dpp_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+               for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+                       dpp_adjust.temperature_matrix[i] =
+                               pipe_ctx->plane_state->gamut_remap_matrix.matrix[i];
+       }
+
+       pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp,
+                                                           &dpp_adjust);
+
+       memset(&mpc_adjust, 0, sizeof(mpc_adjust));
+       mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+       if (pipe_ctx->top_pipe == NULL) {
+               if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
+                       mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+                       for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+                               mpc_adjust.temperature_matrix[i] =
+                                       pipe_ctx->stream->gamut_remap_matrix.matrix[i];
+               }
+       }
+
+       mpc->funcs->set_gamut_remap(mpc, mpcc_id, &mpc_adjust);
+}
+
+bool dcn30_set_output_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream)
+{
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+       struct pwl_params *params = NULL;
+       bool ret = false;
+
+       /* program OGAM or 3DLUT only for the top pipe*/
+       if (pipe_ctx->top_pipe == NULL) {
+               /*program rmu shaper and 3dlut in MPC*/
+               ret = dcn30_set_mpc_shaper_3dlut(pipe_ctx, stream);
+               if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
+                       if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
+                               params = &stream->out_transfer_func->pwl;
+                       else if (pipe_ctx->stream->out_transfer_func->type ==
+                                       TF_TYPE_DISTRIBUTED_POINTS &&
+                                       cm3_helper_translate_curve_to_hw_format(
+                                       stream->out_transfer_func,
+                                       &mpc->blender_params, false))
+                               params = &mpc->blender_params;
+                        /* there are no ROM LUTs in OUTGAM */
+                       if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
+                               BREAK_TO_DEBUGGER();
+               }
+       }
+
+       mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+       return ret;
+}
+
+static void dcn30_set_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context)
+{
+       struct mcif_wb *mcif_wb;
+       struct mcif_buf_params *mcif_buf_params;
+
+       ASSERT(wb_info->dwb_pipe_inst < MAX_DWB_PIPES);
+       ASSERT(wb_info->wb_enabled);
+       ASSERT(wb_info->mpcc_inst >= 0);
+       ASSERT(wb_info->mpcc_inst < dc->res_pool->mpcc_count);
+       mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst];
+       mcif_buf_params = &wb_info->mcif_buf_params;
+
+       /* set DWB MPC mux */
+       dc->res_pool->mpc->funcs->set_dwb_mux(dc->res_pool->mpc,
+                       wb_info->dwb_pipe_inst, wb_info->mpcc_inst);
+       /* set MCIF_WB buffer and arbitration configuration */
+       mcif_wb->funcs->config_mcif_buf(mcif_wb, mcif_buf_params, wb_info->dwb_params.dest_height);
+       mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]);
+}
+
+void dcn30_update_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context)
+{
+       struct dwbc *dwb;
+       dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
+       DC_LOG_DWB("%s dwb_pipe_inst = %d, mpcc_inst = %d",\
+               __func__, wb_info->dwb_pipe_inst,\
+               wb_info->mpcc_inst);
+
+       dcn30_set_writeback(dc, wb_info, context);
+
+       /* update DWB */
+       dwb->funcs->update(dwb, &wb_info->dwb_params);
+}
+
+bool dcn30_mmhubbub_warmup(
+       struct dc *dc,
+       unsigned int num_dwb,
+       struct dc_writeback_info *wb_info)
+{
+       struct dwbc *dwb;
+       struct mcif_wb *mcif_wb;
+       struct mcif_warmup_params warmup_params = {0};
+       unsigned int  i, i_buf;
+       /*make sure there is no active DWB eanbled */
+       for (i = 0; i < num_dwb; i++) {
+               dwb = dc->res_pool->dwbc[wb_info[i].dwb_pipe_inst];
+               if (dwb->dwb_is_efc_transition || dwb->dwb_is_drc) {
+                       /*can not do warmup while any dwb enabled*/
+                       return false;
+               }
+       }
+
+       if (wb_info->mcif_warmup_params.p_vmid == 0)
+               return false;
+
+       /*check whether this is new interface: warmup big buffer once*/
+       if (wb_info->mcif_warmup_params.start_address.quad_part != 0 &&
+               wb_info->mcif_warmup_params.region_size != 0) {
+               /*mmhubbub is shared, so it does not matter which MCIF*/
+               mcif_wb = dc->res_pool->mcif_wb[0];
+               /*warmup a big chunk of VM buffer at once*/
+               warmup_params.start_address.quad_part = wb_info->mcif_warmup_params.start_address.quad_part;
+               warmup_params.address_increment =  wb_info->mcif_warmup_params.region_size;
+               warmup_params.region_size = wb_info->mcif_warmup_params.region_size;
+               warmup_params.p_vmid = wb_info->mcif_warmup_params.p_vmid;
+
+               if (warmup_params.address_increment == 0)
+                       warmup_params.address_increment = dc->dml.soc.vmm_page_size_bytes;
+
+               mcif_wb->funcs->warmup_mcif(mcif_wb, &warmup_params);
+               return true;
+       }
+       /*following is the original: warmup each DWB's mcif buffer*/
+       for (i = 0; i < num_dwb; i++) {
+               dwb = dc->res_pool->dwbc[wb_info[i].dwb_pipe_inst];
+               mcif_wb = dc->res_pool->mcif_wb[wb_info[i].dwb_pipe_inst];
+               /*warmup is for VM mode only*/
+               if (wb_info[i].mcif_buf_params.p_vmid == 0)
+                       return false;
+
+               /* Warmup MCIF_WB */
+               for (i_buf = 0; i_buf < MCIF_BUF_COUNT; i_buf++) {
+                       warmup_params.start_address.quad_part = wb_info[i].mcif_buf_params.luma_address[i_buf];
+                       warmup_params.address_increment = dc->dml.soc.vmm_page_size_bytes;
+                       warmup_params.region_size = wb_info[i].mcif_buf_params.luma_pitch * wb_info[i].dwb_params.dest_height;
+                       warmup_params.p_vmid = wb_info[i].mcif_buf_params.p_vmid;
+                       mcif_wb->funcs->warmup_mcif(mcif_wb, &warmup_params);
+               }
+       }
+       return true;
+}
+
+void dcn30_enable_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context)
+{
+       struct dwbc *dwb;
+       struct mcif_wb *mcif_wb;
+
+       dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
+       mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst];
+
+       DC_LOG_DWB("%s dwb_pipe_inst = %d, mpcc_inst = %d",\
+               __func__, wb_info->dwb_pipe_inst,\
+               wb_info->mpcc_inst);
+
+       /* Warmup interface */
+       dcn30_mmhubbub_warmup(dc, 1, wb_info);
+
+       /* Update writeback pipe */
+       dcn30_set_writeback(dc, wb_info, context);
+
+       /* Enable MCIF_WB */
+       mcif_wb->funcs->enable_mcif(mcif_wb);
+       /* Enable DWB */
+       dwb->funcs->enable(dwb, &wb_info->dwb_params);
+}
+
+void dcn30_disable_writeback(
+               struct dc *dc,
+               unsigned int dwb_pipe_inst)
+{
+       struct dwbc *dwb;
+       struct mcif_wb *mcif_wb;
+
+       ASSERT(dwb_pipe_inst < MAX_DWB_PIPES);
+       dwb = dc->res_pool->dwbc[dwb_pipe_inst];
+       mcif_wb = dc->res_pool->mcif_wb[dwb_pipe_inst];
+       DC_LOG_DWB("%s dwb_pipe_inst = %d",\
+               __func__, dwb_pipe_inst);
+
+       /* disable DWB */
+       dwb->funcs->disable(dwb);
+       /* disable MCIF */
+       mcif_wb->funcs->disable_mcif(mcif_wb);
+       /* disable MPC DWB mux */
+       dc->res_pool->mpc->funcs->disable_dwb_mux(dc->res_pool->mpc, dwb_pipe_inst);
+}
+
+void dcn30_program_all_writeback_pipes_in_tree(
+               struct dc *dc,
+               const struct dc_stream_state *stream,
+               struct dc_state *context)
+{
+       struct dc_writeback_info wb_info;
+       struct dwbc *dwb;
+       struct dc_stream_status *stream_status = NULL;
+       int i_wb, i_pipe, i_stream;
+       DC_LOG_DWB("%s", __func__);
+
+       ASSERT(stream);
+       for (i_stream = 0; i_stream < context->stream_count; i_stream++) {
+               if (context->streams[i_stream] == stream) {
+                       stream_status = &context->stream_status[i_stream];
+                       break;
+               }
+       }
+       ASSERT(stream_status);
+
+       ASSERT(stream->num_wb_info <= dc->res_pool->res_cap->num_dwb);
+       /* For each writeback pipe */
+       for (i_wb = 0; i_wb < stream->num_wb_info; i_wb++) {
+
+               /* copy writeback info to local non-const so mpcc_inst can be set */
+               wb_info = stream->writeback_info[i_wb];
+               if (wb_info.wb_enabled) {
+
+                       /* get the MPCC instance for writeback_source_plane */
+                       wb_info.mpcc_inst = -1;
+                       for (i_pipe = 0; i_pipe < dc->res_pool->pipe_count; i_pipe++) {
+                               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i_pipe];
+
+                               if (!pipe_ctx->plane_state)
+                                       continue;
+
+                               if (pipe_ctx->plane_state == wb_info.writeback_source_plane) {
+                                       wb_info.mpcc_inst = pipe_ctx->plane_res.mpcc_inst;
+                                       break;
+                               }
+                       }
+
+                       if (wb_info.mpcc_inst == -1) {
+                               /* Disable writeback pipe and disconnect from MPCC
+                                * if source plane has been removed
+                                */
+                               dc->hwss.disable_writeback(dc, wb_info.dwb_pipe_inst);
+                               continue;
+                       }
+
+                       ASSERT(wb_info.dwb_pipe_inst < dc->res_pool->res_cap->num_dwb);
+                       dwb = dc->res_pool->dwbc[wb_info.dwb_pipe_inst];
+                       if (dwb->funcs->is_enabled(dwb)) {
+                               /* writeback pipe already enabled, only need to update */
+                               dc->hwss.update_writeback(dc, &wb_info, context);
+                       } else {
+                               /* Enable writeback pipe and connect to MPCC */
+                               dc->hwss.enable_writeback(dc, &wb_info, context);
+                       }
+               } else {
+                       /* Disable writeback pipe and disconnect from MPCC */
+                       dc->hwss.disable_writeback(dc, wb_info.dwb_pipe_inst);
+               }
+       }
+}
+
+void dcn30_init_hw(struct dc *dc)
+{
+       struct abm **abms = dc->res_pool->multiple_abms;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+       struct resource_pool *res_pool = dc->res_pool;
+       int i;
+       int edp_num;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       // Initialize the dccg
+       if (res_pool->dccg->funcs->dccg_init)
+               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       if (!dcb->funcs->is_accelerated_mode(dcb)) {
+               hws->funcs.bios_golden_init(dc);
+               hws->funcs.disable_vga(dc->hwseq);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.dmcu) {
+               // Force ERAM to shutdown if DMCU is not enabled
+               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
+                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
+               }
+       }
+
+       // Set default OPTC memory power states
+       if (dc->debug.enable_mem_low_power.bits.optc) {
+               // Shutdown when unassigned and light sleep in VBLANK
+               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.vga) {
+               // Power down VGA memory
+               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
+       }
+
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (res_pool->dccg && res_pool->hubbub) {
+
+                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+               } else {
+                       // Not all ASICs have DCCG sw component
+                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+               }
+       } else
+               ASSERT_CRITICAL(false);
+
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+
+               /* Check for enabled DIG to identify enabled display */
+               if (link->link_enc->funcs->is_dig_enabled &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
+                       link->link_status.link_active = true;
+                       if (link->link_enc->funcs->fec_is_active &&
+                                       link->link_enc->funcs->fec_is_active(link->link_enc))
+                               link->fec_state = dc_link_fec_enabled;
+               }
+       }
+
+       /* we want to turn off all dp displays before doing detection */
+       dc->link_srv->blank_all_dp_displays(dc);
+
+       if (hws->funcs.enable_power_gating_plane)
+               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
+
+       /* If taking control over from VBIOS, we may want to optimize our first
+        * mode set, so we need to skip powering down pipes until we know which
+        * pipes we want to use.
+        * Otherwise, if taking control is not possible, we need to power
+        * everything down.
+        */
+       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
+               hws->funcs.init_pipes(dc, dc->current_state);
+               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
+                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
+       }
+
+       /* In headless boot cases, DIG may be turned
+        * on which causes HW/SW discrepancies.
+        * To avoid this, power down hardware on boot
+        * if DIG is turned on and seamless boot not enabled
+        */
+       if (!dc->config.seamless_boot_edp_requested) {
+               struct dc_link *edp_links[MAX_NUM_EDP];
+               struct dc_link *edp_link = NULL;
+
+               dc_get_edp_links(dc, edp_links, &edp_num);
+               if (edp_num)
+                       edp_link = edp_links[0];
+               if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
+                               edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                               dc->hwss.edp_backlight_control &&
+                               dc->hwss.power_down &&
+                               dc->hwss.edp_power_control) {
+                       dc->hwss.edp_backlight_control(edp_link, false);
+                       dc->hwss.power_down(dc);
+                       dc->hwss.edp_power_control(edp_link, false);
+               } else {
+                       for (i = 0; i < dc->link_count; i++) {
+                               struct dc_link *link = dc->links[i];
+
+                               if (link->link_enc->funcs->is_dig_enabled &&
+                                               link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
+                                               dc->hwss.power_down) {
+                                       dc->hwss.power_down(dc);
+                                       break;
+                               }
+
+                       }
+               }
+       }
+
+       for (i = 0; i < res_pool->audio_count; i++) {
+               struct audio *audio = res_pool->audios[i];
+
+               audio->funcs->hw_init(audio);
+       }
+
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               if (link->panel_cntl)
+                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (abms[i] != NULL)
+                       abms[i]->funcs->abm_init(abms[i], backlight);
+       }
+
+       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
+       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+       if (!dc->debug.disable_clock_gate) {
+               /* enable all DCN clock gating */
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+       }
+
+       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
+               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
+
+       if (dc->clk_mgr->funcs->notify_wm_ranges)
+               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+       //if softmax is enabled then hardmax will be set by a different call
+       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+               dc->res_pool->hubbub->funcs->force_pstate_change_control(
+                               dc->res_pool->hubbub, false, false);
+       if (dc->res_pool->hubbub->funcs->init_crb)
+               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+
+       // Get DMCUB capabilities
+       dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
+       dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
+       dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
+}
+
+void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
+{
+       if (pipe_ctx == NULL)
+               return;
+
+       if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL)
+               pipe_ctx->stream_res.stream_enc->funcs->set_avmute(
+                               pipe_ctx->stream_res.stream_enc,
+                               enable);
+}
+
+void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx)
+{
+       bool is_hdmi_tmds;
+       bool is_dp;
+
+       ASSERT(pipe_ctx->stream);
+
+       if (pipe_ctx->stream_res.stream_enc == NULL)
+               return;  /* this is not root pipe */
+
+       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
+       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
+
+       if (!is_hdmi_tmds && !is_dp)
+               return;
+
+       if (is_hdmi_tmds)
+               pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
+                       pipe_ctx->stream_res.stream_enc,
+                       &pipe_ctx->stream_res.encoder_info_frame);
+       else {
+               if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)
+                       pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(
+                               pipe_ctx->stream_res.stream_enc,
+                               &pipe_ctx->stream_res.encoder_info_frame);
+
+               pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
+                       pipe_ctx->stream_res.stream_enc,
+                       &pipe_ctx->stream_res.encoder_info_frame);
+       }
+}
+
+void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_stream_state    *stream     = pipe_ctx->stream;
+       struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
+       bool                       enable     = false;
+       struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
+       enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
+                                                       ? dmdata_dp
+                                                       : dmdata_hdmi;
+
+       /* if using dynamic meta, don't set up generic infopackets */
+       if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
+               pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
+               enable = true;
+       }
+
+       if (!hubp)
+               return;
+
+       if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
+               return;
+
+       stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
+                                                       hubp->inst, mode);
+}
+
+bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+{
+       union dmub_rb_cmd cmd;
+       uint32_t tmr_delay = 0, tmr_scale = 0;
+       struct dc_cursor_attributes cursor_attr;
+       bool cursor_cache_enable = false;
+       struct dc_stream_state *stream = NULL;
+       struct dc_plane_state *plane = NULL;
+
+       if (!dc->ctx->dmub_srv)
+               return false;
+
+       if (enable) {
+               if (dc->current_state) {
+                       int i;
+
+                       /* First, check no-memory-requests case */
+                       for (i = 0; i < dc->current_state->stream_count; i++) {
+                               if (dc->current_state->stream_status[i].plane_count)
+                                       /* Fail eligibility on a visible stream */
+                                       break;
+                       }
+
+                       if (i == dc->current_state->stream_count) {
+                               /* Enable no-memory-requests case */
+                               memset(&cmd, 0, sizeof(cmd));
+                               cmd.mall.header.type = DMUB_CMD__MALL;
+                               cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_NO_DF_REQ;
+                               cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header);
+
+                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+
+                               return true;
+                       }
+
+                       stream = dc->current_state->streams[0];
+                       plane = (stream ? dc->current_state->stream_status[0].plane_states[0] : NULL);
+
+                       if (stream && plane) {
+                               cursor_cache_enable = stream->cursor_position.enable &&
+                                               plane->address.grph.cursor_cache_addr.quad_part;
+                               cursor_attr = stream->cursor_attributes;
+                       }
+
+                       /*
+                        * Second, check MALL eligibility
+                        *
+                        * single display only, single surface only, 8 and 16 bit formats only, no VM,
+                        * do not use MALL for displays that support PSR as they use D0i3.2 in DMCUB FW
+                        *
+                        * TODO: When we implement multi-display, PSR displays will be allowed if there is
+                        * a non-PSR display present, since in that case we can't do D0i3.2
+                        */
+                       if (dc->current_state->stream_count == 1 &&
+                                       stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED &&
+                                       dc->current_state->stream_status[0].plane_count == 1 &&
+                                       plane->format <= SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F &&
+                                       plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888 &&
+                                       plane->address.page_table_base.quad_part == 0 &&
+                                       dc->hwss.does_plane_fit_in_mall &&
+                                       dc->hwss.does_plane_fit_in_mall(dc, plane,
+                                                       cursor_cache_enable ? &cursor_attr : NULL)) {
+                               unsigned int v_total = stream->adjust.v_total_max ?
+                                               stream->adjust.v_total_max : stream->timing.v_total;
+                               unsigned int refresh_hz = div_u64((unsigned long long) stream->timing.pix_clk_100hz *
+                                               100LL, (v_total * stream->timing.h_total));
+
+                               /*
+                                * one frame time in microsec:
+                                * Delay_Us = 1000000 / refresh
+                                * dynamic_delay_us = 1000000 / refresh + 2 * stutter_period
+                                *
+                                * one frame time modified by 'additional timer percent' (p):
+                                * Delay_Us_modified = dynamic_delay_us + dynamic_delay_us * p / 100
+                                *                   = dynamic_delay_us * (1 + p / 100)
+                                *                   = (1000000 / refresh + 2 * stutter_period) * (100 + p) / 100
+                                *                   = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (100 * refresh)
+                                *
+                                * formula for timer duration based on parameters, from regspec:
+                                * dynamic_delay_us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale
+                                *
+                                * dynamic_delay_us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale
+                                * (dynamic_delay_us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly
+                                * MallFrameCacheTmrDly = ((dynamic_delay_us / 65.28) / 2^MallFrameCacheTmrScale) - 64
+                                *                      = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (100 * refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64
+                                *                      = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64
+                                *
+                                * need to round up the result of the division before the subtraction
+                                */
+                               unsigned int denom = refresh_hz * 6528;
+                               unsigned int stutter_period = dc->current_state->perf_params.stutter_period_us;
+
+                               tmr_delay = div_u64(((1000000LL + 2 * stutter_period * refresh_hz) *
+                                               (100LL + dc->debug.mall_additional_timer_percent) + denom - 1),
+                                               denom) - 64LL;
+
+                               /* In some cases the stutter period is really big (tiny modes) in these
+                                * cases MALL cant be enabled, So skip these cases to avoid a ASSERT()
+                                *
+                                * We can check if stutter_period is more than 1/10th the frame time to
+                                * consider if we can actually meet the range of hysteresis timer
+                                */
+                               if (stutter_period > 100000/refresh_hz)
+                                       return false;
+
+                               /* scale should be increased until it fits into 6 bits */
+                               while (tmr_delay & ~0x3F) {
+                                       tmr_scale++;
+
+                                       if (tmr_scale > 3) {
+                                               /* Delay exceeds range of hysteresis timer */
+                                               ASSERT(false);
+                                               return false;
+                                       }
+
+                                       denom *= 2;
+                                       tmr_delay = div_u64(((1000000LL + 2 * stutter_period * refresh_hz) *
+                                                       (100LL + dc->debug.mall_additional_timer_percent) + denom - 1),
+                                                       denom) - 64LL;
+                               }
+
+                               /* Copy HW cursor */
+                               if (cursor_cache_enable) {
+                                       memset(&cmd, 0, sizeof(cmd));
+                                       cmd.mall.header.type = DMUB_CMD__MALL;
+                                       cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_COPY_CURSOR;
+                                       cmd.mall.header.payload_bytes =
+                                                       sizeof(cmd.mall) - sizeof(cmd.mall.header);
+
+                                       switch (cursor_attr.color_format) {
+                                       case CURSOR_MODE_MONO:
+                                               cmd.mall.cursor_bpp = 2;
+                                               break;
+                                       case CURSOR_MODE_COLOR_1BIT_AND:
+                                       case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
+                                       case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
+                                               cmd.mall.cursor_bpp = 32;
+                                               break;
+
+                                       case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
+                                       case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
+                                               cmd.mall.cursor_bpp = 64;
+                                               break;
+                                       }
+
+                                       cmd.mall.cursor_copy_src.quad_part = cursor_attr.address.quad_part;
+                                       cmd.mall.cursor_copy_dst.quad_part =
+                                                       (plane->address.grph.cursor_cache_addr.quad_part + 2047) & ~2047;
+                                       cmd.mall.cursor_width = cursor_attr.width;
+                                       cmd.mall.cursor_height = cursor_attr.height;
+                                       cmd.mall.cursor_pitch = cursor_attr.pitch;
+
+                                       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+
+                                       /* Use copied cursor, and it's okay to not switch back */
+                                       cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
+                                       dc_stream_set_cursor_attributes(stream, &cursor_attr);
+                               }
+
+                               /* Enable MALL */
+                               memset(&cmd, 0, sizeof(cmd));
+                               cmd.mall.header.type = DMUB_CMD__MALL;
+                               cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_ALLOW;
+                               cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header);
+                               cmd.mall.tmr_delay = tmr_delay;
+                               cmd.mall.tmr_scale = tmr_scale;
+                               cmd.mall.debug_bits = dc->debug.mall_error_as_fatal;
+
+                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+
+                               return true;
+                       }
+               }
+
+               /* No applicable optimizations */
+               return false;
+       }
+
+       /* Disable MALL */
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.mall.header.type = DMUB_CMD__MALL;
+       cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_DISALLOW;
+       cmd.mall.header.payload_bytes =
+               sizeof(cmd.mall) - sizeof(cmd.mall.header);
+
+       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+
+       return true;
+}
+
+bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane, struct dc_cursor_attributes *cursor_attr)
+{
+       // add meta size?
+       unsigned int surface_size = plane->plane_size.surface_pitch * plane->plane_size.surface_size.height *
+                       (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
+       unsigned int mall_size = dc->caps.mall_size_total;
+       unsigned int cursor_size = 0;
+
+       if (dc->debug.mall_size_override)
+               mall_size = 1024 * 1024 * dc->debug.mall_size_override;
+
+       if (cursor_attr) {
+               cursor_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size;
+
+               switch (cursor_attr->color_format) {
+               case CURSOR_MODE_MONO:
+                       cursor_size /= 2;
+                       break;
+               case CURSOR_MODE_COLOR_1BIT_AND:
+               case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
+               case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
+                       cursor_size *= 4;
+                       break;
+
+               case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
+               case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
+                       cursor_size *= 8;
+                       break;
+               }
+       }
+
+       return (surface_size + cursor_size) < mall_size;
+}
+
+void dcn30_hardware_release(struct dc *dc)
+{
+       bool subvp_in_use = false;
+       uint32_t i;
+
+       dc_dmub_srv_p_state_delegate(dc, false, NULL);
+       dc_dmub_setup_subvp_dmub_command(dc, dc->current_state, false);
+
+       /* SubVP treated the same way as FPO. If driver disable and
+        * we are using a SubVP config, disable and force on DCN side
+        * to prevent P-State hang on driver enable.
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (!pipe->stream)
+                       continue;
+
+               if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+                       subvp_in_use = true;
+                       break;
+               }
+       }
+       /* If pstate unsupported, or still supported
+        * by firmware, force it supported by dcn
+        */
+       if (dc->current_state)
+               if ((!dc->clk_mgr->clks.p_state_change_support || subvp_in_use ||
+                               dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) &&
+                               dc->res_pool->hubbub->funcs->force_pstate_change_control)
+                       dc->res_pool->hubbub->funcs->force_pstate_change_control(
+                                       dc->res_pool->hubbub, true, true);
+}
+
+void dcn30_set_disp_pattern_generator(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum controller_dp_test_pattern test_pattern,
+               enum controller_dp_color_space color_space,
+               enum dc_color_depth color_depth,
+               const struct tg_color *solid_color,
+               int width, int height, int offset)
+{
+       pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern,
+                       color_space, color_depth, solid_color, width, height, offset);
+}
+
+void dcn30_prepare_bandwidth(struct dc *dc,
+       struct dc_state *context)
+{
+       bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+       /* Any transition into an FPO config should disable MCLK switching first to avoid
+        * driver and FW P-State synchronization issues.
+        */
+       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+               dc->optimized_required = true;
+               context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
+       }
+
+       if (dc->clk_mgr->dc_mode_softmax_enabled)
+               if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
+                               context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
+                       dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
+
+       dcn20_prepare_bandwidth(dc, context);
+       /*
+        * enabled -> enabled: do not disable
+        * enabled -> disabled: disable
+        * disabled -> enabled: don't care
+        * disabled -> disabled: don't care
+        */
+       if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
+               dc_dmub_srv_p_state_delegate(dc, false, context);
+
+       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+               /* After disabling P-State, restore the original value to ensure we get the correct P-State
+                * on the next optimize. */
+               context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
+       }
+}
+
+void dcn30_set_static_screen_control(struct pipe_ctx **pipe_ctx,
+               int num_pipes, const struct dc_static_screen_params *params)
+{
+       unsigned int i;
+       unsigned int triggers = 0;
+
+       if (params->triggers.surface_update)
+               triggers |= 0x100;
+       if (params->triggers.cursor_update)
+               triggers |= 0x8;
+       if (params->triggers.force_trigger)
+               triggers |= 0x1;
+
+       for (i = 0; i < num_pipes; i++)
+               pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(pipe_ctx[i]->stream_res.tg,
+                                       triggers, params->num_frames);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h
new file mode 100644 (file)
index 0000000..e557e2b
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+* Copyright 2020 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_HWSS_DCN30_H__
+#define __DC_HWSS_DCN30_H__
+
+#include "hw_sequencer_private.h"
+#include "dcn20/dcn20_hwseq.h"
+struct dc;
+
+void dcn30_init_hw(struct dc *dc);
+void dcn30_program_all_writeback_pipes_in_tree(
+               struct dc *dc,
+               const struct dc_stream_state *stream,
+               struct dc_state *context);
+void dcn30_update_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context);
+void dcn30_enable_writeback(
+               struct dc *dc,
+               struct dc_writeback_info *wb_info,
+               struct dc_state *context);
+void dcn30_disable_writeback(
+               struct dc *dc,
+               unsigned int dwb_pipe_inst);
+
+bool dcn30_mmhubbub_warmup(
+       struct dc *dc,
+       unsigned int num_dwb,
+       struct dc_writeback_info *wb_info);
+
+bool dcn30_set_blend_lut(struct pipe_ctx *pipe_ctx,
+               const struct dc_plane_state *plane_state);
+
+bool dcn30_set_input_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state);
+
+void dcn30_program_gamut_remap(struct pipe_ctx *pipe_ctx);
+
+bool dcn30_set_output_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream);
+void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
+void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx);
+void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx);
+
+bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane,
+               struct dc_cursor_attributes *cursor_attr);
+
+bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable);
+
+void dcn30_hardware_release(struct dc *dc);
+
+void dcn30_set_disp_pattern_generator(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               enum controller_dp_test_pattern test_pattern,
+               enum controller_dp_color_space color_space,
+               enum dc_color_depth color_depth,
+               const struct tg_color *solid_color,
+               int width, int height, int offset);
+
+void dcn30_set_hubp_blank(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               bool blank_enable);
+
+void dcn30_prepare_bandwidth(struct dc *dc,
+       struct dc_state *context);
+
+void dcn30_set_static_screen_control(struct pipe_ctx **pipe_ctx,
+               int num_pipes, const struct dc_static_screen_params *params);
+
+#endif /* __DC_HWSS_DCN30_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_hwseq.c
new file mode 100644 (file)
index 0000000..10bedb2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 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 "core_types.h"
+#include "dce/dce_hwseq.h"
+#include "dcn301_hwseq.h"
+#include "reg_helper.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#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
+
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_hwseq.h
new file mode 100644 (file)
index 0000000..aa3df3f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* Copyright 2020 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_HWSS_DCN301_H__
+#define __DC_HWSS_DCN301_H__
+
+#include "hw_sequencer_private.h"
+
+
+#endif /* __DC_HWSS_DCN301_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn302/dcn302_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn302/dcn302_hwseq.c
new file mode 100644 (file)
index 0000000..0a6d58d
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2020 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 "dcn302_hwseq.h"
+
+#include "dce/dce_hwseq.h"
+
+#include "reg_helper.h"
+#include "dc.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#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 dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+
+       if (hws->ctx->dc->debug.disable_dpp_power_gate)
+               return;
+       if (REG(DOMAIN1_PG_CONFIG) == 0)
+               return;
+
+       switch (dpp_inst) {
+       case 0: /* DPP0 */
+               REG_UPDATE(DOMAIN1_PG_CONFIG,
+                               DOMAIN1_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN1_PG_STATUS,
+                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DPP1 */
+               REG_UPDATE(DOMAIN3_PG_CONFIG,
+                               DOMAIN3_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN3_PG_STATUS,
+                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DPP2 */
+               REG_UPDATE(DOMAIN5_PG_CONFIG,
+                               DOMAIN5_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN5_PG_STATUS,
+                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DPP3 */
+               REG_UPDATE(DOMAIN7_PG_CONFIG,
+                               DOMAIN7_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN7_PG_STATUS,
+                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 4: /* DPP4 */
+               REG_UPDATE(DOMAIN9_PG_CONFIG,
+                               DOMAIN9_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN9_PG_STATUS,
+                               DOMAIN9_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
+               return;
+       if (REG(DOMAIN0_PG_CONFIG) == 0)
+               return;
+
+       switch (hubp_inst) {
+       case 0: /* DCHUBP0 */
+               REG_UPDATE(DOMAIN0_PG_CONFIG,
+                               DOMAIN0_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN0_PG_STATUS,
+                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DCHUBP1 */
+               REG_UPDATE(DOMAIN2_PG_CONFIG,
+                               DOMAIN2_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN2_PG_STATUS,
+                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DCHUBP2 */
+               REG_UPDATE(DOMAIN4_PG_CONFIG,
+                               DOMAIN4_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN4_PG_STATUS,
+                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DCHUBP3 */
+               REG_UPDATE(DOMAIN6_PG_CONFIG,
+                               DOMAIN6_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN6_PG_STATUS,
+                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 4: /* DCHUBP4 */
+               REG_UPDATE(DOMAIN8_PG_CONFIG,
+                               DOMAIN8_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN8_PG_STATUS,
+                               DOMAIN8_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_dsc_power_gate)
+               return;
+
+       if (REG(DOMAIN16_PG_CONFIG) == 0)
+               return;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_UPDATE(DOMAIN16_PG_CONFIG,
+                               DOMAIN16_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN16_PG_STATUS,
+                               DOMAIN16_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DSC1 */
+               REG_UPDATE(DOMAIN17_PG_CONFIG,
+                               DOMAIN17_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN17_PG_STATUS,
+                               DOMAIN17_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DSC2 */
+               REG_UPDATE(DOMAIN18_PG_CONFIG,
+                               DOMAIN18_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN18_PG_STATUS,
+                               DOMAIN18_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DSC3 */
+               REG_UPDATE(DOMAIN19_PG_CONFIG,
+                               DOMAIN19_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN19_PG_STATUS,
+                               DOMAIN19_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 4: /* DSC4 */
+               REG_UPDATE(DOMAIN20_PG_CONFIG,
+                               DOMAIN20_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN20_PG_STATUS,
+                               DOMAIN20_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn302/dcn302_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn302/dcn302_hwseq.h
new file mode 100644 (file)
index 0000000..1e5126a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 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_HWSS_DCN302_H__
+#define __DC_HWSS_DCN302_H__
+
+#include "hw_sequencer_private.h"
+
+void dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on);
+void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
+void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
+
+#endif /* __DC_HWSS_DCN302_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c
new file mode 100644 (file)
index 0000000..b48b732
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (C) 2021 Advanced Micro Devices, Inc.
+ *
+ * Authors: AMD
+ */
+
+#include "dcn303_hwseq.h"
+
+#include "dce/dce_hwseq.h"
+
+#include "reg_helper.h"
+#include "dc.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#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 dcn303_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on)
+{
+       /*DCN303 removes PG registers*/
+}
+
+void dcn303_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
+{
+       /*DCN303 removes PG registers*/
+}
+
+void dcn303_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on)
+{
+       /*DCN303 removes PG registers*/
+}
+
+void dcn303_enable_power_gating_plane(struct dce_hwseq *hws, bool enable)
+{
+       /*DCN303 removes PG registers*/
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h
new file mode 100644 (file)
index 0000000..8b69a3b
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (C) 2021 Advanced Micro Devices, Inc.
+ *
+ * Authors: AMD
+ */
+
+#ifndef __DC_HWSS_DCN303_H__
+#define __DC_HWSS_DCN303_H__
+
+#include "hw_sequencer_private.h"
+
+void dcn303_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on);
+void dcn303_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
+void dcn303_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
+void dcn303_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
+
+#endif /* __DC_HWSS_DCN303_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
new file mode 100644 (file)
index 0000000..c339f75
--- /dev/null
@@ -0,0 +1,604 @@
+/*
+ * 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 "dm_services.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dccg.h"
+#include "dce/dce_hwseq.h"
+#include "clk_mgr.h"
+#include "reg_helper.h"
+#include "abm.h"
+#include "hubp.h"
+#include "dchubbub.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "mcif_wb.h"
+#include "dc_dmub_srv.h"
+#include "dcn31_hwseq.h"
+#include "link_hwss.h"
+#include "dpcd_defs.h"
+#include "dce/dmub_outbox.h"
+#include "link.h"
+#include "dcn10/dcn10_hwseq.h"
+#include "inc/link_enc_cfg.h"
+#include "dcn30/dcn30_vpg.h"
+#include "dce/dce_i2c_hw.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#define CTX \
+       hws->ctx
+#define REG(reg)\
+       hws->regs->reg
+#define DC_LOGGER \
+               dc->ctx->logger
+
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+
+static void enable_memory_low_power(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       int i;
+
+       if (dc->debug.enable_mem_low_power.bits.dmcu) {
+               // Force ERAM to shutdown if DMCU is not enabled
+               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
+                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
+               }
+       }
+
+       // Set default OPTC memory power states
+       if (dc->debug.enable_mem_low_power.bits.optc) {
+               // Shutdown when unassigned and light sleep in VBLANK
+               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.vga) {
+               // Power down VGA memory
+               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.mpc &&
+               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode)
+               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
+
+
+       if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
+               // Power down VPGs
+               for (i = 0; i < dc->res_pool->stream_enc_count; i++)
+                       if (dc->res_pool->stream_enc[i]->vpg)
+                               dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
+#if defined(CONFIG_DRM_AMD_DC_FP)
+               for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
+                       dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
+#endif
+       }
+
+}
+
+void dcn31_init_hw(struct dc *dc)
+{
+       struct abm **abms = dc->res_pool->multiple_abms;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+       struct resource_pool *res_pool = dc->res_pool;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+       int i;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       if (!dcb->funcs->is_accelerated_mode(dcb)) {
+               hws->funcs.bios_golden_init(dc);
+               if (hws->funcs.disable_vga)
+                       hws->funcs.disable_vga(dc->hwseq);
+       }
+       // Initialize the dccg
+       if (res_pool->dccg->funcs->dccg_init)
+               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       enable_memory_low_power(dc);
+
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (res_pool->dccg && res_pool->hubbub) {
+
+                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+               } else {
+                       // Not all ASICs have DCCG sw component
+                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+               }
+       } else
+               ASSERT_CRITICAL(false);
+
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               if (link->ep_type != DISPLAY_ENDPOINT_PHY)
+                       continue;
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+
+               /* Check for enabled DIG to identify enabled display */
+               if (link->link_enc->funcs->is_dig_enabled &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
+                       link->link_status.link_active = true;
+                       if (link->link_enc->funcs->fec_is_active &&
+                                       link->link_enc->funcs->fec_is_active(link->link_enc))
+                               link->fec_state = dc_link_fec_enabled;
+               }
+       }
+
+       /* we want to turn off all dp displays before doing detection */
+       dc->link_srv->blank_all_dp_displays(dc);
+
+       if (hws->funcs.enable_power_gating_plane)
+               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
+
+       /* If taking control over from VBIOS, we may want to optimize our first
+        * mode set, so we need to skip powering down pipes until we know which
+        * pipes we want to use.
+        * Otherwise, if taking control is not possible, we need to power
+        * everything down.
+        */
+       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
+
+               // we want to turn off edp displays if odm is enabled and no seamless boot
+               if (!dc->caps.seamless_odm) {
+                       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+                               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+                               uint32_t num_opps, opp_id_src0, opp_id_src1;
+
+                               num_opps = 1;
+                               if (tg) {
+                                       if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) {
+                                               tg->funcs->get_optc_source(tg, &num_opps,
+                                                               &opp_id_src0, &opp_id_src1);
+                                       }
+                               }
+
+                               if (num_opps > 1) {
+                                       dc->link_srv->blank_all_edp_displays(dc);
+                                       break;
+                               }
+                       }
+               }
+
+               hws->funcs.init_pipes(dc, dc->current_state);
+               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
+                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
+       }
+
+       for (i = 0; i < res_pool->audio_count; i++) {
+               struct audio *audio = res_pool->audios[i];
+
+               audio->funcs->hw_init(audio);
+       }
+
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               if (link->panel_cntl)
+                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (abms[i] != NULL)
+                       abms[i]->funcs->abm_init(abms[i], backlight);
+       }
+
+       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
+       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+       // Set i2c to light sleep until engine is setup
+       if (dc->debug.enable_mem_low_power.bits.i2c)
+               REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
+
+       if (hws->funcs.setup_hpo_hw_control)
+               hws->funcs.setup_hpo_hw_control(hws, false);
+
+       if (!dc->debug.disable_clock_gate) {
+               /* enable all DCN clock gating */
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+       }
+
+       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
+               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
+
+       if (dc->clk_mgr->funcs->notify_wm_ranges)
+               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+               dc->res_pool->hubbub->funcs->force_pstate_change_control(
+                               dc->res_pool->hubbub, false, false);
+#if defined(CONFIG_DRM_AMD_DC_FP)
+       if (dc->res_pool->hubbub->funcs->init_crb)
+               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+#endif
+
+       // Get DMCUB capabilities
+       dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
+       dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
+       dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
+}
+
+void dcn31_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_dsc_power_gate)
+               return;
+
+       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
+               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
+               power_on)
+               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
+                       hws->ctx->dc->res_pool->dccg, dsc_inst);
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_UPDATE(DOMAIN16_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN16_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DSC1 */
+               REG_UPDATE(DOMAIN17_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN17_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DSC2 */
+               REG_UPDATE(DOMAIN18_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN18_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+
+       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
+               if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
+                       hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
+                               hws->ctx->dc->res_pool->dccg, dsc_inst);
+       }
+
+}
+
+
+void dcn31_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable)
+{
+       bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
+
+       if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)
+               force_on = false;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+       /* DCHUBP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       /* DPP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       force_on = true; /* disable power gating */
+       if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
+               force_on = false;
+
+       /* DCS0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
+{
+       bool is_hdmi_tmds;
+       bool is_dp;
+
+       ASSERT(pipe_ctx->stream);
+
+       if (pipe_ctx->stream_res.stream_enc == NULL)
+               return;  /* this is not root pipe */
+
+       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
+       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
+
+       if (!is_hdmi_tmds && !is_dp)
+               return;
+
+       if (is_hdmi_tmds)
+               pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
+                       pipe_ctx->stream_res.stream_enc,
+                       &pipe_ctx->stream_res.encoder_info_frame);
+       else if (pipe_ctx->stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets(
+                               pipe_ctx->stream_res.hpo_dp_stream_enc,
+                               &pipe_ctx->stream_res.encoder_info_frame);
+               return;
+       } else {
+               if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)
+                       pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(
+                               pipe_ctx->stream_res.stream_enc,
+                               &pipe_ctx->stream_res.encoder_info_frame);
+
+               pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
+                       pipe_ctx->stream_res.stream_enc,
+                       &pipe_ctx->stream_res.encoder_info_frame);
+       }
+}
+void dcn31_z10_save_init(struct dc *dc)
+{
+       union dmub_rb_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
+       cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT;
+
+       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
+void dcn31_z10_restore(const struct dc *dc)
+{
+       union dmub_rb_cmd cmd;
+
+       /*
+        * DMUB notifies whether restore is required.
+        * Optimization to avoid sending commands when not required.
+        */
+       if (!dc_dmub_srv_is_restore_required(dc->ctx->dmub_srv))
+               return;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
+       cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_RESTORE;
+
+       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
+void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl;
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
+               return;
+
+       if (REG(DOMAIN0_PG_CONFIG) == 0)
+               return;
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (hubp_inst) {
+       case 0:
+               REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       case 1:
+               REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       case 2:
+               REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       case 3:
+               REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
+{
+       struct dcn_hubbub_phys_addr_config config;
+
+       config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
+       config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
+       config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
+       config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
+       config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
+       config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
+       config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
+       config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
+
+       if (pa_config->gart_config.base_addr_is_mc_addr) {
+               /* Convert from MC address to offset into FB */
+               config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr -
+                               pa_config->system_aperture.fb_base +
+                               pa_config->system_aperture.fb_offset;
+       } else
+               config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
+
+       return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
+}
+
+static void dcn31_reset_back_end_for_pipe(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_state *context)
+{
+       struct dc_link *link;
+
+       DC_LOGGER_INIT(dc->ctx->logger);
+       if (pipe_ctx->stream_res.stream_enc == NULL) {
+               pipe_ctx->stream = NULL;
+               return;
+       }
+       ASSERT(!pipe_ctx->top_pipe);
+
+       dc->hwss.set_abm_immediate_disable(pipe_ctx);
+
+       pipe_ctx->stream_res.tg->funcs->set_dsc_config(
+                       pipe_ctx->stream_res.tg,
+                       OPTC_DSC_DISABLED, 0, 0);
+       pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
+       pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+       if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
+               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+       pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
+
+       if (pipe_ctx->stream_res.tg->funcs->set_drr)
+               pipe_ctx->stream_res.tg->funcs->set_drr(
+                               pipe_ctx->stream_res.tg, NULL);
+
+       link = pipe_ctx->stream->link;
+       /* DPMS may already disable or */
+       /* dpms_off status is incorrect due to fastboot
+        * feature. When system resume from S4 with second
+        * screen only, the dpms_off would be true but
+        * VBIOS lit up eDP, so check link status too.
+        */
+       if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+               dc->link_srv->set_dpms_off(pipe_ctx);
+       else if (pipe_ctx->stream_res.audio)
+               dc->hwss.disable_audio_stream(pipe_ctx);
+
+       /* free acquired resources */
+       if (pipe_ctx->stream_res.audio) {
+               /*disable az_endpoint*/
+               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+               /*free audio*/
+               if (dc->caps.dynamic_audio == true) {
+                       /*we have to dynamic arbitrate the audio endpoints*/
+                       /*we free the resource, need reset is_audio_acquired*/
+                       update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
+                                       pipe_ctx->stream_res.audio, false);
+                       pipe_ctx->stream_res.audio = NULL;
+               }
+       }
+
+       pipe_ctx->stream = NULL;
+       DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
+                                       pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
+}
+
+void dcn31_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       /* Reset Back End*/
+       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
+               struct pipe_ctx *pipe_ctx_old =
+                       &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe_ctx_old->stream)
+                       continue;
+
+               if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
+                       continue;
+
+               if (!pipe_ctx->stream ||
+                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+                       struct clock_source *old_clk = pipe_ctx_old->clock_source;
+
+                       dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
+                       if (hws->funcs.enable_stream_gating)
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
+                       if (old_clk)
+                               old_clk->funcs->cs_power_down(old_clk);
+               }
+       }
+
+       /* New dc_state in the process of being applied to hardware. */
+       link_enc_cfg_set_transient_mode(dc, dc->current_state, context);
+}
+
+void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
+{
+       if (hws->ctx->dc->debug.hpo_optimization)
+               REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.h
new file mode 100644 (file)
index 0000000..edfc01d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+* 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 __DC_HWSS_DCN31_H__
+#define __DC_HWSS_DCN31_H__
+
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dcn31_init_hw(struct dc *dc);
+
+void dcn31_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on);
+
+void dcn31_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable);
+
+void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx);
+
+void dcn31_z10_restore(const struct dc *dc);
+void dcn31_z10_save_init(struct dc *dc);
+
+void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
+int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config);
+void dcn31_reset_hw_ctx_wrap(
+               struct dc *dc,
+               struct dc_state *context);
+bool dcn31_is_abm_supported(struct dc *dc,
+               struct dc_state *context, struct dc_stream_state *stream);
+void dcn31_init_pipes(struct dc *dc, struct dc_state *context);
+void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
+
+#endif /* __DC_HWSS_DCN31_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
new file mode 100644 (file)
index 0000000..3a9cc8a
--- /dev/null
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2022 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 "dm_services.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dccg.h"
+#include "dce/dce_hwseq.h"
+#include "clk_mgr.h"
+#include "reg_helper.h"
+#include "abm.h"
+#include "hubp.h"
+#include "dchubbub.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "mcif_wb.h"
+#include "dc_dmub_srv.h"
+#include "dcn314_hwseq.h"
+#include "link_hwss.h"
+#include "dpcd_defs.h"
+#include "dce/dmub_outbox.h"
+#include "link.h"
+#include "dcn10/dcn10_hwseq.h"
+#include "inc/link_enc_cfg.h"
+#include "dcn30/dcn30_vpg.h"
+#include "dce/dce_i2c_hw.h"
+#include "dsc.h"
+#include "dcn20/dcn20_optc.h"
+#include "dcn30/dcn30_cm_common.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#define CTX \
+       hws->ctx
+#define REG(reg)\
+       hws->regs->reg
+#define DC_LOGGER \
+       stream->ctx->logger
+
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+
+static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
+               int opp_cnt)
+{
+       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
+       int flow_ctrl_cnt;
+
+       if (opp_cnt >= 2)
+               hblank_halved = true;
+
+       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
+                       stream->timing.h_border_left -
+                       stream->timing.h_border_right;
+
+       if (hblank_halved)
+               flow_ctrl_cnt /= 2;
+
+       /* ODM combine 4:1 case */
+       if (opp_cnt == 4)
+               flow_ctrl_cnt /= 2;
+
+       return flow_ctrl_cnt;
+}
+
+static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
+{
+       struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 1;
+
+       ASSERT(dsc);
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               opp_cnt++;
+
+       if (enable) {
+               struct dsc_config dsc_cfg;
+               struct dsc_optc_config dsc_optc_cfg;
+               enum optc_dsc_mode optc_dsc_mode;
+
+               /* Enable DSC hw block */
+               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
+               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
+               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+               dsc_cfg.color_depth = stream->timing.display_color_depth;
+               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
+               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+               ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
+               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+
+               dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
+               dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+                       struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
+
+                       ASSERT(odm_dsc);
+                       odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
+                       odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
+               }
+               dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
+               dsc_cfg.pic_width *= opp_cnt;
+
+               optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
+
+               /* Enable DSC in OPTC */
+               DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+               pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
+                                                       optc_dsc_mode,
+                                                       dsc_optc_cfg.bytes_per_pixel,
+                                                       dsc_optc_cfg.slice_width);
+       } else {
+               /* disable DSC in OPTC */
+               pipe_ctx->stream_res.tg->funcs->set_dsc_config(
+                               pipe_ctx->stream_res.tg,
+                               OPTC_DSC_DISABLED, 0, 0);
+
+               /* disable DSC block */
+               dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+                       ASSERT(odm_pipe->stream_res.dsc);
+                       odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
+               }
+       }
+}
+
+// Given any pipe_ctx, return the total ODM combine factor, and optionally return
+// the OPPids which are used
+static unsigned int get_odm_config(struct pipe_ctx *pipe_ctx, unsigned int *opp_instances)
+{
+       unsigned int opp_count = 1;
+       struct pipe_ctx *odm_pipe;
+
+       // First get to the top pipe
+       for (odm_pipe = pipe_ctx; odm_pipe->prev_odm_pipe; odm_pipe = odm_pipe->prev_odm_pipe)
+               ;
+
+       // First pipe is always used
+       if (opp_instances)
+               opp_instances[0] = odm_pipe->stream_res.opp->inst;
+
+       // Find and count odm pipes, if any
+       for (odm_pipe = odm_pipe->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               if (opp_instances)
+                       opp_instances[opp_count] = odm_pipe->stream_res.opp->inst;
+               opp_count++;
+       }
+
+       return opp_count;
+}
+
+void dcn314_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 0;
+       int opp_inst[MAX_PIPES] = {0};
+       bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
+       struct mpc_dwb_flow_control flow_control;
+       struct mpc *mpc = dc->res_pool->mpc;
+       int i;
+
+       opp_cnt = get_odm_config(pipe_ctx, opp_inst);
+
+       if (opp_cnt > 1)
+               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
+                               pipe_ctx->stream_res.tg,
+                               opp_inst, opp_cnt,
+                               &pipe_ctx->stream->timing);
+       else
+               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+
+       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
+       flow_control.flow_ctrl_mode = 0;
+       flow_control.flow_ctrl_cnt0 = 0x80;
+       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
+       if (mpc->funcs->set_out_rate_control) {
+               for (i = 0; i < opp_cnt; ++i) {
+                       mpc->funcs->set_out_rate_control(
+                                       mpc, opp_inst[i],
+                                       true,
+                                       rate_control_2x_pclk,
+                                       &flow_control);
+               }
+       }
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
+                               odm_pipe->stream_res.opp,
+                               true);
+       }
+
+       if (pipe_ctx->stream_res.dsc) {
+               struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
+
+               update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
+
+               /* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
+               if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
+                               current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
+                       struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
+                       /* disconnect DSC block from stream */
+                       dsc->funcs->dsc_disconnect(dsc);
+               }
+       }
+}
+
+void dcn314_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_dsc_power_gate)
+               return;
+
+       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
+               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
+               power_on)
+               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
+                       hws->ctx->dc->res_pool->dccg, dsc_inst);
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_UPDATE(DOMAIN16_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN16_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DSC1 */
+               REG_UPDATE(DOMAIN17_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN17_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DSC2 */
+               REG_UPDATE(DOMAIN18_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN18_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DSC3 */
+               REG_UPDATE(DOMAIN19_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN19_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+
+       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
+               if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
+                       hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
+                               hws->ctx->dc->res_pool->dccg, dsc_inst);
+       }
+
+}
+
+void dcn314_enable_power_gating_plane(struct dce_hwseq *hws, bool enable)
+{
+       bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
+
+       if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)
+               force_on = false;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+       /* DCHUBP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       /* DPP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       force_on = true; /* disable power gating */
+       if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
+               force_on = false;
+
+       /* DCS0/1/2/3/4 */
+       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       unsigned int odm_combine_factor = 0;
+       bool two_pix_per_container = false;
+
+       two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
+       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+
+       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               *k1_div = PIXEL_RATE_DIV_BY_1;
+               *k2_div = PIXEL_RATE_DIV_BY_1;
+       } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
+               *k1_div = PIXEL_RATE_DIV_BY_1;
+               if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+                       *k2_div = PIXEL_RATE_DIV_BY_2;
+               else
+                       *k2_div = PIXEL_RATE_DIV_BY_4;
+       } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
+               if (two_pix_per_container) {
+                       *k1_div = PIXEL_RATE_DIV_BY_1;
+                       *k2_div = PIXEL_RATE_DIV_BY_2;
+               } else {
+                       *k1_div = PIXEL_RATE_DIV_BY_1;
+                       *k2_div = PIXEL_RATE_DIV_BY_4;
+                       if (odm_combine_factor == 2)
+                               *k2_div = PIXEL_RATE_DIV_BY_2;
+               }
+       }
+
+       if ((*k1_div == PIXEL_RATE_DIV_NA) && (*k2_div == PIXEL_RATE_DIV_NA))
+               ASSERT(false);
+
+       return odm_combine_factor;
+}
+
+void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
+{
+       uint32_t pix_per_cycle = 1;
+       uint32_t odm_combine_factor = 1;
+
+       if (!pipe_ctx || !pipe_ctx->stream || !pipe_ctx->stream_res.stream_enc)
+               return;
+
+       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+       if (optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing) || odm_combine_factor > 1)
+               pix_per_cycle = 2;
+
+       if (pipe_ctx->stream_res.stream_enc->funcs->set_input_mode)
+               pipe_ctx->stream_res.stream_enc->funcs->set_input_mode(pipe_ctx->stream_res.stream_enc,
+                               pix_per_cycle);
+}
+
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
+{
+       unsigned int i;
+       struct pipe_ctx *pipe = NULL;
+       bool otg_disabled[MAX_PIPES] = {false};
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (pipe->top_pipe || pipe->prev_odm_pipe)
+                       continue;
+
+               if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
+                       pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
+                       reset_sync_context_for_pipe(dc, context, i);
+                       otg_disabled[i] = true;
+               }
+       }
+
+       hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (otg_disabled[i])
+                       pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+       }
+}
+
+void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on)
+{
+       if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
+               return;
+
+       if (hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control)
+               hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control(
+                       hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on);
+}
+
+static void apply_symclk_on_tx_off_wa(struct dc_link *link)
+{
+       /* There are use cases where SYMCLK is referenced by OTG. For instance
+        * for TMDS signal, OTG relies SYMCLK even if TX video output is off.
+        * However current link interface will power off PHY when disabling link
+        * output. This will turn off SYMCLK generated by PHY. The workaround is
+        * to identify such case where SYMCLK is still in use by OTG when we
+        * power off PHY. When this is detected, we will temporarily power PHY
+        * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
+        * program_pix_clk interface. When OTG is disabled, we will then power
+        * off PHY by calling disable link output again.
+        *
+        * In future dcn generations, we plan to rework transmitter control
+        * interface so that we could have an option to set SYMCLK ON TX OFF
+        * state in one step without this workaround
+        */
+
+       struct dc *dc = link->ctx->dc;
+       struct pipe_ctx *pipe_ctx = NULL;
+       uint8_t i;
+
+       if (link->phy_state.symclk_ref_cnts.otg > 0) {
+               for (i = 0; i < MAX_PIPES; i++) {
+                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+                       if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
+                               pipe_ctx->clock_source->funcs->program_pix_clk(
+                                               pipe_ctx->clock_source,
+                                               &pipe_ctx->stream_res.pix_clk_params,
+                                               dc->link_srv->dp_get_encoding_format(
+                                                               &pipe_ctx->link_config.dp_link_settings),
+                                               &pipe_ctx->pll_settings);
+                               link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+                               break;
+                       }
+               }
+       }
+}
+
+void dcn314_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal)
+{
+       struct dc *dc = link->ctx->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control &&
+                       !link->skip_implict_edp_power_control)
+               link->dc->hwss.edp_backlight_control(link, false);
+       else if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       link_hwss->disable_link_output(link, link_res, signal);
+       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+       /*
+        * Add the logic to extract BOTH power up and power down sequences
+        * from enable/disable link output and only call edp panel control
+        * in enable_link_dp and disable_link_dp once.
+        */
+       if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+
+       apply_symclk_on_tx_off_wa(link);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
new file mode 100644 (file)
index 0000000..eafcc4e
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2022 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_HWSS_DCN314_H__
+#define __DC_HWSS_DCN314_H__
+
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dcn314_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
+
+void dcn314_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
+
+void dcn314_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
+
+unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div);
+
+void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
+
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
+
+void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
+
+void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal);
+
+#endif /* __DC_HWSS_DCN314_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
new file mode 100644 (file)
index 0000000..68dc990
--- /dev/null
@@ -0,0 +1,1678 @@
+/*
+ * 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 "dm_services.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dccg.h"
+#include "dce/dce_hwseq.h"
+#include "dcn30/dcn30_cm_common.h"
+#include "reg_helper.h"
+#include "abm.h"
+#include "hubp.h"
+#include "dchubbub.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "mcif_wb.h"
+#include "dc_dmub_srv.h"
+#include "link_hwss.h"
+#include "dpcd_defs.h"
+#include "dcn32_hwseq.h"
+#include "clk_mgr.h"
+#include "dsc.h"
+#include "dcn20/dcn20_optc.h"
+#include "dce/dmub_hw_lock_mgr.h"
+#include "dcn32/dcn32_resource.h"
+#include "link.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#define CTX \
+       hws->ctx
+#define REG(reg)\
+       hws->regs->reg
+#define DC_LOGGER \
+       stream->ctx->logger
+
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+
+void dcn32_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_dsc_power_gate)
+               return;
+
+       if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support)
+               return;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_UPDATE(DOMAIN16_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN16_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DSC1 */
+               REG_UPDATE(DOMAIN17_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN17_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DSC2 */
+               REG_UPDATE(DOMAIN18_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN18_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DSC3 */
+               REG_UPDATE(DOMAIN19_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN19_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+
+void dcn32_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable)
+{
+       bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
+
+       if (enable)
+               force_on = false;
+
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       /* DCHUBP0/1/2/3 */
+       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       /* DCS0/1/2/3 */
+       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
+               return;
+
+       if (REG(DOMAIN0_PG_CONFIG) == 0)
+               return;
+
+       switch (hubp_inst) {
+       case 0:
+               REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       case 1:
+               REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       case 2:
+               REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       case 3:
+               REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
+               REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+}
+
+static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
+{
+       int i;
+
+    /* First, check no-memory-request case */
+       for (i = 0; i < dc->current_state->stream_count; i++) {
+               if ((dc->current_state->stream_status[i].plane_count) &&
+                       (dc->current_state->streams[i]->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED))
+                       /* Fail eligibility on a visible stream */
+                       break;
+       }
+
+       if (i == dc->current_state->stream_count)
+               return true;
+
+       return false;
+}
+
+
+/* This function loops through every surface that needs to be cached in CAB for SS,
+ * and calculates the total number of ways required to store all surfaces (primary,
+ * meta, cursor).
+ */
+static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
+{
+       int i;
+       uint8_t num_ways = 0;
+       uint32_t mall_ss_size_bytes = 0;
+
+       mall_ss_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_size_bytes;
+       // TODO add additional logic for PSR active stream exclusion optimization
+       // mall_ss_psr_active_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_psr_active_size_bytes;
+
+       // Include cursor size for CAB allocation
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[i];
+
+               if (!pipe->stream || !pipe->plane_state)
+                       continue;
+
+               mall_ss_size_bytes += dcn32_helper_calculate_mall_bytes_for_cursor(dc, pipe, false);
+       }
+
+       // Convert number of cache lines required to number of ways
+       if (dc->debug.force_mall_ss_num_ways > 0) {
+               num_ways = dc->debug.force_mall_ss_num_ways;
+       } else {
+               num_ways = dcn32_helper_mall_bytes_to_ways(dc, mall_ss_size_bytes);
+       }
+
+       return num_ways;
+}
+
+bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
+{
+       union dmub_rb_cmd cmd;
+       uint8_t ways, i;
+       int j;
+       bool mall_ss_unsupported = false;
+       struct dc_plane_state *plane = NULL;
+
+       if (!dc->ctx->dmub_srv)
+               return false;
+
+       for (i = 0; i < dc->current_state->stream_count; i++) {
+               /* MALL SS messaging is not supported with PSR at this time */
+               if (dc->current_state->streams[i] != NULL &&
+                               dc->current_state->streams[i]->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
+                       return false;
+       }
+
+       if (enable) {
+               if (dc->current_state) {
+
+                       /* 1. Check no memory request case for CAB.
+                        * If no memory request case, send CAB_ACTION NO_DF_REQ DMUB message
+                        */
+                       if (dcn32_check_no_memory_request_for_cab(dc)) {
+                               /* Enable no-memory-requests case */
+                               memset(&cmd, 0, sizeof(cmd));
+                               cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
+                               cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
+                               cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
+
+                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+
+                               return true;
+                       }
+
+                       /* 2. Check if all surfaces can fit in CAB.
+                        * If surfaces can fit into CAB, send CAB_ACTION_ALLOW DMUB message
+                        * and configure HUBP's to fetch from MALL
+                        */
+                       ways = dcn32_calculate_cab_allocation(dc, dc->current_state);
+
+                       /* MALL not supported with Stereo3D or TMZ surface. If any plane is using stereo,
+                        * or TMZ surface, don't try to enter MALL.
+                        */
+                       for (i = 0; i < dc->current_state->stream_count; i++) {
+                               for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) {
+                                       plane = dc->current_state->stream_status[i].plane_states[j];
+
+                                       if (plane->address.type == PLN_ADDR_TYPE_GRPH_STEREO ||
+                                                       plane->address.tmz_surface) {
+                                               mall_ss_unsupported = true;
+                                               break;
+                                       }
+                               }
+                               if (mall_ss_unsupported)
+                                       break;
+                       }
+                       if (ways <= dc->caps.cache_num_ways && !mall_ss_unsupported) {
+                               memset(&cmd, 0, sizeof(cmd));
+                               cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
+                               cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
+                               cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
+                               cmd.cab.cab_alloc_ways = ways;
+
+                               dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+
+                               return true;
+                       }
+
+               }
+               return false;
+       }
+
+       /* Disable CAB */
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
+       cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION;
+       cmd.cab.header.payload_bytes =
+                       sizeof(cmd.cab) - sizeof(cmd.cab.header);
+
+       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+
+       return true;
+}
+
+/* Send DMCUB message with SubVP pipe info
+ * - For each pipe in context, populate payload with required SubVP information
+ *   if the pipe is using SubVP for MCLK switch
+ * - This function must be called while the DMUB HW lock is acquired by driver
+ */
+void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       bool enable_subvp = false;
+
+       if (!dc->ctx || !dc->ctx->dmub_srv)
+               return;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.paired_stream &&
+                               pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN) {
+                       // There is at least 1 SubVP pipe, so enable SubVP
+                       enable_subvp = true;
+                       break;
+               }
+       }
+       dc_dmub_setup_subvp_dmub_command(dc, context, enable_subvp);
+}
+
+/* Sub-Viewport DMUB lock needs to be acquired by driver whenever SubVP is active and:
+ * 1. Any full update for any SubVP main pipe
+ * 2. Any immediate flip for any SubVP pipe
+ * 3. Any flip for DRR pipe
+ * 4. If SubVP was previously in use (i.e. in old context)
+ */
+void dcn32_subvp_pipe_control_lock(struct dc *dc,
+               struct dc_state *context,
+               bool lock,
+               bool should_lock_all_pipes,
+               struct pipe_ctx *top_pipe_to_program,
+               bool subvp_prev_use)
+{
+       unsigned int i = 0;
+       bool subvp_immediate_flip = false;
+       bool subvp_in_use = false;
+       struct pipe_ctx *pipe;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+                       subvp_in_use = true;
+                       break;
+               }
+       }
+
+       if (top_pipe_to_program && top_pipe_to_program->stream && top_pipe_to_program->plane_state) {
+               if (top_pipe_to_program->stream->mall_stream_config.type == SUBVP_MAIN &&
+                               top_pipe_to_program->plane_state->flip_immediate)
+                       subvp_immediate_flip = true;
+       }
+
+       // Don't need to lock for DRR VSYNC flips -- FW will wait for DRR pending update cleared.
+       if ((subvp_in_use && (should_lock_all_pipes || subvp_immediate_flip)) || (!subvp_in_use && subvp_prev_use)) {
+               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+
+               if (!lock) {
+                       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                               pipe = &context->res_ctx.pipe_ctx[i];
+                               if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN &&
+                                               should_lock_all_pipes)
+                                       pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VBLANK);
+                       }
+               }
+
+               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+               hw_lock_cmd.bits.lock = lock;
+               hw_lock_cmd.bits.should_release = !lock;
+               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
+       }
+}
+
+void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params)
+{
+       struct dc *dc = params->subvp_pipe_control_lock_fast_params.dc;
+       bool lock = params->subvp_pipe_control_lock_fast_params.lock;
+       struct pipe_ctx *pipe_ctx = params->subvp_pipe_control_lock_fast_params.pipe_ctx;
+       bool subvp_immediate_flip = false;
+
+       if (pipe_ctx && pipe_ctx->stream && pipe_ctx->plane_state) {
+               if (pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN &&
+                               pipe_ctx->plane_state->flip_immediate)
+                       subvp_immediate_flip = true;
+       }
+
+       // Don't need to lock for DRR VSYNC flips -- FW will wait for DRR pending update cleared.
+       if (subvp_immediate_flip) {
+               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+
+               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+               hw_lock_cmd.bits.lock = lock;
+               hw_lock_cmd.bits.should_release = !lock;
+               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
+       }
+}
+
+bool dcn32_set_mpc_shaper_3dlut(
+       struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+       bool result = false;
+
+       const struct pwl_params *shaper_lut = NULL;
+       //get the shaper lut params
+       if (stream->func_shaper) {
+               if (stream->func_shaper->type == TF_TYPE_HWPWL)
+                       shaper_lut = &stream->func_shaper->pwl;
+               else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm_helper_translate_curve_to_hw_format(stream->ctx,
+                                       stream->func_shaper,
+                                       &dpp_base->shaper_params, true);
+                       shaper_lut = &dpp_base->shaper_params;
+               }
+       }
+
+       if (stream->lut3d_func &&
+               stream->lut3d_func->state.bits.initialized == 1) {
+
+               result = mpc->funcs->program_3dlut(mpc,
+                                                               &stream->lut3d_func->lut_3d,
+                                                               mpcc_id);
+
+               result = mpc->funcs->program_shaper(mpc,
+                                                               shaper_lut,
+                                                               mpcc_id);
+       }
+
+       return result;
+}
+
+bool dcn32_set_mcm_luts(
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
+{
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+       bool result = true;
+       struct pwl_params *lut_params = NULL;
+
+       // 1D LUT
+       if (plane_state->blend_tf) {
+               if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
+                       lut_params = &plane_state->blend_tf->pwl;
+               else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                       plane_state->blend_tf,
+                                       &dpp_base->regamma_params, false);
+                       lut_params = &dpp_base->regamma_params;
+               }
+       }
+       result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
+
+       // Shaper
+       if (plane_state->in_shaper_func) {
+               if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL)
+                       lut_params = &plane_state->in_shaper_func->pwl;
+               else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       // TODO: dpp_base replace
+                       ASSERT(false);
+                       cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                       plane_state->in_shaper_func,
+                                       &dpp_base->shaper_params, true);
+                       lut_params = &dpp_base->shaper_params;
+               }
+       }
+
+       result = mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+
+       // 3D
+       if (plane_state->lut3d_func && plane_state->lut3d_func->state.bits.initialized == 1)
+               result = mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func->lut_3d, mpcc_id);
+       else
+               result = mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+
+       return result;
+}
+
+bool dcn32_set_input_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct mpc *mpc = dc->res_pool->mpc;
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+
+       enum dc_transfer_func_predefined tf;
+       bool result = true;
+       struct pwl_params *params = NULL;
+
+       if (mpc == NULL || plane_state == NULL)
+               return false;
+
+       tf = TRANSFER_FUNCTION_UNITY;
+
+       if (plane_state->in_transfer_func &&
+               plane_state->in_transfer_func->type == TF_TYPE_PREDEFINED)
+               tf = plane_state->in_transfer_func->tf;
+
+       dpp_base->funcs->dpp_set_pre_degam(dpp_base, tf);
+
+       if (plane_state->in_transfer_func) {
+               if (plane_state->in_transfer_func->type == TF_TYPE_HWPWL)
+                       params = &plane_state->in_transfer_func->pwl;
+               else if (plane_state->in_transfer_func->type == TF_TYPE_DISTRIBUTED_POINTS &&
+                       cm3_helper_translate_curve_to_hw_format(plane_state->in_transfer_func,
+                                       &dpp_base->degamma_params, false))
+                       params = &dpp_base->degamma_params;
+       }
+
+       dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
+
+       if (pipe_ctx->stream_res.opp &&
+                       pipe_ctx->stream_res.opp->ctx &&
+                       hws->funcs.set_mcm_luts)
+               result = hws->funcs.set_mcm_luts(pipe_ctx, plane_state);
+
+       return result;
+}
+
+bool dcn32_set_output_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream)
+{
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+       struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+       struct pwl_params *params = NULL;
+       bool ret = false;
+
+       /* program OGAM or 3DLUT only for the top pipe*/
+       if (resource_is_pipe_type(pipe_ctx, OPP_HEAD)) {
+               /*program shaper and 3dlut in MPC*/
+               ret = dcn32_set_mpc_shaper_3dlut(pipe_ctx, stream);
+               if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
+                       if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
+                               params = &stream->out_transfer_func->pwl;
+                       else if (pipe_ctx->stream->out_transfer_func->type ==
+                                       TF_TYPE_DISTRIBUTED_POINTS &&
+                                       cm3_helper_translate_curve_to_hw_format(
+                                       stream->out_transfer_func,
+                                       &mpc->blender_params, false))
+                               params = &mpc->blender_params;
+                       /* there are no ROM LUTs in OUTGAM */
+                       if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
+                               BREAK_TO_DEBUGGER();
+               }
+       }
+
+       mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+       return ret;
+}
+
+/* Program P-State force value according to if pipe is using SubVP / FPO or not:
+ * 1. Reset P-State force on all pipes first
+ * 2. For each main pipe, force P-State disallow (P-State allow moderated by DMUB)
+ */
+void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context)
+{
+       int i;
+
+       /* Unforce p-state for each pipe if it is not FPO or SubVP.
+        * For FPO and SubVP, if it's already forced disallow, leave
+        * it as disallow.
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = pipe->plane_res.hubp;
+
+               if (!pipe->stream || !(pipe->stream->mall_stream_config.type == SUBVP_MAIN ||
+                   pipe->stream->fpo_in_use)) {
+                       if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
+                               hubp->funcs->hubp_update_force_pstate_disallow(hubp, false);
+               }
+
+               /* Today only FPO uses cursor P-State force. Only clear cursor P-State force
+                * if it's not FPO.
+                */
+               if (!pipe->stream || !pipe->stream->fpo_in_use) {
+                       if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow)
+                               hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, false);
+               }
+       }
+
+       /* Loop through each pipe -- for each subvp main pipe force p-state allow equal to false.
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = pipe->plane_res.hubp;
+
+               if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+                       if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
+                               hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
+               }
+
+               if (pipe->stream && pipe->stream->fpo_in_use) {
+                       if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
+                               hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
+                       /* For now only force cursor p-state disallow for FPO
+                        * Needs to be added for subvp once FW side gets updated
+                        */
+                       if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow)
+                               hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, true);
+               }
+       }
+}
+
+/* Update MALL_SEL register based on if pipe / plane
+ * is a phantom pipe, main pipe, and if using MALL
+ * for SS.
+ */
+void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       unsigned int num_ways = dcn32_calculate_cab_allocation(dc, context);
+       bool cache_cursor = false;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = pipe->plane_res.hubp;
+
+               if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
+                       int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
+
+                       switch (hubp->curs_attr.color_format) {
+                       case CURSOR_MODE_MONO:
+                               cursor_size /= 2;
+                               break;
+                       case CURSOR_MODE_COLOR_1BIT_AND:
+                       case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
+                       case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
+                               cursor_size *= 4;
+                               break;
+
+                       case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
+                       case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
+                       default:
+                               cursor_size *= 8;
+                               break;
+                       }
+
+                       if (cursor_size > 16384)
+                               cache_cursor = true;
+
+                       if (pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                                       hubp->funcs->hubp_update_mall_sel(hubp, 1, false);
+                       } else {
+                               // MALL not supported with Stereo3D
+                               hubp->funcs->hubp_update_mall_sel(hubp,
+                                       num_ways <= dc->caps.cache_num_ways &&
+                                       pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED &&
+                                       pipe->plane_state->address.type !=  PLN_ADDR_TYPE_GRPH_STEREO &&
+                                       !pipe->plane_state->address.tmz_surface ? 2 : 0,
+                                                       cache_cursor);
+                       }
+               }
+       }
+}
+
+/* Program the sub-viewport pipe configuration after the main / phantom pipes
+ * have been programmed in hardware.
+ * 1. Update force P-State for all the main pipes (disallow P-state)
+ * 2. Update MALL_SEL register
+ * 3. Program FORCE_ONE_ROW_FOR_FRAME for main subvp pipes
+ */
+void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       // Don't force p-state disallow -- can't block dummy p-state
+
+       // Update MALL_SEL register for each pipe
+       if (hws && hws->funcs.update_mall_sel)
+               hws->funcs.update_mall_sel(dc, context);
+
+       // Program FORCE_ONE_ROW_FOR_FRAME and CURSOR_REQ_MODE for main subvp pipes
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = pipe->plane_res.hubp;
+
+               if (pipe->stream && hubp && hubp->funcs->hubp_prepare_subvp_buffering) {
+                       /* TODO - remove setting CURSOR_REQ_MODE to 0 for legacy cases
+                        *      - need to investigate single pipe MPO + SubVP case to
+                        *        see if CURSOR_REQ_MODE will be back to 1 for SubVP
+                        *        when it should be 0 for MPO
+                        */
+                       if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+                               hubp->funcs->hubp_prepare_subvp_buffering(hubp, true);
+                       }
+               }
+       }
+}
+
+static void dcn32_initialize_min_clocks(struct dc *dc)
+{
+       struct dc_clocks *clocks = &dc->current_state->bw_ctx.bw.dcn.clk;
+
+       clocks->dcfclk_deep_sleep_khz = DCN3_2_DCFCLK_DS_INIT_KHZ;
+       clocks->dcfclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz * 1000;
+       clocks->socclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].socclk_mhz * 1000;
+       clocks->dramclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].memclk_mhz * 1000;
+       clocks->dppclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dppclk_mhz * 1000;
+       clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
+       clocks->fclk_p_state_change_support = true;
+       clocks->p_state_change_support = true;
+       if (dc->debug.disable_boot_optimizations) {
+               clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000;
+       } else {
+               /* Even though DPG_EN = 1 for the connected display, it still requires the
+                * correct timing so we cannot set DISPCLK to min freq or it could cause
+                * audio corruption. Read current DISPCLK from DENTIST and request the same
+                * freq to ensure that the timing is valid and unchanged.
+                */
+               clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
+       }
+
+       dc->clk_mgr->funcs->update_clocks(
+                       dc->clk_mgr,
+                       dc->current_state,
+                       true);
+}
+
+void dcn32_init_hw(struct dc *dc)
+{
+       struct abm **abms = dc->res_pool->multiple_abms;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+       struct resource_pool *res_pool = dc->res_pool;
+       int i;
+       int edp_num;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       // Initialize the dccg
+       if (res_pool->dccg->funcs->dccg_init)
+               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       if (!dcb->funcs->is_accelerated_mode(dcb)) {
+               hws->funcs.bios_golden_init(dc);
+               hws->funcs.disable_vga(dc->hwseq);
+       }
+
+       // Set default OPTC memory power states
+       if (dc->debug.enable_mem_low_power.bits.optc) {
+               // Shutdown when unassigned and light sleep in VBLANK
+               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.vga) {
+               // Power down VGA memory
+               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
+       }
+
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (res_pool->dccg && res_pool->hubbub) {
+                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+               } else {
+                       // Not all ASICs have DCCG sw component
+                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                                       res_pool->ref_clocks.xtalin_clock_inKhz;
+               }
+       } else
+               ASSERT_CRITICAL(false);
+
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+
+               /* Check for enabled DIG to identify enabled display */
+               if (link->link_enc->funcs->is_dig_enabled &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
+                       link->link_status.link_active = true;
+                       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+                       if (link->link_enc->funcs->fec_is_active &&
+                                       link->link_enc->funcs->fec_is_active(link->link_enc))
+                               link->fec_state = dc_link_fec_enabled;
+               }
+       }
+
+       /* enable_power_gating_plane before dsc_pg_control because
+        * FORCEON = 1 with hw default value on bootup, resume from s3
+        */
+       if (hws->funcs.enable_power_gating_plane)
+               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
+
+       /* we want to turn off all dp displays before doing detection */
+       dc->link_srv->blank_all_dp_displays(dc);
+
+       /* If taking control over from VBIOS, we may want to optimize our first
+        * mode set, so we need to skip powering down pipes until we know which
+        * pipes we want to use.
+        * Otherwise, if taking control is not possible, we need to power
+        * everything down.
+        */
+       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
+               /* Disable boot optimizations means power down everything including PHY, DIG,
+                * and OTG (i.e. the boot is not optimized because we do a full power down).
+                */
+               if (dc->hwss.enable_accelerated_mode && dc->debug.disable_boot_optimizations)
+                       dc->hwss.enable_accelerated_mode(dc, dc->current_state);
+               else
+                       hws->funcs.init_pipes(dc, dc->current_state);
+
+               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
+                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
+
+               dcn32_initialize_min_clocks(dc);
+
+               /* On HW init, allow idle optimizations after pipes have been turned off.
+                *
+                * In certain D3 cases (i.e. BOCO / BOMACO) it's possible that hardware state
+                * is reset (i.e. not in idle at the time hw init is called), but software state
+                * still has idle_optimizations = true, so we must disable idle optimizations first
+                * (i.e. set false), then re-enable (set true).
+                */
+               dc_allow_idle_optimizations(dc, false);
+               dc_allow_idle_optimizations(dc, true);
+       }
+
+       /* In headless boot cases, DIG may be turned
+        * on which causes HW/SW discrepancies.
+        * To avoid this, power down hardware on boot
+        * if DIG is turned on and seamless boot not enabled
+        */
+       if (!dc->config.seamless_boot_edp_requested) {
+               struct dc_link *edp_links[MAX_NUM_EDP];
+               struct dc_link *edp_link;
+
+               dc_get_edp_links(dc, edp_links, &edp_num);
+               if (edp_num) {
+                       for (i = 0; i < edp_num; i++) {
+                               edp_link = edp_links[i];
+                               if (edp_link->link_enc->funcs->is_dig_enabled &&
+                                               edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                                               dc->hwss.edp_backlight_control &&
+                                               dc->hwss.power_down &&
+                                               dc->hwss.edp_power_control) {
+                                       dc->hwss.edp_backlight_control(edp_link, false);
+                                       dc->hwss.power_down(dc);
+                                       dc->hwss.edp_power_control(edp_link, false);
+                               }
+                       }
+               } else {
+                       for (i = 0; i < dc->link_count; i++) {
+                               struct dc_link *link = dc->links[i];
+
+                               if (link->link_enc->funcs->is_dig_enabled &&
+                                               link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
+                                               dc->hwss.power_down) {
+                                       dc->hwss.power_down(dc);
+                                       break;
+                               }
+
+                       }
+               }
+       }
+
+       for (i = 0; i < res_pool->audio_count; i++) {
+               struct audio *audio = res_pool->audios[i];
+
+               audio->funcs->hw_init(audio);
+       }
+
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               if (link->panel_cntl)
+                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (abms[i] != NULL && abms[i]->funcs != NULL)
+                       abms[i]->funcs->abm_init(abms[i], backlight);
+       }
+
+       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
+       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+       if (!dc->debug.disable_clock_gate) {
+               /* enable all DCN clock gating */
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+       }
+
+       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
+               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
+
+       if (dc->clk_mgr->funcs->notify_wm_ranges)
+               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+               dc->res_pool->hubbub->funcs->force_pstate_change_control(
+                               dc->res_pool->hubbub, false, false);
+
+       if (dc->res_pool->hubbub->funcs->init_crb)
+               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+
+       if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0)
+               dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->ctx->dc_bios->vram_info.num_chans, dc->config.sdpif_request_limit_words_per_umc);
+
+       // Get DMCUB capabilities
+       if (dc->ctx->dmub_srv) {
+               dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
+               dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
+               dc->caps.dmub_caps.subvp_psr = dc->ctx->dmub_srv->dmub->feature_caps.subvp_psr_support;
+               dc->caps.dmub_caps.gecc_enable = dc->ctx->dmub_srv->dmub->feature_caps.gecc_enable;
+               dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
+       }
+}
+
+static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
+               int opp_cnt)
+{
+       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
+       int flow_ctrl_cnt;
+
+       if (opp_cnt >= 2)
+               hblank_halved = true;
+
+       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
+                       stream->timing.h_border_left -
+                       stream->timing.h_border_right;
+
+       if (hblank_halved)
+               flow_ctrl_cnt /= 2;
+
+       /* ODM combine 4:1 case */
+       if (opp_cnt == 4)
+               flow_ctrl_cnt /= 2;
+
+       return flow_ctrl_cnt;
+}
+
+static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
+{
+       struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 1;
+
+       ASSERT(dsc);
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               opp_cnt++;
+
+       if (enable) {
+               struct dsc_config dsc_cfg;
+               struct dsc_optc_config dsc_optc_cfg;
+               enum optc_dsc_mode optc_dsc_mode;
+
+               /* Enable DSC hw block */
+               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
+               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
+               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+               dsc_cfg.color_depth = stream->timing.display_color_depth;
+               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
+               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+               ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
+               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+
+               dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
+               dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+                       struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
+
+                       ASSERT(odm_dsc);
+                       odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
+                       odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
+               }
+               dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
+               dsc_cfg.pic_width *= opp_cnt;
+
+               optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
+
+               /* Enable DSC in OPTC */
+               DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+               pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
+                                                       optc_dsc_mode,
+                                                       dsc_optc_cfg.bytes_per_pixel,
+                                                       dsc_optc_cfg.slice_width);
+       } else {
+               /* disable DSC in OPTC */
+               pipe_ctx->stream_res.tg->funcs->set_dsc_config(
+                               pipe_ctx->stream_res.tg,
+                               OPTC_DSC_DISABLED, 0, 0);
+
+               /* disable DSC block */
+               dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+                       ASSERT(odm_pipe->stream_res.dsc);
+                       odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
+               }
+       }
+}
+
+/*
+* Given any pipe_ctx, return the total ODM combine factor, and optionally return
+* the OPPids which are used
+* */
+static unsigned int get_odm_config(struct pipe_ctx *pipe_ctx, unsigned int *opp_instances)
+{
+       unsigned int opp_count = 1;
+       struct pipe_ctx *odm_pipe;
+
+       /* First get to the top pipe */
+       for (odm_pipe = pipe_ctx; odm_pipe->prev_odm_pipe; odm_pipe = odm_pipe->prev_odm_pipe)
+               ;
+
+       /* First pipe is always used */
+       if (opp_instances)
+               opp_instances[0] = odm_pipe->stream_res.opp->inst;
+
+       /* Find and count odm pipes, if any */
+       for (odm_pipe = odm_pipe->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               if (opp_instances)
+                       opp_instances[opp_count] = odm_pipe->stream_res.opp->inst;
+               opp_count++;
+       }
+
+       return opp_count;
+}
+
+void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 0;
+       int opp_inst[MAX_PIPES] = {0};
+       bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
+       struct mpc_dwb_flow_control flow_control;
+       struct mpc *mpc = dc->res_pool->mpc;
+       int i;
+
+       opp_cnt = get_odm_config(pipe_ctx, opp_inst);
+
+       if (opp_cnt > 1)
+               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
+                               pipe_ctx->stream_res.tg,
+                               opp_inst, opp_cnt,
+                               &pipe_ctx->stream->timing);
+       else
+               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+
+       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
+       flow_control.flow_ctrl_mode = 0;
+       flow_control.flow_ctrl_cnt0 = 0x80;
+       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
+       if (mpc->funcs->set_out_rate_control) {
+               for (i = 0; i < opp_cnt; ++i) {
+                       mpc->funcs->set_out_rate_control(
+                                       mpc, opp_inst[i],
+                                       true,
+                                       rate_control_2x_pclk,
+                                       &flow_control);
+               }
+       }
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
+                               odm_pipe->stream_res.opp,
+                               true);
+       }
+
+       if (pipe_ctx->stream_res.dsc) {
+               struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
+
+               update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
+
+               /* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
+               if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
+                               current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
+                       struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
+                       /* disconnect DSC block from stream */
+                       dsc->funcs->dsc_disconnect(dsc);
+               }
+       }
+}
+
+unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div)
+{
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       unsigned int odm_combine_factor = 0;
+       bool two_pix_per_container = false;
+
+       two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
+       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+
+       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               *k1_div = PIXEL_RATE_DIV_BY_1;
+               *k2_div = PIXEL_RATE_DIV_BY_1;
+       } else if (dc_is_hdmi_tmds_signal(stream->signal) || dc_is_dvi_signal(stream->signal)) {
+               *k1_div = PIXEL_RATE_DIV_BY_1;
+               if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+                       *k2_div = PIXEL_RATE_DIV_BY_2;
+               else
+                       *k2_div = PIXEL_RATE_DIV_BY_4;
+       } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) {
+               if (two_pix_per_container) {
+                       *k1_div = PIXEL_RATE_DIV_BY_1;
+                       *k2_div = PIXEL_RATE_DIV_BY_2;
+               } else {
+                       *k1_div = PIXEL_RATE_DIV_BY_1;
+                       *k2_div = PIXEL_RATE_DIV_BY_4;
+                       if ((odm_combine_factor == 2) || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx))
+                               *k2_div = PIXEL_RATE_DIV_BY_2;
+               }
+       }
+
+       if ((*k1_div == PIXEL_RATE_DIV_NA) && (*k2_div == PIXEL_RATE_DIV_NA))
+               ASSERT(false);
+
+       return odm_combine_factor;
+}
+
+void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
+{
+       uint32_t pix_per_cycle = 1;
+       uint32_t odm_combine_factor = 1;
+
+       if (!pipe_ctx || !pipe_ctx->stream || !pipe_ctx->stream_res.stream_enc)
+               return;
+
+       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+       if (optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing) || odm_combine_factor > 1
+               || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx))
+               pix_per_cycle = 2;
+
+       if (pipe_ctx->stream_res.stream_enc->funcs->set_input_mode)
+               pipe_ctx->stream_res.stream_enc->funcs->set_input_mode(pipe_ctx->stream_res.stream_enc,
+                               pix_per_cycle);
+}
+
+void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
+{
+       unsigned int i;
+       struct pipe_ctx *pipe = NULL;
+       bool otg_disabled[MAX_PIPES] = {false};
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (!resource_is_pipe_type(pipe, OTG_MASTER))
+                       continue;
+
+               if ((pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))
+                       && pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+                       pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
+                       reset_sync_context_for_pipe(dc, context, i);
+                       otg_disabled[i] = true;
+               }
+       }
+
+       hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (otg_disabled[i])
+                       pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+       }
+}
+
+void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings)
+{
+       struct encoder_unblank_param params = {0};
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct dc_link *link = stream->link;
+       struct dce_hwseq *hws = link->dc->hwseq;
+       struct pipe_ctx *odm_pipe;
+       uint32_t pix_per_cycle = 1;
+
+       params.opp_cnt = 1;
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               params.opp_cnt++;
+
+       /* only 3 items below are used by unblank */
+       params.timing = pipe_ctx->stream->timing;
+
+       params.link_settings.link_rate = link_settings->link_rate;
+
+       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
+               /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
+               pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
+                               pipe_ctx->stream_res.hpo_dp_stream_enc,
+                               pipe_ctx->stream_res.tg->inst);
+       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1
+                       || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx)) {
+                       params.timing.pix_clk_100hz /= 2;
+                       pix_per_cycle = 2;
+               }
+               pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine(
+                               pipe_ctx->stream_res.stream_enc, pix_per_cycle > 1);
+               pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
+       }
+
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP)
+               hws->funcs.edp_backlight_control(link, true);
+}
+
+bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
+{
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
+
+       if (!is_h_timing_divisible_by_2(pipe_ctx->stream))
+               return false;
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) &&
+               dc->debug.enable_dp_dig_pixel_rate_div_policy)
+               return true;
+       return false;
+}
+
+static void apply_symclk_on_tx_off_wa(struct dc_link *link)
+{
+       /* There are use cases where SYMCLK is referenced by OTG. For instance
+        * for TMDS signal, OTG relies SYMCLK even if TX video output is off.
+        * However current link interface will power off PHY when disabling link
+        * output. This will turn off SYMCLK generated by PHY. The workaround is
+        * to identify such case where SYMCLK is still in use by OTG when we
+        * power off PHY. When this is detected, we will temporarily power PHY
+        * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
+        * program_pix_clk interface. When OTG is disabled, we will then power
+        * off PHY by calling disable link output again.
+        *
+        * In future dcn generations, we plan to rework transmitter control
+        * interface so that we could have an option to set SYMCLK ON TX OFF
+        * state in one step without this workaround
+        */
+
+       struct dc *dc = link->ctx->dc;
+       struct pipe_ctx *pipe_ctx = NULL;
+       uint8_t i;
+
+       if (link->phy_state.symclk_ref_cnts.otg > 0) {
+               for (i = 0; i < MAX_PIPES; i++) {
+                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+                       if (resource_is_pipe_type(pipe_ctx, OPP_HEAD) && pipe_ctx->stream->link == link) {
+                               pipe_ctx->clock_source->funcs->program_pix_clk(
+                                               pipe_ctx->clock_source,
+                                               &pipe_ctx->stream_res.pix_clk_params,
+                                               dc->link_srv->dp_get_encoding_format(
+                                                               &pipe_ctx->link_config.dp_link_settings),
+                                               &pipe_ctx->pll_settings);
+                               link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+                               break;
+                       }
+               }
+       }
+}
+
+void dcn32_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal)
+{
+       struct dc *dc = link->ctx->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control &&
+                       !link->skip_implict_edp_power_control)
+               link->dc->hwss.edp_backlight_control(link, false);
+       else if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       link_hwss->disable_link_output(link, link_res, signal);
+       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control &&
+                       !link->skip_implict_edp_power_control)
+               link->dc->hwss.edp_power_control(link, false);
+       else if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+
+       apply_symclk_on_tx_off_wa(link);
+}
+
+/* For SubVP the main pipe can have a viewport position change
+ * without a full update. In this case we must also update the
+ * viewport positions for the phantom pipe accordingly.
+ */
+void dcn32_update_phantom_vp_position(struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *phantom_pipe)
+{
+       uint32_t i;
+       struct dc_plane_state *phantom_plane = phantom_pipe->plane_state;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN &&
+                               pipe->stream->mall_stream_config.paired_stream == phantom_pipe->stream) {
+                       if (pipe->plane_state && pipe->plane_state->update_flags.bits.position_change) {
+
+                               phantom_plane->src_rect.x = pipe->plane_state->src_rect.x;
+                               phantom_plane->src_rect.y = pipe->plane_state->src_rect.y;
+                               phantom_plane->clip_rect.x = pipe->plane_state->clip_rect.x;
+                               phantom_plane->dst_rect.x = pipe->plane_state->dst_rect.x;
+                               phantom_plane->dst_rect.y = pipe->plane_state->dst_rect.y;
+
+                               phantom_pipe->plane_state->update_flags.bits.position_change = 1;
+                               resource_build_scaling_params(phantom_pipe);
+                               return;
+                       }
+               }
+       }
+}
+
+/* Treat the phantom pipe as if it needs to be fully enabled.
+ * If the pipe was previously in use but not phantom, it would
+ * have been disabled earlier in the sequence so we need to run
+ * the full enable sequence.
+ */
+void dcn32_apply_update_flags_for_phantom(struct pipe_ctx *phantom_pipe)
+{
+       phantom_pipe->update_flags.raw = 0;
+       if (phantom_pipe->stream && phantom_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+               if (resource_is_pipe_type(phantom_pipe, DPP_PIPE)) {
+                       phantom_pipe->update_flags.bits.enable = 1;
+                       phantom_pipe->update_flags.bits.mpcc = 1;
+                       phantom_pipe->update_flags.bits.dppclk = 1;
+                       phantom_pipe->update_flags.bits.hubp_interdependent = 1;
+                       phantom_pipe->update_flags.bits.hubp_rq_dlg_ttu = 1;
+                       phantom_pipe->update_flags.bits.gamut_remap = 1;
+                       phantom_pipe->update_flags.bits.scaler = 1;
+                       phantom_pipe->update_flags.bits.viewport = 1;
+                       phantom_pipe->update_flags.bits.det_size = 1;
+                       if (resource_is_pipe_type(phantom_pipe, OTG_MASTER)) {
+                               phantom_pipe->update_flags.bits.odm = 1;
+                               phantom_pipe->update_flags.bits.global_sync = 1;
+                       }
+               }
+       }
+}
+
+bool dcn32_dsc_pg_status(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst)
+{
+       uint32_t pwr_status = 0;
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_GET(DOMAIN16_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
+               break;
+       case 1: /* DSC1 */
+
+               REG_GET(DOMAIN17_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
+               break;
+       case 2: /* DSC2 */
+               REG_GET(DOMAIN18_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
+               break;
+       case 3: /* DSC3 */
+               REG_GET(DOMAIN19_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, &pwr_status);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       return pwr_status == 0;
+}
+
+void dcn32_update_dsc_pg(struct dc *dc,
+               struct dc_state *context,
+               bool safe_to_disable)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       int i;
+
+       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+               struct display_stream_compressor *dsc = dc->res_pool->dscs[i];
+               bool is_dsc_ungated = hws->funcs.dsc_pg_status(hws, dsc->inst);
+
+               if (context->res_ctx.is_dsc_acquired[i]) {
+                       if (!is_dsc_ungated) {
+                               hws->funcs.dsc_pg_control(hws, dsc->inst, true);
+                       }
+               } else if (safe_to_disable) {
+                       if (is_dsc_ungated) {
+                               hws->funcs.dsc_pg_control(hws, dsc->inst, false);
+                       }
+               }
+       }
+}
+
+void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context)
+{
+       unsigned int i;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               /* If an active, non-phantom pipe is being transitioned into a phantom
+                * pipe, wait for the double buffer update to complete first before we do
+                * ANY phantom pipe programming.
+                */
+               if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM &&
+                               old_pipe->stream && old_pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+                       old_pipe->stream_res.tg->funcs->wait_for_state(
+                                       old_pipe->stream_res.tg,
+                                       CRTC_STATE_VBLANK);
+                       old_pipe->stream_res.tg->funcs->wait_for_state(
+                                       old_pipe->stream_res.tg,
+                                       CRTC_STATE_VACTIVE);
+               }
+       }
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       // If old context or new context has phantom pipes, apply
+                       // the phantom timings now. We can't change the phantom
+                       // pipe configuration safely without driver acquiring
+                       // the DMCUB lock first.
+                       dc->hwss.apply_ctx_to_hw(dc, context);
+                       break;
+               }
+       }
+}
+
+/* Blank pixel data during initialization */
+void dcn32_init_blank(
+               struct dc *dc,
+               struct timing_generator *tg)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       enum dc_color_space color_space;
+       struct tg_color black_color = {0};
+       struct output_pixel_processor *opp = NULL;
+       struct output_pixel_processor *bottom_opp = NULL;
+       uint32_t num_opps, opp_id_src0, opp_id_src1;
+       uint32_t otg_active_width, otg_active_height;
+       uint32_t i;
+
+       /* program opp dpg blank color */
+       color_space = COLOR_SPACE_SRGB;
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       /* get the OTG active size */
+       tg->funcs->get_otg_active_size(tg,
+                       &otg_active_width,
+                       &otg_active_height);
+
+       /* get the OPTC source */
+       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+
+       if (opp_id_src0 >= dc->res_pool->res_cap->num_opp) {
+               ASSERT(false);
+               return;
+       }
+
+       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+               if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
+                       opp = dc->res_pool->opps[i];
+                       break;
+               }
+       }
+
+       if (num_opps == 2) {
+               otg_active_width = otg_active_width / 2;
+
+               if (opp_id_src1 >= dc->res_pool->res_cap->num_opp) {
+                       ASSERT(false);
+                       return;
+               }
+               for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+                       if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src1) {
+                               bottom_opp = dc->res_pool->opps[i];
+                               break;
+                       }
+               }
+       }
+
+       if (opp && opp->funcs->opp_set_disp_pattern_generator)
+               opp->funcs->opp_set_disp_pattern_generator(
+                               opp,
+                               CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+                               CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+                               COLOR_DEPTH_UNDEFINED,
+                               &black_color,
+                               otg_active_width,
+                               otg_active_height,
+                               0);
+
+       if (num_opps == 2) {
+               if (bottom_opp && bottom_opp->funcs->opp_set_disp_pattern_generator) {
+                       bottom_opp->funcs->opp_set_disp_pattern_generator(
+                                       bottom_opp,
+                                       CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+                                       CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+                                       COLOR_DEPTH_UNDEFINED,
+                                       &black_color,
+                                       otg_active_width,
+                                       otg_active_height,
+                                       0);
+                       hws->funcs.wait_for_blank_complete(bottom_opp);
+               }
+       }
+
+       if (opp)
+               hws->funcs.wait_for_blank_complete(opp);
+}
+
+void dcn32_blank_phantom(struct dc *dc,
+               struct timing_generator *tg,
+               int width,
+               int height)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       enum dc_color_space color_space;
+       struct tg_color black_color = {0};
+       struct output_pixel_processor *opp = NULL;
+       uint32_t num_opps, opp_id_src0, opp_id_src1;
+       uint32_t otg_active_width, otg_active_height;
+       uint32_t i;
+
+       /* program opp dpg blank color */
+       color_space = COLOR_SPACE_SRGB;
+       color_space_to_black_color(dc, color_space, &black_color);
+
+       otg_active_width = width;
+       otg_active_height = height;
+
+       /* get the OPTC source */
+       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+       ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
+
+       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+               if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
+                       opp = dc->res_pool->opps[i];
+                       break;
+               }
+       }
+
+       if (opp && opp->funcs->opp_set_disp_pattern_generator)
+               opp->funcs->opp_set_disp_pattern_generator(
+                               opp,
+                               CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+                               CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+                               COLOR_DEPTH_UNDEFINED,
+                               &black_color,
+                               otg_active_width,
+                               otg_active_height,
+                               0);
+
+       if (tg->funcs->is_tg_enabled(tg))
+               hws->funcs.wait_for_blank_complete(opp);
+}
+
+bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
+               const struct dc_state *cur_ctx,
+               const struct dc_state *new_ctx)
+{
+       int i;
+       const struct pipe_ctx *cur_pipe, *new_pipe;
+       bool is_seamless = true;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               cur_pipe = &cur_ctx->res_ctx.pipe_ctx[i];
+               new_pipe = &new_ctx->res_ctx.pipe_ctx[i];
+
+               if (resource_is_pipe_type(cur_pipe, FREE_PIPE) ||
+                               resource_is_pipe_type(new_pipe, FREE_PIPE))
+                       /* adding or removing free pipes is always seamless */
+                       continue;
+               else if (resource_is_pipe_type(cur_pipe, OTG_MASTER)) {
+                       if (resource_is_pipe_type(new_pipe, OTG_MASTER))
+                               if (cur_pipe->stream->stream_id == new_pipe->stream->stream_id)
+                               /* OTG master with the same stream is seamless */
+                                       continue;
+               } else if (resource_is_pipe_type(cur_pipe, OPP_HEAD)) {
+                       if (resource_is_pipe_type(new_pipe, OPP_HEAD)) {
+                               if (cur_pipe->stream_res.tg == new_pipe->stream_res.tg)
+                                       /*
+                                        * OPP heads sharing the same timing
+                                        * generator is seamless
+                                        */
+                                       continue;
+                       }
+               } else if (resource_is_pipe_type(cur_pipe, DPP_PIPE)) {
+                       if (resource_is_pipe_type(new_pipe, DPP_PIPE)) {
+                               if (cur_pipe->stream_res.opp == new_pipe->stream_res.opp)
+                                       /*
+                                        * DPP pipes sharing the same OPP head is
+                                        * seamless
+                                        */
+                                       continue;
+                       }
+               }
+
+               /*
+                * This pipe's transition doesn't fall under any seamless
+                * conditions
+                */
+               is_seamless = false;
+               break;
+       }
+
+       return is_seamless;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
new file mode 100644 (file)
index 0000000..9992e40
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+* 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 __DC_HWSS_DCN32_H__
+#define __DC_HWSS_DCN32_H__
+
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dcn32_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on);
+
+void dcn32_enable_power_gating_plane(
+       struct dce_hwseq *hws,
+       bool enable);
+
+void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
+
+bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable);
+
+void dcn32_cab_for_ss_control(struct dc *dc, bool enable);
+
+void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context);
+
+bool dcn32_set_mcm_luts(struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state);
+
+bool dcn32_set_input_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state);
+
+bool dcn32_set_mpc_shaper_3dlut(
+       struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream);
+
+bool dcn32_set_output_transfer_func(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream);
+
+void dcn32_init_hw(struct dc *dc);
+
+void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context);
+
+void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context);
+
+void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context);
+
+void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
+
+unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div);
+
+void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
+
+void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
+
+void dcn32_subvp_pipe_control_lock(struct dc *dc,
+               struct dc_state *context,
+               bool lock,
+               bool should_lock_all_pipes,
+               struct pipe_ctx *top_pipe_to_program,
+               bool subvp_prev_use);
+
+void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params);
+
+void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
+               struct dc_link_settings *link_settings);
+
+bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx);
+
+void dcn32_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal);
+
+void dcn32_update_phantom_vp_position(struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *phantom_pipe);
+
+void dcn32_apply_update_flags_for_phantom(struct pipe_ctx *phantom_pipe);
+
+bool dcn32_dsc_pg_status(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst);
+
+void dcn32_update_dsc_pg(struct dc *dc,
+               struct dc_state *context,
+               bool safe_to_disable);
+
+void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context);
+
+void dcn32_init_blank(
+               struct dc *dc,
+               struct timing_generator *tg);
+
+void dcn32_blank_phantom(struct dc *dc,
+               struct timing_generator *tg,
+               int width,
+               int height);
+
+bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
+               const struct dc_state *cur_ctx,
+               const struct dc_state *new_ctx);
+
+#endif /* __DC_HWSS_DCN32_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
new file mode 100644 (file)
index 0000000..0e218f9
--- /dev/null
@@ -0,0 +1,1205 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2023 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.
+ *
+ */
+
+#include "dm_services.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "resource.h"
+#include "dccg.h"
+#include "dce/dce_hwseq.h"
+#include "clk_mgr.h"
+#include "reg_helper.h"
+#include "abm.h"
+#include "hubp.h"
+#include "dchubbub.h"
+#include "timing_generator.h"
+#include "opp.h"
+#include "ipp.h"
+#include "mpc.h"
+#include "mcif_wb.h"
+#include "dc_dmub_srv.h"
+#include "dcn35_hwseq.h"
+#include "dcn35/dcn35_dccg.h"
+#include "link_hwss.h"
+#include "dpcd_defs.h"
+#include "dce/dmub_outbox.h"
+#include "link.h"
+#include "dcn10/dcn10_hwseq.h"
+#include "inc/link_enc_cfg.h"
+#include "dcn30/dcn30_vpg.h"
+#include "dce/dce_i2c_hw.h"
+#include "dsc.h"
+#include "dcn20/dcn20_optc.h"
+#include "dcn30/dcn30_cm_common.h"
+#include "dcn31/dcn31_hwseq.h"
+#include "dcn20/dcn20_hwseq.h"
+
+#define DC_LOGGER_INIT(logger) \
+       struct dal_logger *dc_logger = logger
+
+#define CTX \
+       hws->ctx
+#define REG(reg)\
+       hws->regs->reg
+#define DC_LOGGER \
+       dc_logger
+
+
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
+#if 0
+static void enable_memory_low_power(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       int i;
+
+       if (dc->debug.enable_mem_low_power.bits.dmcu) {
+               // Force ERAM to shutdown if DMCU is not enabled
+               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
+                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
+               }
+       }
+       /*dcn35 has default MEM_PWR enabled, make sure wake them up*/
+       // Set default OPTC memory power states
+       if (dc->debug.enable_mem_low_power.bits.optc) {
+               // Shutdown when unassigned and light sleep in VBLANK
+               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.vga) {
+               // Power down VGA memory
+               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.mpc &&
+               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode)
+               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
+
+       if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
+               // Power down VPGs
+               for (i = 0; i < dc->res_pool->stream_enc_count; i++)
+                       dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
+#if defined(CONFIG_DRM_AMD_DC_DP2_0)
+               for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
+                       dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
+#endif
+       }
+
+}
+#endif
+
+void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable)
+{
+       REG_UPDATE_3(DMU_CLK_CNTL,
+               RBBMIF_FGCG_REP_DIS, !enable,
+               IHC_FGCG_REP_DIS, !enable,
+               LONO_FGCG_REP_DIS, !enable
+       );
+}
+
+void dcn35_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
+{
+       REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
+}
+
+void dcn35_init_hw(struct dc *dc)
+{
+       struct abm **abms = dc->res_pool->multiple_abms;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct dc_bios *dcb = dc->ctx->dc_bios;
+       struct resource_pool *res_pool = dc->res_pool;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+       int i;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+               dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+       REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+       REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0x3F000000);
+       REG_WRITE(DCCG_GATE_DISABLE_CNTL5, 0x1f7c3fcf);
+
+       //dcn35_set_dmu_fgcg(hws, dc->debug.enable_fine_grain_clock_gating.bits.dmu);
+
+       if (!dcb->funcs->is_accelerated_mode(dcb)) {
+               /*this calls into dmubfw to do the init*/
+               hws->funcs.bios_golden_init(dc);
+       }
+       // Initialize the dccg
+       if (res_pool->dccg->funcs->dccg_init)
+               res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+
+       //enable_memory_low_power(dc);
+
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (res_pool->dccg && res_pool->hubbub) {
+
+                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                               &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                               res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                               &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+               } else {
+                       // Not all ASICs have DCCG sw component
+                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                               res_pool->ref_clocks.xtalin_clock_inKhz;
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                               res_pool->ref_clocks.xtalin_clock_inKhz;
+               }
+       } else
+               ASSERT_CRITICAL(false);
+
+       for (i = 0; i < dc->link_count; i++) {
+               /* Power up AND update implementation according to the
+                * required signal (which may be different from the
+                * default signal on connector).
+                */
+               struct dc_link *link = dc->links[i];
+
+               if (link->ep_type != DISPLAY_ENDPOINT_PHY)
+                       continue;
+
+               link->link_enc->funcs->hw_init(link->link_enc);
+
+               /* Check for enabled DIG to identify enabled display */
+               if (link->link_enc->funcs->is_dig_enabled &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
+                       link->link_status.link_active = true;
+                       if (link->link_enc->funcs->fec_is_active &&
+                                       link->link_enc->funcs->fec_is_active(link->link_enc))
+                               link->fec_state = dc_link_fec_enabled;
+               }
+       }
+
+       /* we want to turn off all dp displays before doing detection */
+       dc->link_srv->blank_all_dp_displays(dc);
+/*
+       if (hws->funcs.enable_power_gating_plane)
+               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
+*/
+       if (res_pool->hubbub->funcs->dchubbub_init)
+               res_pool->hubbub->funcs->dchubbub_init(dc->res_pool->hubbub);
+       /* If taking control over from VBIOS, we may want to optimize our first
+        * mode set, so we need to skip powering down pipes until we know which
+        * pipes we want to use.
+        * Otherwise, if taking control is not possible, we need to power
+        * everything down.
+        */
+       if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
+
+               // we want to turn off edp displays if odm is enabled and no seamless boot
+               if (!dc->caps.seamless_odm) {
+                       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+                               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+                               uint32_t num_opps, opp_id_src0, opp_id_src1;
+
+                               num_opps = 1;
+                               if (tg) {
+                                       if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) {
+                                               tg->funcs->get_optc_source(tg, &num_opps,
+                                                               &opp_id_src0, &opp_id_src1);
+                                       }
+                               }
+
+                               if (num_opps > 1) {
+                                       dc->link_srv->blank_all_edp_displays(dc);
+                                       break;
+                               }
+                       }
+               }
+
+               hws->funcs.init_pipes(dc, dc->current_state);
+               if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+                       dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
+                                       !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
+       }
+
+       for (i = 0; i < res_pool->audio_count; i++) {
+               struct audio *audio = res_pool->audios[i];
+
+               audio->funcs->hw_init(audio);
+       }
+
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               if (link->panel_cntl)
+                       backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
+       }
+       if (dc->ctx->dmub_srv) {
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (abms[i] != NULL && abms[i]->funcs != NULL)
+                       abms[i]->funcs->abm_init(abms[i], backlight);
+               }
+       }
+
+       /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
+       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+       // Set i2c to light sleep until engine is setup
+       if (dc->debug.enable_mem_low_power.bits.i2c)
+               REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 0);
+
+       if (hws->funcs.setup_hpo_hw_control)
+               hws->funcs.setup_hpo_hw_control(hws, false);
+
+       if (!dc->debug.disable_clock_gate) {
+               /* enable all DCN clock gating */
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+       }
+
+       if (dc->debug.disable_mem_low_power) {
+               REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
+       }
+       if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
+               dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
+
+       if (dc->clk_mgr->funcs->notify_wm_ranges)
+               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+       if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+               dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+
+
+       if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+               dc->res_pool->hubbub->funcs->force_pstate_change_control(
+                               dc->res_pool->hubbub, false, false);
+
+       if (dc->res_pool->hubbub->funcs->init_crb)
+               dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+
+       if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0)
+               dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->ctx->dc_bios->vram_info.num_chans, dc->config.sdpif_request_limit_words_per_umc);
+       // Get DMCUB capabilities
+       if (dc->ctx->dmub_srv) {
+               dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
+               dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
+               dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
+       }
+
+       if (dc->res_pool->pg_cntl) {
+               if (dc->res_pool->pg_cntl->funcs->init_pg_status)
+                       dc->res_pool->pg_cntl->funcs->init_pg_status(dc->res_pool->pg_cntl);
+       }
+}
+
+static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
+               int opp_cnt)
+{
+       bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
+       int flow_ctrl_cnt;
+
+       if (opp_cnt >= 2)
+               hblank_halved = true;
+
+       flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
+                       stream->timing.h_border_left -
+                       stream->timing.h_border_right;
+
+       if (hblank_halved)
+               flow_ctrl_cnt /= 2;
+
+       /* ODM combine 4:1 case */
+       if (opp_cnt == 4)
+               flow_ctrl_cnt /= 2;
+
+       return flow_ctrl_cnt;
+}
+
+static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
+{
+       struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+       struct dc_stream_state *stream = pipe_ctx->stream;
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 1;
+
+       DC_LOGGER_INIT(stream->ctx->logger);
+
+       ASSERT(dsc);
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               opp_cnt++;
+
+       if (enable) {
+               struct dsc_config dsc_cfg;
+               struct dsc_optc_config dsc_optc_cfg;
+               enum optc_dsc_mode optc_dsc_mode;
+
+               /* Enable DSC hw block */
+               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
+               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
+               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+               dsc_cfg.color_depth = stream->timing.display_color_depth;
+               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
+               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+               ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
+               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+
+               dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
+               dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+                       struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
+
+                       ASSERT(odm_dsc);
+                       odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
+                       odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
+               }
+               dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
+               dsc_cfg.pic_width *= opp_cnt;
+
+               optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
+
+               /* Enable DSC in OPTC */
+               DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+               pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
+                                                       optc_dsc_mode,
+                                                       dsc_optc_cfg.bytes_per_pixel,
+                                                       dsc_optc_cfg.slice_width);
+       } else {
+               /* disable DSC in OPTC */
+               pipe_ctx->stream_res.tg->funcs->set_dsc_config(
+                               pipe_ctx->stream_res.tg,
+                               OPTC_DSC_DISABLED, 0, 0);
+
+               /* disable DSC block */
+               dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+                       ASSERT(odm_pipe->stream_res.dsc);
+                       odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
+               }
+       }
+}
+
+// Given any pipe_ctx, return the total ODM combine factor, and optionally return
+// the OPPids which are used
+static unsigned int get_odm_config(struct pipe_ctx *pipe_ctx, unsigned int *opp_instances)
+{
+       unsigned int opp_count = 1;
+       struct pipe_ctx *odm_pipe;
+
+       // First get to the top pipe
+       for (odm_pipe = pipe_ctx; odm_pipe->prev_odm_pipe; odm_pipe = odm_pipe->prev_odm_pipe)
+               ;
+
+       // First pipe is always used
+       if (opp_instances)
+               opp_instances[0] = odm_pipe->stream_res.opp->inst;
+
+       // Find and count odm pipes, if any
+       for (odm_pipe = odm_pipe->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               if (opp_instances)
+                       opp_instances[opp_count] = odm_pipe->stream_res.opp->inst;
+               opp_count++;
+       }
+
+       return opp_count;
+}
+
+void dcn35_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *odm_pipe;
+       int opp_cnt = 0;
+       int opp_inst[MAX_PIPES] = {0};
+       bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
+       struct mpc_dwb_flow_control flow_control;
+       struct mpc *mpc = dc->res_pool->mpc;
+       int i;
+
+       opp_cnt = get_odm_config(pipe_ctx, opp_inst);
+
+       if (opp_cnt > 1)
+               pipe_ctx->stream_res.tg->funcs->set_odm_combine(
+                               pipe_ctx->stream_res.tg,
+                               opp_inst, opp_cnt,
+                               &pipe_ctx->stream->timing);
+       else
+               pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
+                               pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+
+       rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
+       flow_control.flow_ctrl_mode = 0;
+       flow_control.flow_ctrl_cnt0 = 0x80;
+       flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
+       if (mpc->funcs->set_out_rate_control) {
+               for (i = 0; i < opp_cnt; ++i) {
+                       mpc->funcs->set_out_rate_control(
+                                       mpc, opp_inst[i],
+                                       true,
+                                       rate_control_2x_pclk,
+                                       &flow_control);
+               }
+       }
+
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+               odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
+                               odm_pipe->stream_res.opp,
+                               true);
+       }
+
+       if (pipe_ctx->stream_res.dsc) {
+               struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
+
+               update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
+
+               /* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
+               if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
+                               current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
+                       struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
+                       /* disconnect DSC block from stream */
+                       dsc->funcs->dsc_disconnect(dsc);
+               }
+       }
+}
+
+void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on)
+{
+       if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
+               return;
+
+       if (hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control) {
+               hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control(
+                       hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on);
+       }
+}
+
+void dcn35_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on)
+{
+       uint32_t power_gate = power_on ? 0 : 1;
+       uint32_t pwr_status = power_on ? 0 : 2;
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_dsc_power_gate)
+               return;
+       if (hws->ctx->dc->debug.ignore_pg)
+               return;
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
+       switch (dsc_inst) {
+       case 0: /* DSC0 */
+               REG_UPDATE(DOMAIN16_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN16_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 1: /* DSC1 */
+               REG_UPDATE(DOMAIN17_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN17_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 2: /* DSC2 */
+               REG_UPDATE(DOMAIN18_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN18_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       case 3: /* DSC3 */
+               REG_UPDATE(DOMAIN19_PG_CONFIG,
+                               DOMAIN_POWER_GATE, power_gate);
+
+               REG_WAIT(DOMAIN19_PG_STATUS,
+                               DOMAIN_PGFSM_PWR_STATUS, pwr_status,
+                               1, 1000);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+}
+
+void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable)
+{
+       bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
+
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
+               return;
+       if (hws->ctx->dc->debug.ignore_pg)
+               return;
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+       /* DCHUBP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       /* DPP0/1/2/3/4/5 */
+       REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       force_on = true; /* disable power gating */
+       if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
+               force_on = false;
+
+       /* DCS0/1/2/3/4 */
+       REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+       REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+
+}
+
+/* In headless boot cases, DIG may be turned
+ * on which causes HW/SW discrepancies.
+ * To avoid this, power down hardware on boot
+ * if DIG is turned on
+ */
+void dcn35_power_down_on_boot(struct dc *dc)
+{
+       struct dc_link *edp_links[MAX_NUM_EDP];
+       struct dc_link *edp_link = NULL;
+       int edp_num;
+       int i = 0;
+
+       dc_get_edp_links(dc, edp_links, &edp_num);
+       if (edp_num)
+               edp_link = edp_links[0];
+
+       if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
+                       edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                       dc->hwseq->funcs.edp_backlight_control &&
+                       dc->hwss.power_down &&
+                       dc->hwss.edp_power_control) {
+               dc->hwseq->funcs.edp_backlight_control(edp_link, false);
+               dc->hwss.power_down(dc);
+               dc->hwss.edp_power_control(edp_link, false);
+       } else {
+               for (i = 0; i < dc->link_count; i++) {
+                       struct dc_link *link = dc->links[i];
+
+                       if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
+                                       link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
+                                       dc->hwss.power_down) {
+                               dc->hwss.power_down(dc);
+                               break;
+                       }
+
+               }
+       }
+
+       /*
+        * Call update_clocks with empty context
+        * to send DISPLAY_OFF
+        * Otherwise DISPLAY_OFF may not be asserted
+        */
+       if (dc->clk_mgr->funcs->set_low_power_state)
+               dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
+
+       if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER) {
+               if (!dc->idle_optimizations_allowed) {
+                       dc_dmub_srv_notify_idle(dc, true);
+                       dc->idle_optimizations_allowed = true;
+               }
+       }
+}
+
+bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
+{
+       struct dc_link *edp_links[MAX_NUM_EDP];
+       int edp_num;
+       if (dc->debug.dmcub_emulation)
+               return true;
+
+       if (enable) {
+               dc_get_edp_links(dc, edp_links, &edp_num);
+               if (edp_num == 0 || edp_num > 1)
+                       return false;
+       }
+
+       // TODO: review other cases when idle optimization is allowed
+
+       if (!enable)
+               dc_dmub_srv_exit_low_power_state(dc);
+       else
+               dc_dmub_srv_notify_idle(dc, enable);
+
+       return true;
+}
+
+void dcn35_z10_restore(const struct dc *dc)
+{
+       if (dc->debug.disable_z10)
+               return;
+
+       dc_dmub_srv_exit_low_power_state(dc);
+
+       dcn31_z10_restore(dc);
+}
+
+void dcn35_init_pipes(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct hubbub *hubbub = dc->res_pool->hubbub;
+       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
+       bool can_apply_seamless_boot = false;
+
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->streams[i]->apply_seamless_boot_optimization) {
+                       can_apply_seamless_boot = true;
+                       break;
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* There is assumption that pipe_ctx is not mapping irregularly
+                * to non-preferred front end. If pipe_ctx->stream is not NULL,
+                * we will use the pipe, so don't disable
+                */
+               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+                       continue;
+
+               /* Blank controller using driver code instead of
+                * command table.
+                */
+               if (tg->funcs->is_tg_enabled(tg)) {
+                       if (hws->funcs.init_blank != NULL) {
+                               hws->funcs.init_blank(dc, tg);
+                               tg->funcs->lock(tg);
+                       } else {
+                               tg->funcs->lock(tg);
+                               tg->funcs->set_blank(tg, true);
+                               hwss_wait_for_blank_complete(tg);
+                       }
+               }
+       }
+
+       /* Reset det size */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               struct hubp *hubp = dc->res_pool->hubps[i];
+
+               /* Do not need to reset for seamless boot */
+               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+                       continue;
+
+               if (hubbub && hubp) {
+                       if (hubbub->funcs->program_det_size)
+                               hubbub->funcs->program_det_size(hubbub, hubp->inst, 0);
+               }
+       }
+
+       /* num_opp will be equal to number of mpcc */
+       for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* Cannot reset the MPC mux if seamless boot */
+               if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+                       continue;
+
+               dc->res_pool->mpc->funcs->mpc_init_single_inst(
+                               dc->res_pool->mpc, i);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+               struct hubp *hubp = dc->res_pool->hubps[i];
+               struct dpp *dpp = dc->res_pool->dpps[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               /* There is assumption that pipe_ctx is not mapping irregularly
+                * to non-preferred front end. If pipe_ctx->stream is not NULL,
+                * we will use the pipe, so don't disable
+                */
+               if (can_apply_seamless_boot &&
+                       pipe_ctx->stream != NULL &&
+                       pipe_ctx->stream_res.tg->funcs->is_tg_enabled(
+                               pipe_ctx->stream_res.tg)) {
+                       // Enable double buffering for OTG_BLANK no matter if
+                       // seamless boot is enabled or not to suppress global sync
+                       // signals when OTG blanked. This is to prevent pipe from
+                       // requesting data while in PSR.
+                       tg->funcs->tg_init(tg);
+                       hubp->power_gated = true;
+                       continue;
+               }
+
+               /* Disable on the current state so the new one isn't cleared. */
+               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               dpp->funcs->dpp_reset(dpp);
+
+               pipe_ctx->stream_res.tg = tg;
+               pipe_ctx->pipe_idx = i;
+
+               pipe_ctx->plane_res.hubp = hubp;
+               pipe_ctx->plane_res.dpp = dpp;
+               pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+               hubp->mpcc_id = dpp->inst;
+               hubp->opp_id = OPP_ID_INVALID;
+               hubp->power_gated = false;
+
+               dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+               dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+               dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+               pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
+
+               hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
+
+               if (tg->funcs->is_tg_enabled(tg))
+                       tg->funcs->unlock(tg);
+
+               dc->hwss.disable_plane(dc, pipe_ctx);
+
+               pipe_ctx->stream_res.tg = NULL;
+               pipe_ctx->plane_res.hubp = NULL;
+
+               if (tg->funcs->is_tg_enabled(tg)) {
+                       if (tg->funcs->init_odm)
+                               tg->funcs->init_odm(tg);
+               }
+
+               tg->funcs->tg_init(tg);
+       }
+
+       if (pg_cntl != NULL) {
+               if (pg_cntl->funcs->dsc_pg_control != NULL) {
+                       uint32_t num_opps = 0;
+                       uint32_t opp_id_src0 = OPP_ID_INVALID;
+                       uint32_t opp_id_src1 = OPP_ID_INVALID;
+
+                       // Step 1: To find out which OPTC is running & OPTC DSC is ON
+                       // We can't use res_pool->res_cap->num_timing_generator to check
+                       // Because it records display pipes default setting built in driver,
+                       // not display pipes of the current chip.
+                       // Some ASICs would be fused display pipes less than the default setting.
+                       // In dcnxx_resource_construct function, driver would obatin real information.
+                       for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
+                               uint32_t optc_dsc_state = 0;
+                               struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+                               if (tg->funcs->is_tg_enabled(tg)) {
+                                       if (tg->funcs->get_dsc_status)
+                                               tg->funcs->get_dsc_status(tg, &optc_dsc_state);
+                                       // Only one OPTC with DSC is ON, so if we got one result,
+                                       // we would exit this block. non-zero value is DSC enabled
+                                       if (optc_dsc_state != 0) {
+                                               tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+                                               break;
+                                       }
+                               }
+                       }
+
+                       // Step 2: To power down DSC but skip DSC  of running OPTC
+                       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+                               struct dcn_dsc_state s  = {0};
+
+                               dc->res_pool->dscs[i]->funcs->dsc_read_state(dc->res_pool->dscs[i], &s);
+
+                               if ((s.dsc_opp_source == opp_id_src0 || s.dsc_opp_source == opp_id_src1) &&
+                                       s.dsc_clock_en && s.dsc_fw_en)
+                                       continue;
+
+                               pg_cntl->funcs->dsc_pg_control(pg_cntl, dc->res_pool->dscs[i]->inst, false);
+                       }
+               }
+       }
+}
+
+void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                              struct dc_state *context)
+{
+       /* enable DCFCLK current DCHUB */
+       pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
+
+       /* initialize HUBP on power up */
+       pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp);
+
+       /* make sure OPP_PIPE_CLOCK_EN = 1 */
+       pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+                       pipe_ctx->stream_res.opp,
+                       true);
+       /*to do: insert PG here*/
+       if (dc->vm_pa_config.valid) {
+               struct vm_system_aperture_param apt;
+
+               apt.sys_default.quad_part = 0;
+
+               apt.sys_low.quad_part = dc->vm_pa_config.system_aperture.start_addr;
+               apt.sys_high.quad_part = dc->vm_pa_config.system_aperture.end_addr;
+
+               // Program system aperture settings
+               pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
+       }
+
+       if (!pipe_ctx->top_pipe
+               && pipe_ctx->plane_state
+               && pipe_ctx->plane_state->flip_int_enabled
+               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
+               pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
+}
+
+/* disable HW used by plane.
+ * note:  cannot disable until disconnect is complete
+ */
+void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+
+       dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
+
+       /* In flip immediate with pipe splitting case GSL is used for
+        * synchronization so we must disable it when the plane is disabled.
+        */
+       if (pipe_ctx->stream_res.gsl_group != 0)
+               dcn20_setup_gsl_group_as_lock(dc, pipe_ctx, false);
+/*
+       if (hubp->funcs->hubp_update_mall_sel)
+               hubp->funcs->hubp_update_mall_sel(hubp, 0, false);
+*/
+       dc->hwss.set_flip_control_gsl(pipe_ctx, false);
+
+       hubp->funcs->hubp_clk_cntl(hubp, false);
+
+       dpp->funcs->dpp_dppclk_control(dpp, false, false);
+/*to do, need to support both case*/
+       hubp->power_gated = true;
+
+       dpp->funcs->dpp_reset(dpp);
+
+       pipe_ctx->stream = NULL;
+       memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
+       memset(&pipe_ctx->plane_res, 0, sizeof(pipe_ctx->plane_res));
+       pipe_ctx->top_pipe = NULL;
+       pipe_ctx->bottom_pipe = NULL;
+       pipe_ctx->plane_state = NULL;
+}
+
+void dcn35_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       bool is_phantom = pipe_ctx->plane_state && pipe_ctx->plane_state->is_phantom;
+       struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL;
+
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
+               return;
+
+       if (hws->funcs.plane_atomic_disable)
+               hws->funcs.plane_atomic_disable(dc, pipe_ctx);
+
+       /* Turn back off the phantom OTG after the phantom plane is fully disabled
+        */
+       if (is_phantom)
+               if (tg && tg->funcs->disable_phantom_crtc)
+                       tg->funcs->disable_phantom_crtc(tg);
+
+       DC_LOG_DC("Power down front end %d\n",
+                                       pipe_ctx->pipe_idx);
+}
+
+void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
+       struct pg_block_update *update_state)
+{
+       bool hpo_frl_stream_enc_acquired = false;
+       bool hpo_dp_stream_enc_acquired = false;
+       int i = 0, j = 0;
+
+       memset(update_state, 0, sizeof(struct pg_block_update));
+
+       for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) {
+               if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] &&
+                               dc->res_pool->hpo_dp_stream_enc[i]) {
+                       hpo_dp_stream_enc_acquired = true;
+                       break;
+               }
+       }
+
+       if (!hpo_frl_stream_enc_acquired && !hpo_dp_stream_enc_acquired)
+               update_state->pg_res_update[PG_HPO] = true;
+
+       update_state->pg_res_update[PG_DWB] = true;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++)
+                       update_state->pg_pipe_res_update[j][i] = true;
+
+               if (!pipe_ctx)
+                       continue;
+
+               if (pipe_ctx->plane_res.hubp)
+                       update_state->pg_pipe_res_update[PG_HUBP][pipe_ctx->plane_res.hubp->inst] = false;
+
+               if (pipe_ctx->plane_res.dpp)
+                       update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->plane_res.hubp->inst] = false;
+
+               if ((pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp) &&
+                       pipe_ctx->plane_res.mpcc_inst >= 0)
+                       update_state->pg_pipe_res_update[PG_MPCC][pipe_ctx->plane_res.mpcc_inst] = false;
+
+               if (pipe_ctx->stream_res.dsc)
+                       update_state->pg_pipe_res_update[PG_DSC][pipe_ctx->stream_res.dsc->inst] = false;
+
+               if (pipe_ctx->stream_res.opp)
+                       update_state->pg_pipe_res_update[PG_OPP][pipe_ctx->stream_res.opp->inst] = false;
+
+               if (pipe_ctx->stream_res.tg)
+                       update_state->pg_pipe_res_update[PG_OPTC][pipe_ctx->stream_res.tg->inst] = false;
+       }
+}
+
+void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
+       struct pg_block_update *update_state)
+{
+       bool hpo_frl_stream_enc_acquired = false;
+       bool hpo_dp_stream_enc_acquired = false;
+       int i = 0, j = 0;
+
+       memset(update_state, 0, sizeof(struct pg_block_update));
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *cur_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (cur_pipe == NULL || new_pipe == NULL)
+                       continue;
+
+               if ((!cur_pipe->plane_state && new_pipe->plane_state) ||
+                       (!cur_pipe->stream && new_pipe->stream)) {
+                       // New pipe addition
+                       for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) {
+                               if (j == PG_HUBP && new_pipe->plane_res.hubp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.hubp->inst] = true;
+
+                               if (j == PG_DPP && new_pipe->plane_res.dpp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.dpp->inst] = true;
+
+                               if (j == PG_MPCC && new_pipe->plane_res.dpp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.mpcc_inst] = true;
+
+                               if (j == PG_DSC && new_pipe->stream_res.dsc)
+                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.dsc->inst] = true;
+
+                               if (j == PG_OPP && new_pipe->stream_res.opp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.opp->inst] = true;
+
+                               if (j == PG_OPTC && new_pipe->stream_res.tg)
+                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.tg->inst] = true;
+                       }
+               } else if (cur_pipe->plane_state == new_pipe->plane_state ||
+                               cur_pipe == new_pipe) {
+                       //unchanged pipes
+                       for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) {
+                               if (j == PG_HUBP &&
+                                       cur_pipe->plane_res.hubp != new_pipe->plane_res.hubp &&
+                                       new_pipe->plane_res.hubp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.hubp->inst] = true;
+
+                               if (j == PG_DPP &&
+                                       cur_pipe->plane_res.dpp != new_pipe->plane_res.dpp &&
+                                       new_pipe->plane_res.dpp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->plane_res.dpp->inst] = true;
+
+                               if (j == PG_OPP &&
+                                       cur_pipe->stream_res.opp != new_pipe->stream_res.opp &&
+                                       new_pipe->stream_res.opp)
+                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.opp->inst] = true;
+
+                               if (j == PG_DSC &&
+                                       cur_pipe->stream_res.dsc != new_pipe->stream_res.dsc &&
+                                       new_pipe->stream_res.dsc)
+                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.dsc->inst] = true;
+
+                               if (j == PG_OPTC &&
+                                       cur_pipe->stream_res.tg != new_pipe->stream_res.tg &&
+                                       new_pipe->stream_res.tg)
+                                       update_state->pg_pipe_res_update[j][new_pipe->stream_res.tg->inst] = true;
+                       }
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) {
+               if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] &&
+                               dc->res_pool->hpo_dp_stream_enc[i]) {
+                       hpo_dp_stream_enc_acquired = true;
+                       break;
+               }
+       }
+
+       if (hpo_frl_stream_enc_acquired || hpo_dp_stream_enc_acquired)
+               update_state->pg_res_update[PG_HPO] = true;
+
+}
+
+void dcn35_block_power_control(struct dc *dc,
+       struct pg_block_update *update_state, bool power_on)
+{
+       int i = 0;
+       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
+
+       if (!pg_cntl)
+               return;
+       if (dc->debug.ignore_pg)
+               return;
+       if (update_state->pg_res_update[PG_HPO]) {
+               if (pg_cntl->funcs->hpo_pg_control)
+                       pg_cntl->funcs->hpo_pg_control(pg_cntl, power_on);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
+                       update_state->pg_pipe_res_update[PG_DPP][i]) {
+                       if (pg_cntl->funcs->hubp_dpp_pg_control)
+                               pg_cntl->funcs->hubp_dpp_pg_control(pg_cntl, i, power_on);
+               }
+
+               if (update_state->pg_pipe_res_update[PG_DSC][i]) {
+                       if (pg_cntl->funcs->dsc_pg_control)
+                               pg_cntl->funcs->dsc_pg_control(pg_cntl, i, power_on);
+               }
+
+               if (update_state->pg_pipe_res_update[PG_MPCC][i]) {
+                       if (pg_cntl->funcs->mpcc_pg_control)
+                               pg_cntl->funcs->mpcc_pg_control(pg_cntl, i, power_on);
+               }
+
+               if (update_state->pg_pipe_res_update[PG_OPP][i]) {
+                       if (pg_cntl->funcs->opp_pg_control)
+                               pg_cntl->funcs->opp_pg_control(pg_cntl, i, power_on);
+               }
+
+               if (update_state->pg_pipe_res_update[PG_OPTC][i]) {
+                       if (pg_cntl->funcs->optc_pg_control)
+                               pg_cntl->funcs->optc_pg_control(pg_cntl, i, power_on);
+               }
+       }
+
+       if (update_state->pg_res_update[PG_DWB]) {
+               if (pg_cntl->funcs->dwb_pg_control)
+                       pg_cntl->funcs->dwb_pg_control(pg_cntl, power_on);
+       }
+
+       if (pg_cntl->funcs->plane_otg_pg_control)
+               pg_cntl->funcs->plane_otg_pg_control(pg_cntl, power_on);
+}
+
+void dcn35_root_clock_control(struct dc *dc,
+       struct pg_block_update *update_state, bool power_on)
+{
+       int i = 0;
+       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
+
+       if (!pg_cntl)
+               return;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
+                       update_state->pg_pipe_res_update[PG_DPP][i]) {
+                       if (dc->hwseq->funcs.dpp_root_clock_control)
+                               dc->hwseq->funcs.dpp_root_clock_control(dc->hwseq, i, power_on);
+               }
+
+               if (update_state->pg_pipe_res_update[PG_DSC][i]) {
+                       if (power_on) {
+                               if (dc->res_pool->dccg->funcs->enable_dsc)
+                                       dc->res_pool->dccg->funcs->enable_dsc(dc->res_pool->dccg, i);
+                       } else {
+                               if (dc->res_pool->dccg->funcs->disable_dsc)
+                                       dc->res_pool->dccg->funcs->disable_dsc(dc->res_pool->dccg, i);
+                       }
+               }
+       }
+}
+
+void dcn35_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct pg_block_update pg_update_state;
+
+       if (dc->hwss.calc_blocks_to_ungate) {
+               dc->hwss.calc_blocks_to_ungate(dc, context, &pg_update_state);
+
+               if (dc->hwss.root_clock_control)
+                       dc->hwss.root_clock_control(dc, &pg_update_state, true);
+
+               if (dc->hwss.block_power_control)
+                       dc->hwss.block_power_control(dc, &pg_update_state, true);
+       }
+
+       dcn20_prepare_bandwidth(dc, context);
+}
+
+void dcn35_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context)
+{
+       struct pg_block_update pg_update_state;
+
+       dcn20_optimize_bandwidth(dc, context);
+
+       if (dc->hwss.calc_blocks_to_gate) {
+               dc->hwss.calc_blocks_to_gate(dc, context, &pg_update_state);
+
+               if (dc->hwss.block_power_control)
+                       dc->hwss.block_power_control(dc, &pg_update_state, false);
+
+               if (dc->hwss.root_clock_control)
+                       dc->hwss.root_clock_control(dc, &pg_update_state, false);
+       }
+}
+
+void dcn35_set_idle_state(const struct dc *dc, bool allow_idle)
+{
+       // TODO: Find a more suitable communcation
+       if (dc->clk_mgr->funcs->set_idle_state)
+               dc->clk_mgr->funcs->set_idle_state(dc->clk_mgr, allow_idle);
+}
+
+uint32_t dcn35_get_idle_state(const struct dc *dc)
+{
+       // TODO: Find a more suitable communcation
+       if (dc->clk_mgr->funcs->get_idle_state)
+               return dc->clk_mgr->funcs->get_idle_state(dc->clk_mgr);
+
+       return 0;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
new file mode 100644 (file)
index 0000000..14bbdb0
--- /dev/null
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2023 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.
+ *
+ */
+
+#ifndef __DC_HWSS_DCN35_H__
+#define __DC_HWSS_DCN35_H__
+
+#include "hw_sequencer_private.h"
+
+struct dc;
+
+void dcn35_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
+
+void dcn35_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on);
+
+void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
+
+void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
+
+void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable);
+
+void dcn35_init_hw(struct dc *dc);
+
+void dcn35_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal);
+
+void dcn35_power_down_on_boot(struct dc *dc);
+
+bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable);
+
+void dcn35_z10_restore(const struct dc *dc);
+
+void dcn35_init_pipes(struct dc *dc, struct dc_state *context);
+void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx);
+void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                              struct dc_state *context);
+void dcn35_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
+
+void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
+       struct pg_block_update *update_state);
+void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
+       struct pg_block_update *update_state);
+void dcn35_block_power_control(struct dc *dc,
+       struct pg_block_update *update_state, bool power_on);
+void dcn35_root_clock_control(struct dc *dc,
+       struct pg_block_update *update_state, bool power_on);
+
+void dcn35_prepare_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+
+void dcn35_optimize_bandwidth(
+               struct dc *dc,
+               struct dc_state *context);
+
+void dcn35_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
+void dcn35_dsc_pg_control(
+               struct dce_hwseq *hws,
+               unsigned int dsc_inst,
+               bool power_on);
+
+void dcn35_set_idle_state(const struct dc *dc, bool allow_idle);
+uint32_t dcn35_get_idle_state(const struct dc *dc);
+#endif /* __DC_HWSS_DCN35_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
new file mode 100644 (file)
index 0000000..452680f
--- /dev/null
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2015 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_HW_SEQUENCER_H__
+#define __DC_HW_SEQUENCER_H__
+#include "dc_types.h"
+#include "inc/clock_source.h"
+#include "inc/hw/timing_generator.h"
+#include "inc/hw/opp.h"
+#include "inc/hw/link_encoder.h"
+#include "inc/core_status.h"
+
+struct pipe_ctx;
+struct dc_state;
+struct dc_stream_status;
+struct dc_writeback_info;
+struct dchub_init_data;
+struct dc_static_screen_params;
+struct resource_pool;
+struct dc_phy_addr_space_config;
+struct dc_virtual_addr_space_config;
+struct dpp;
+struct dce_hwseq;
+struct link_resource;
+struct dc_dmub_cmd;
+struct pg_block_update;
+
+struct subvp_pipe_control_lock_fast_params {
+       struct dc *dc;
+       bool lock;
+       struct pipe_ctx *pipe_ctx;
+};
+
+struct pipe_control_lock_params {
+       struct dc *dc;
+       struct pipe_ctx *pipe_ctx;
+       bool lock;
+};
+
+struct set_flip_control_gsl_params {
+       struct pipe_ctx *pipe_ctx;
+       bool flip_immediate;
+};
+
+struct program_triplebuffer_params {
+       const struct dc *dc;
+       struct pipe_ctx *pipe_ctx;
+       bool enableTripleBuffer;
+};
+
+struct update_plane_addr_params {
+       struct dc *dc;
+       struct pipe_ctx *pipe_ctx;
+};
+
+struct set_input_transfer_func_params {
+       struct dc *dc;
+       struct pipe_ctx *pipe_ctx;
+       struct dc_plane_state *plane_state;
+};
+
+struct program_gamut_remap_params {
+       struct pipe_ctx *pipe_ctx;
+};
+
+struct program_manual_trigger_params {
+       struct pipe_ctx *pipe_ctx;
+};
+
+struct send_dmcub_cmd_params {
+       struct dc_context *ctx;
+       union dmub_rb_cmd *cmd;
+       enum dm_dmub_wait_type wait_type;
+};
+
+struct setup_dpp_params {
+       struct pipe_ctx *pipe_ctx;
+};
+
+struct program_bias_and_scale_params {
+       struct pipe_ctx *pipe_ctx;
+};
+
+struct set_output_transfer_func_params {
+       struct dc *dc;
+       struct pipe_ctx *pipe_ctx;
+       const struct dc_stream_state *stream;
+};
+
+struct update_visual_confirm_params {
+       struct dc *dc;
+       struct pipe_ctx *pipe_ctx;
+       int mpcc_id;
+};
+
+struct power_on_mpc_mem_pwr_params {
+       struct mpc *mpc;
+       int mpcc_id;
+       bool power_on;
+};
+
+struct set_output_csc_params {
+       struct mpc *mpc;
+       int opp_id;
+       const uint16_t *regval;
+       enum mpc_output_csc_mode ocsc_mode;
+};
+
+struct set_ocsc_default_params {
+       struct mpc *mpc;
+       int opp_id;
+       enum dc_color_space color_space;
+       enum mpc_output_csc_mode ocsc_mode;
+};
+
+struct subvp_save_surf_addr {
+       struct dc_dmub_srv *dc_dmub_srv;
+       const struct dc_plane_address *addr;
+       uint8_t subvp_index;
+};
+
+union block_sequence_params {
+       struct update_plane_addr_params update_plane_addr_params;
+       struct subvp_pipe_control_lock_fast_params subvp_pipe_control_lock_fast_params;
+       struct pipe_control_lock_params pipe_control_lock_params;
+       struct set_flip_control_gsl_params set_flip_control_gsl_params;
+       struct program_triplebuffer_params program_triplebuffer_params;
+       struct set_input_transfer_func_params set_input_transfer_func_params;
+       struct program_gamut_remap_params program_gamut_remap_params;
+       struct program_manual_trigger_params program_manual_trigger_params;
+       struct send_dmcub_cmd_params send_dmcub_cmd_params;
+       struct setup_dpp_params setup_dpp_params;
+       struct program_bias_and_scale_params program_bias_and_scale_params;
+       struct set_output_transfer_func_params set_output_transfer_func_params;
+       struct update_visual_confirm_params update_visual_confirm_params;
+       struct power_on_mpc_mem_pwr_params power_on_mpc_mem_pwr_params;
+       struct set_output_csc_params set_output_csc_params;
+       struct set_ocsc_default_params set_ocsc_default_params;
+       struct subvp_save_surf_addr subvp_save_surf_addr;
+};
+
+enum block_sequence_func {
+       DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST = 0,
+       OPTC_PIPE_CONTROL_LOCK,
+       HUBP_SET_FLIP_CONTROL_GSL,
+       HUBP_PROGRAM_TRIPLEBUFFER,
+       HUBP_UPDATE_PLANE_ADDR,
+       DPP_SET_INPUT_TRANSFER_FUNC,
+       DPP_PROGRAM_GAMUT_REMAP,
+       OPTC_PROGRAM_MANUAL_TRIGGER,
+       DMUB_SEND_DMCUB_CMD,
+       DPP_SETUP_DPP,
+       DPP_PROGRAM_BIAS_AND_SCALE,
+       DPP_SET_OUTPUT_TRANSFER_FUNC,
+       MPC_UPDATE_VISUAL_CONFIRM,
+       MPC_POWER_ON_MPC_MEM_PWR,
+       MPC_SET_OUTPUT_CSC,
+       MPC_SET_OCSC_DEFAULT,
+       DMUB_SUBVP_SAVE_SURF_ADDR,
+};
+
+struct block_sequence {
+       union block_sequence_params params;
+       enum block_sequence_func func;
+};
+
+struct hw_sequencer_funcs {
+       void (*hardware_release)(struct dc *dc);
+       /* Embedded Display Related */
+       void (*edp_power_control)(struct dc_link *link, bool enable);
+       void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
+       void (*edp_wait_for_T12)(struct dc_link *link);
+
+       /* Pipe Programming Related */
+       void (*init_hw)(struct dc *dc);
+       void (*power_down_on_boot)(struct dc *dc);
+       void (*enable_accelerated_mode)(struct dc *dc,
+                       struct dc_state *context);
+       enum dc_status (*apply_ctx_to_hw)(struct dc *dc,
+                       struct dc_state *context);
+       void (*disable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+       void (*disable_pixel_data)(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank);
+       void (*apply_ctx_for_surface)(struct dc *dc,
+                       const struct dc_stream_state *stream,
+                       int num_planes, struct dc_state *context);
+       void (*program_front_end_for_ctx)(struct dc *dc,
+                       struct dc_state *context);
+       void (*wait_for_pending_cleared)(struct dc *dc,
+                       struct dc_state *context);
+       void (*post_unlock_program_front_end)(struct dc *dc,
+                       struct dc_state *context);
+       void (*update_plane_addr)(const struct dc *dc,
+                       struct pipe_ctx *pipe_ctx);
+       void (*update_dchub)(struct dce_hwseq *hws,
+                       struct dchub_init_data *dh_data);
+       void (*wait_for_mpcc_disconnect)(struct dc *dc,
+                       struct resource_pool *res_pool,
+                       struct pipe_ctx *pipe_ctx);
+       void (*edp_backlight_control)(
+                       struct dc_link *link,
+                       bool enable);
+       void (*program_triplebuffer)(const struct dc *dc,
+               struct pipe_ctx *pipe_ctx, bool enableTripleBuffer);
+       void (*update_pending_status)(struct pipe_ctx *pipe_ctx);
+       void (*power_down)(struct dc *dc);
+       void (*update_dsc_pg)(struct dc *dc, struct dc_state *context, bool safe_to_disable);
+
+       /* Pipe Lock Related */
+       void (*pipe_control_lock)(struct dc *dc,
+                       struct pipe_ctx *pipe, bool lock);
+       void (*interdependent_update_lock)(struct dc *dc,
+                       struct dc_state *context, bool lock);
+       void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx,
+                       bool flip_immediate);
+       void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock);
+
+       /* Timing Related */
+       void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
+                       struct crtc_position *position);
+       int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx);
+       void (*calc_vupdate_position)(
+                       struct dc *dc,
+                       struct pipe_ctx *pipe_ctx,
+                       uint32_t *start_line,
+                       uint32_t *end_line);
+       void (*enable_per_frame_crtc_position_reset)(struct dc *dc,
+                       int group_size, struct pipe_ctx *grouped_pipes[]);
+       void (*enable_timing_synchronization)(struct dc *dc,
+                       int group_index, int group_size,
+                       struct pipe_ctx *grouped_pipes[]);
+       void (*enable_vblanks_synchronization)(struct dc *dc,
+                       int group_index, int group_size,
+                       struct pipe_ctx *grouped_pipes[]);
+       void (*setup_periodic_interrupt)(struct dc *dc,
+                       struct pipe_ctx *pipe_ctx);
+       void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
+                       struct dc_crtc_timing_adjust adjust);
+       void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
+                       int num_pipes,
+                       const struct dc_static_screen_params *events);
+
+       /* Stream Related */
+       void (*enable_stream)(struct pipe_ctx *pipe_ctx);
+       void (*disable_stream)(struct pipe_ctx *pipe_ctx);
+       void (*blank_stream)(struct pipe_ctx *pipe_ctx);
+       void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
+                       struct dc_link_settings *link_settings);
+
+       /* Bandwidth Related */
+       void (*prepare_bandwidth)(struct dc *dc, struct dc_state *context);
+       bool (*update_bandwidth)(struct dc *dc, struct dc_state *context);
+       void (*optimize_bandwidth)(struct dc *dc, struct dc_state *context);
+
+       /* Infopacket Related */
+       void (*set_avmute)(struct pipe_ctx *pipe_ctx, bool enable);
+       void (*send_immediate_sdp_message)(
+                       struct pipe_ctx *pipe_ctx,
+                       const uint8_t *custom_sdp_message,
+                       unsigned int sdp_message_size);
+       void (*update_info_frame)(struct pipe_ctx *pipe_ctx);
+       void (*set_dmdata_attributes)(struct pipe_ctx *pipe);
+       void (*program_dmdata_engine)(struct pipe_ctx *pipe_ctx);
+       bool (*dmdata_status_done)(struct pipe_ctx *pipe_ctx);
+
+       /* Cursor Related */
+       void (*set_cursor_position)(struct pipe_ctx *pipe);
+       void (*set_cursor_attribute)(struct pipe_ctx *pipe);
+       void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe);
+
+       /* Colour Related */
+       void (*program_gamut_remap)(struct pipe_ctx *pipe_ctx);
+       void (*program_output_csc)(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                       enum dc_color_space colorspace,
+                       uint16_t *matrix, int opp_id);
+
+       /* VM Related */
+       int (*init_sys_ctx)(struct dce_hwseq *hws,
+                       struct dc *dc,
+                       struct dc_phy_addr_space_config *pa_config);
+       void (*init_vm_ctx)(struct dce_hwseq *hws,
+                       struct dc *dc,
+                       struct dc_virtual_addr_space_config *va_config,
+                       int vmid);
+
+       /* Writeback Related */
+       void (*update_writeback)(struct dc *dc,
+                       struct dc_writeback_info *wb_info,
+                       struct dc_state *context);
+       void (*enable_writeback)(struct dc *dc,
+                       struct dc_writeback_info *wb_info,
+                       struct dc_state *context);
+       void (*disable_writeback)(struct dc *dc,
+                       unsigned int dwb_pipe_inst);
+
+       bool (*mmhubbub_warmup)(struct dc *dc,
+                       unsigned int num_dwb,
+                       struct dc_writeback_info *wb_info);
+
+       /* Clock Related */
+       enum dc_status (*set_clock)(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       uint32_t clk_khz, uint32_t stepping);
+       void (*get_clock)(struct dc *dc, enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg);
+       void (*optimize_pwr_state)(const struct dc *dc,
+                       struct dc_state *context);
+       void (*exit_optimized_pwr_state)(const struct dc *dc,
+                       struct dc_state *context);
+
+       /* Audio Related */
+       void (*enable_audio_stream)(struct pipe_ctx *pipe_ctx);
+       void (*disable_audio_stream)(struct pipe_ctx *pipe_ctx);
+
+       /* Stereo 3D Related */
+       void (*setup_stereo)(struct pipe_ctx *pipe_ctx, struct dc *dc);
+
+       /* HW State Logging Related */
+       void (*log_hw_state)(struct dc *dc, struct dc_log_buffer_ctx *log_ctx);
+       void (*get_hw_state)(struct dc *dc, char *pBuf,
+                       unsigned int bufSize, unsigned int mask);
+       void (*clear_status_bits)(struct dc *dc, unsigned int mask);
+
+       bool (*set_backlight_level)(struct pipe_ctx *pipe_ctx,
+                       uint32_t backlight_pwm_u16_16,
+                       uint32_t frame_ramp);
+
+       void (*set_abm_immediate_disable)(struct pipe_ctx *pipe_ctx);
+
+       void (*set_pipe)(struct pipe_ctx *pipe_ctx);
+
+       void (*enable_dp_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal,
+                       enum clock_source_id clock_source,
+                       const struct dc_link_settings *link_settings);
+       void (*enable_tmds_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal,
+                       enum clock_source_id clock_source,
+                       enum dc_color_depth color_depth,
+                       uint32_t pixel_clock);
+       void (*enable_lvds_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum clock_source_id clock_source,
+                       uint32_t pixel_clock);
+       void (*disable_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal);
+
+       void (*get_dcc_en_bits)(struct dc *dc, int *dcc_en_bits);
+
+       /* Idle Optimization Related */
+       bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable);
+
+       bool (*does_plane_fit_in_mall)(struct dc *dc, struct dc_plane_state *plane,
+                       struct dc_cursor_attributes *cursor_attr);
+       void (*commit_subvp_config)(struct dc *dc, struct dc_state *context);
+       void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context);
+       void (*subvp_pipe_control_lock)(struct dc *dc,
+                       struct dc_state *context,
+                       bool lock,
+                       bool should_lock_all_pipes,
+                       struct pipe_ctx *top_pipe_to_program,
+                       bool subvp_prev_use);
+       void (*subvp_pipe_control_lock_fast)(union block_sequence_params *params);
+
+       void (*z10_restore)(const struct dc *dc);
+       void (*z10_save_init)(struct dc *dc);
+       bool (*is_abm_supported)(struct dc *dc,
+                       struct dc_state *context, struct dc_stream_state *stream);
+
+       void (*set_disp_pattern_generator)(const struct dc *dc,
+                       struct pipe_ctx *pipe_ctx,
+                       enum controller_dp_test_pattern test_pattern,
+                       enum controller_dp_color_space color_space,
+                       enum dc_color_depth color_depth,
+                       const struct tg_color *solid_color,
+                       int width, int height, int offset);
+       void (*blank_phantom)(struct dc *dc,
+                       struct timing_generator *tg,
+                       int width,
+                       int height);
+       void (*update_visual_confirm_color)(struct dc *dc,
+                       struct pipe_ctx *pipe_ctx,
+                       int mpcc_id);
+       void (*update_phantom_vp_position)(struct dc *dc,
+                       struct dc_state *context,
+                       struct pipe_ctx *phantom_pipe);
+       void (*apply_update_flags_for_phantom)(struct pipe_ctx *phantom_pipe);
+
+       void (*calc_blocks_to_gate)(struct dc *dc, struct dc_state *context,
+               struct pg_block_update *update_state);
+       void (*calc_blocks_to_ungate)(struct dc *dc, struct dc_state *context,
+               struct pg_block_update *update_state);
+       void (*block_power_control)(struct dc *dc,
+               struct pg_block_update *update_state, bool power_on);
+       void (*root_clock_control)(struct dc *dc,
+               struct pg_block_update *update_state, bool power_on);
+       void (*set_idle_state)(const struct dc *dc, bool allow_idle);
+       uint32_t (*get_idle_state)(const struct dc *dc);
+       bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
+                       const struct dc_state *cur_ctx,
+                       const struct dc_state *new_ctx);
+};
+
+void color_space_to_black_color(
+       const struct dc *dc,
+       enum dc_color_space colorspace,
+       struct tg_color *black_color);
+
+bool hwss_wait_for_blank_complete(
+               struct timing_generator *tg);
+
+const uint16_t *find_color_matrix(
+               enum dc_color_space color_space,
+               uint32_t *array_size);
+
+void get_surface_tile_visual_confirm_color(
+               struct pipe_ctx *pipe_ctx,
+               struct tg_color *color);
+void get_surface_visual_confirm_color(
+               const struct pipe_ctx *pipe_ctx,
+               struct tg_color *color);
+
+void get_hdr_visual_confirm_color(
+               struct pipe_ctx *pipe_ctx,
+               struct tg_color *color);
+void get_mpctree_visual_confirm_color(
+               struct pipe_ctx *pipe_ctx,
+               struct tg_color *color);
+
+void get_subvp_visual_confirm_color(
+       struct dc *dc,
+       struct dc_state *context,
+       struct pipe_ctx *pipe_ctx,
+       struct tg_color *color);
+
+void get_mclk_switch_visual_confirm_color(
+               struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *pipe_ctx,
+               struct tg_color *color);
+
+void hwss_execute_sequence(struct dc *dc,
+               struct block_sequence block_sequence[],
+               int num_steps);
+
+void hwss_build_fast_sequence(struct dc *dc,
+               struct dc_dmub_cmd *dc_dmub_cmd,
+               unsigned int dmub_cmd_count,
+               struct block_sequence block_sequence[],
+               int *num_steps,
+               struct pipe_ctx *pipe_ctx);
+
+void hwss_send_dmcub_cmd(union block_sequence_params *params);
+
+void hwss_program_manual_trigger(union block_sequence_params *params);
+
+void hwss_setup_dpp(union block_sequence_params *params);
+
+void hwss_program_bias_and_scale(union block_sequence_params *params);
+
+void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params);
+
+void hwss_set_output_csc(union block_sequence_params *params);
+
+void hwss_set_ocsc_default(union block_sequence_params *params);
+
+void hwss_subvp_save_surf_addr(union block_sequence_params *params);
+
+#endif /* __DC_HW_SEQUENCER_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
new file mode 100644 (file)
index 0000000..82c5921
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2015 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_HW_SEQUENCER_PRIVATE_H__
+#define __DC_HW_SEQUENCER_PRIVATE_H__
+
+#include "dc_types.h"
+
+enum pipe_gating_control {
+       PIPE_GATING_CONTROL_DISABLE = 0,
+       PIPE_GATING_CONTROL_ENABLE,
+       PIPE_GATING_CONTROL_INIT
+};
+
+struct dce_hwseq_wa {
+       bool blnd_crtc_trigger;
+       bool DEGVIDCN10_253;
+       bool false_optc_underflow;
+       bool DEGVIDCN10_254;
+       bool DEGVIDCN21;
+       bool disallow_self_refresh_during_multi_plane_transition;
+       bool dp_hpo_and_otg_sequence;
+       bool wait_hubpret_read_start_during_mpo_transition;
+};
+
+struct hwseq_wa_state {
+       bool DEGVIDCN10_253_applied;
+       bool disallow_self_refresh_during_multi_plane_transition_applied;
+       unsigned int disallow_self_refresh_during_multi_plane_transition_applied_on_frame;
+};
+
+struct pipe_ctx;
+struct dc_state;
+struct dc_stream_status;
+struct dc_writeback_info;
+struct dchub_init_data;
+struct dc_static_screen_params;
+struct resource_pool;
+struct resource_context;
+struct stream_resource;
+struct dc_phy_addr_space_config;
+struct dc_virtual_addr_space_config;
+struct hubp;
+struct dpp;
+struct dce_hwseq;
+struct timing_generator;
+struct tg_color;
+struct output_pixel_processor;
+struct mpcc_blnd_cfg;
+
+struct hwseq_private_funcs {
+
+       void (*disable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+       void (*enable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+       void (*init_pipes)(struct dc *dc, struct dc_state *context);
+       void (*reset_hw_ctx_wrap)(struct dc *dc, struct dc_state *context);
+       void (*update_plane_addr)(const struct dc *dc,
+                       struct pipe_ctx *pipe_ctx);
+       void (*plane_atomic_disconnect)(struct dc *dc,
+                       struct pipe_ctx *pipe_ctx);
+       void (*update_mpcc)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+       bool (*set_input_transfer_func)(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state);
+       bool (*set_output_transfer_func)(struct dc *dc,
+                               struct pipe_ctx *pipe_ctx,
+                               const struct dc_stream_state *stream);
+       void (*power_down)(struct dc *dc);
+       void (*enable_display_pipe_clock_gating)(struct dc_context *ctx,
+                                       bool clock_gating);
+       bool (*enable_display_power_gating)(struct dc *dc,
+                                       uint8_t controller_id,
+                                       struct dc_bios *dcb,
+                                       enum pipe_gating_control power_gating);
+       void (*blank_pixel_data)(struct dc *dc,
+                       struct pipe_ctx *pipe_ctx,
+                       bool blank);
+       enum dc_status (*enable_stream_timing)(
+                       struct pipe_ctx *pipe_ctx,
+                       struct dc_state *context,
+                       struct dc *dc);
+       void (*edp_backlight_control)(struct dc_link *link,
+                       bool enable);
+       void (*setup_vupdate_interrupt)(struct dc *dc,
+                       struct pipe_ctx *pipe_ctx);
+       bool (*did_underflow_occur)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+       void (*init_blank)(struct dc *dc, struct timing_generator *tg);
+       void (*disable_vga)(struct dce_hwseq *hws);
+       void (*bios_golden_init)(struct dc *dc);
+       void (*plane_atomic_power_down)(struct dc *dc,
+                       struct dpp *dpp,
+                       struct hubp *hubp);
+       void (*plane_atomic_disable)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+       void (*enable_power_gating_plane)(struct dce_hwseq *hws,
+               bool enable);
+       void (*dpp_root_clock_control)(
+                       struct dce_hwseq *hws,
+                       unsigned int dpp_inst,
+                       bool clock_on);
+       void (*dpp_pg_control)(struct dce_hwseq *hws,
+                       unsigned int dpp_inst,
+                       bool power_on);
+       void (*hubp_pg_control)(struct dce_hwseq *hws,
+                       unsigned int hubp_inst,
+                       bool power_on);
+       void (*dsc_pg_control)(struct dce_hwseq *hws,
+                       unsigned int dsc_inst,
+                       bool power_on);
+       bool (*dsc_pg_status)(struct dce_hwseq *hws,
+                       unsigned int dsc_inst);
+       void (*update_odm)(struct dc *dc, struct dc_state *context,
+                       struct pipe_ctx *pipe_ctx);
+       void (*program_all_writeback_pipes_in_tree)(struct dc *dc,
+                       const struct dc_stream_state *stream,
+                       struct dc_state *context);
+       bool (*s0i3_golden_init_wa)(struct dc *dc);
+       void (*set_hdr_multiplier)(struct pipe_ctx *pipe_ctx);
+       void (*verify_allow_pstate_change_high)(struct dc *dc);
+       void (*program_pipe)(struct dc *dc,
+                       struct pipe_ctx *pipe_ctx,
+                       struct dc_state *context);
+       bool (*wait_for_blank_complete)(struct output_pixel_processor *opp);
+       void (*dccg_init)(struct dce_hwseq *hws);
+       bool (*set_blend_lut)(struct pipe_ctx *pipe_ctx,
+                       const struct dc_plane_state *plane_state);
+       bool (*set_shaper_3dlut)(struct pipe_ctx *pipe_ctx,
+                       const struct dc_plane_state *plane_state);
+       bool (*set_mcm_luts)(struct pipe_ctx *pipe_ctx,
+                       const struct dc_plane_state *plane_state);
+       void (*PLAT_58856_wa)(struct dc_state *context,
+                       struct pipe_ctx *pipe_ctx);
+       void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
+       void (*enable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx,
+                              struct dc_state *context);
+#ifdef CONFIG_DRM_AMD_DC_FP
+       void (*program_mall_pipe_config)(struct dc *dc, struct dc_state *context);
+       void (*update_force_pstate)(struct dc *dc, struct dc_state *context);
+       void (*update_mall_sel)(struct dc *dc, struct dc_state *context);
+       unsigned int (*calculate_dccg_k1_k2_values)(struct pipe_ctx *pipe_ctx,
+                       unsigned int *k1_div,
+                       unsigned int *k2_div);
+       void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx);
+       void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc,
+                       struct dc_state *context);
+       bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx);
+#endif
+};
+
+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;
+       struct dce_hwseq_wa wa;
+       struct hwseq_wa_state wa_state;
+       struct hwseq_private_funcs funcs;
+
+       PHYSICAL_ADDRESS_LOC fb_base;
+       PHYSICAL_ADDRESS_LOC fb_top;
+       PHYSICAL_ADDRESS_LOC fb_offset;
+       PHYSICAL_ADDRESS_LOC uma_top;
+};
+
+#endif /* __DC_HW_SEQUENCER_PRIVATE_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
deleted file mode 100644 (file)
index 844ad5e..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright 2015 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_HW_SEQUENCER_H__
-#define __DC_HW_SEQUENCER_H__
-#include "dc_types.h"
-#include "clock_source.h"
-#include "inc/hw/timing_generator.h"
-#include "inc/hw/opp.h"
-#include "inc/hw/link_encoder.h"
-#include "core_status.h"
-
-struct pipe_ctx;
-struct dc_state;
-struct dc_stream_status;
-struct dc_writeback_info;
-struct dchub_init_data;
-struct dc_static_screen_params;
-struct resource_pool;
-struct dc_phy_addr_space_config;
-struct dc_virtual_addr_space_config;
-struct dpp;
-struct dce_hwseq;
-struct link_resource;
-struct dc_dmub_cmd;
-struct pg_block_update;
-
-struct subvp_pipe_control_lock_fast_params {
-       struct dc *dc;
-       bool lock;
-       struct pipe_ctx *pipe_ctx;
-};
-
-struct pipe_control_lock_params {
-       struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
-       bool lock;
-};
-
-struct set_flip_control_gsl_params {
-       struct pipe_ctx *pipe_ctx;
-       bool flip_immediate;
-};
-
-struct program_triplebuffer_params {
-       const struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
-       bool enableTripleBuffer;
-};
-
-struct update_plane_addr_params {
-       struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
-};
-
-struct set_input_transfer_func_params {
-       struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
-       struct dc_plane_state *plane_state;
-};
-
-struct program_gamut_remap_params {
-       struct pipe_ctx *pipe_ctx;
-};
-
-struct program_manual_trigger_params {
-       struct pipe_ctx *pipe_ctx;
-};
-
-struct send_dmcub_cmd_params {
-       struct dc_context *ctx;
-       union dmub_rb_cmd *cmd;
-       enum dm_dmub_wait_type wait_type;
-};
-
-struct setup_dpp_params {
-       struct pipe_ctx *pipe_ctx;
-};
-
-struct program_bias_and_scale_params {
-       struct pipe_ctx *pipe_ctx;
-};
-
-struct set_output_transfer_func_params {
-       struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
-       const struct dc_stream_state *stream;
-};
-
-struct update_visual_confirm_params {
-       struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
-       int mpcc_id;
-};
-
-struct power_on_mpc_mem_pwr_params {
-       struct mpc *mpc;
-       int mpcc_id;
-       bool power_on;
-};
-
-struct set_output_csc_params {
-       struct mpc *mpc;
-       int opp_id;
-       const uint16_t *regval;
-       enum mpc_output_csc_mode ocsc_mode;
-};
-
-struct set_ocsc_default_params {
-       struct mpc *mpc;
-       int opp_id;
-       enum dc_color_space color_space;
-       enum mpc_output_csc_mode ocsc_mode;
-};
-
-struct subvp_save_surf_addr {
-       struct dc_dmub_srv *dc_dmub_srv;
-       const struct dc_plane_address *addr;
-       uint8_t subvp_index;
-};
-
-union block_sequence_params {
-       struct update_plane_addr_params update_plane_addr_params;
-       struct subvp_pipe_control_lock_fast_params subvp_pipe_control_lock_fast_params;
-       struct pipe_control_lock_params pipe_control_lock_params;
-       struct set_flip_control_gsl_params set_flip_control_gsl_params;
-       struct program_triplebuffer_params program_triplebuffer_params;
-       struct set_input_transfer_func_params set_input_transfer_func_params;
-       struct program_gamut_remap_params program_gamut_remap_params;
-       struct program_manual_trigger_params program_manual_trigger_params;
-       struct send_dmcub_cmd_params send_dmcub_cmd_params;
-       struct setup_dpp_params setup_dpp_params;
-       struct program_bias_and_scale_params program_bias_and_scale_params;
-       struct set_output_transfer_func_params set_output_transfer_func_params;
-       struct update_visual_confirm_params update_visual_confirm_params;
-       struct power_on_mpc_mem_pwr_params power_on_mpc_mem_pwr_params;
-       struct set_output_csc_params set_output_csc_params;
-       struct set_ocsc_default_params set_ocsc_default_params;
-       struct subvp_save_surf_addr subvp_save_surf_addr;
-};
-
-enum block_sequence_func {
-       DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST = 0,
-       OPTC_PIPE_CONTROL_LOCK,
-       HUBP_SET_FLIP_CONTROL_GSL,
-       HUBP_PROGRAM_TRIPLEBUFFER,
-       HUBP_UPDATE_PLANE_ADDR,
-       DPP_SET_INPUT_TRANSFER_FUNC,
-       DPP_PROGRAM_GAMUT_REMAP,
-       OPTC_PROGRAM_MANUAL_TRIGGER,
-       DMUB_SEND_DMCUB_CMD,
-       DPP_SETUP_DPP,
-       DPP_PROGRAM_BIAS_AND_SCALE,
-       DPP_SET_OUTPUT_TRANSFER_FUNC,
-       MPC_UPDATE_VISUAL_CONFIRM,
-       MPC_POWER_ON_MPC_MEM_PWR,
-       MPC_SET_OUTPUT_CSC,
-       MPC_SET_OCSC_DEFAULT,
-       DMUB_SUBVP_SAVE_SURF_ADDR,
-};
-
-struct block_sequence {
-       union block_sequence_params params;
-       enum block_sequence_func func;
-};
-
-struct hw_sequencer_funcs {
-       void (*hardware_release)(struct dc *dc);
-       /* Embedded Display Related */
-       void (*edp_power_control)(struct dc_link *link, bool enable);
-       void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
-       void (*edp_wait_for_T12)(struct dc_link *link);
-
-       /* Pipe Programming Related */
-       void (*init_hw)(struct dc *dc);
-       void (*power_down_on_boot)(struct dc *dc);
-       void (*enable_accelerated_mode)(struct dc *dc,
-                       struct dc_state *context);
-       enum dc_status (*apply_ctx_to_hw)(struct dc *dc,
-                       struct dc_state *context);
-       void (*disable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx);
-       void (*disable_pixel_data)(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank);
-       void (*apply_ctx_for_surface)(struct dc *dc,
-                       const struct dc_stream_state *stream,
-                       int num_planes, struct dc_state *context);
-       void (*program_front_end_for_ctx)(struct dc *dc,
-                       struct dc_state *context);
-       void (*wait_for_pending_cleared)(struct dc *dc,
-                       struct dc_state *context);
-       void (*post_unlock_program_front_end)(struct dc *dc,
-                       struct dc_state *context);
-       void (*update_plane_addr)(const struct dc *dc,
-                       struct pipe_ctx *pipe_ctx);
-       void (*update_dchub)(struct dce_hwseq *hws,
-                       struct dchub_init_data *dh_data);
-       void (*wait_for_mpcc_disconnect)(struct dc *dc,
-                       struct resource_pool *res_pool,
-                       struct pipe_ctx *pipe_ctx);
-       void (*edp_backlight_control)(
-                       struct dc_link *link,
-                       bool enable);
-       void (*program_triplebuffer)(const struct dc *dc,
-               struct pipe_ctx *pipe_ctx, bool enableTripleBuffer);
-       void (*update_pending_status)(struct pipe_ctx *pipe_ctx);
-       void (*power_down)(struct dc *dc);
-       void (*update_dsc_pg)(struct dc *dc, struct dc_state *context, bool safe_to_disable);
-
-       /* Pipe Lock Related */
-       void (*pipe_control_lock)(struct dc *dc,
-                       struct pipe_ctx *pipe, bool lock);
-       void (*interdependent_update_lock)(struct dc *dc,
-                       struct dc_state *context, bool lock);
-       void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx,
-                       bool flip_immediate);
-       void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock);
-
-       /* Timing Related */
-       void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
-                       struct crtc_position *position);
-       int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx);
-       void (*calc_vupdate_position)(
-                       struct dc *dc,
-                       struct pipe_ctx *pipe_ctx,
-                       uint32_t *start_line,
-                       uint32_t *end_line);
-       void (*enable_per_frame_crtc_position_reset)(struct dc *dc,
-                       int group_size, struct pipe_ctx *grouped_pipes[]);
-       void (*enable_timing_synchronization)(struct dc *dc,
-                       int group_index, int group_size,
-                       struct pipe_ctx *grouped_pipes[]);
-       void (*enable_vblanks_synchronization)(struct dc *dc,
-                       int group_index, int group_size,
-                       struct pipe_ctx *grouped_pipes[]);
-       void (*setup_periodic_interrupt)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx);
-       void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
-                       struct dc_crtc_timing_adjust adjust);
-       void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
-                       int num_pipes,
-                       const struct dc_static_screen_params *events);
-
-       /* Stream Related */
-       void (*enable_stream)(struct pipe_ctx *pipe_ctx);
-       void (*disable_stream)(struct pipe_ctx *pipe_ctx);
-       void (*blank_stream)(struct pipe_ctx *pipe_ctx);
-       void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
-                       struct dc_link_settings *link_settings);
-
-       /* Bandwidth Related */
-       void (*prepare_bandwidth)(struct dc *dc, struct dc_state *context);
-       bool (*update_bandwidth)(struct dc *dc, struct dc_state *context);
-       void (*optimize_bandwidth)(struct dc *dc, struct dc_state *context);
-
-       /* Infopacket Related */
-       void (*set_avmute)(struct pipe_ctx *pipe_ctx, bool enable);
-       void (*send_immediate_sdp_message)(
-                       struct pipe_ctx *pipe_ctx,
-                       const uint8_t *custom_sdp_message,
-                       unsigned int sdp_message_size);
-       void (*update_info_frame)(struct pipe_ctx *pipe_ctx);
-       void (*set_dmdata_attributes)(struct pipe_ctx *pipe);
-       void (*program_dmdata_engine)(struct pipe_ctx *pipe_ctx);
-       bool (*dmdata_status_done)(struct pipe_ctx *pipe_ctx);
-
-       /* Cursor Related */
-       void (*set_cursor_position)(struct pipe_ctx *pipe);
-       void (*set_cursor_attribute)(struct pipe_ctx *pipe);
-       void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe);
-
-       /* Colour Related */
-       void (*program_gamut_remap)(struct pipe_ctx *pipe_ctx);
-       void (*program_output_csc)(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                       enum dc_color_space colorspace,
-                       uint16_t *matrix, int opp_id);
-
-       /* VM Related */
-       int (*init_sys_ctx)(struct dce_hwseq *hws,
-                       struct dc *dc,
-                       struct dc_phy_addr_space_config *pa_config);
-       void (*init_vm_ctx)(struct dce_hwseq *hws,
-                       struct dc *dc,
-                       struct dc_virtual_addr_space_config *va_config,
-                       int vmid);
-
-       /* Writeback Related */
-       void (*update_writeback)(struct dc *dc,
-                       struct dc_writeback_info *wb_info,
-                       struct dc_state *context);
-       void (*enable_writeback)(struct dc *dc,
-                       struct dc_writeback_info *wb_info,
-                       struct dc_state *context);
-       void (*disable_writeback)(struct dc *dc,
-                       unsigned int dwb_pipe_inst);
-
-       bool (*mmhubbub_warmup)(struct dc *dc,
-                       unsigned int num_dwb,
-                       struct dc_writeback_info *wb_info);
-
-       /* Clock Related */
-       enum dc_status (*set_clock)(struct dc *dc,
-                       enum dc_clock_type clock_type,
-                       uint32_t clk_khz, uint32_t stepping);
-       void (*get_clock)(struct dc *dc, enum dc_clock_type clock_type,
-                       struct dc_clock_config *clock_cfg);
-       void (*optimize_pwr_state)(const struct dc *dc,
-                       struct dc_state *context);
-       void (*exit_optimized_pwr_state)(const struct dc *dc,
-                       struct dc_state *context);
-
-       /* Audio Related */
-       void (*enable_audio_stream)(struct pipe_ctx *pipe_ctx);
-       void (*disable_audio_stream)(struct pipe_ctx *pipe_ctx);
-
-       /* Stereo 3D Related */
-       void (*setup_stereo)(struct pipe_ctx *pipe_ctx, struct dc *dc);
-
-       /* HW State Logging Related */
-       void (*log_hw_state)(struct dc *dc, struct dc_log_buffer_ctx *log_ctx);
-       void (*get_hw_state)(struct dc *dc, char *pBuf,
-                       unsigned int bufSize, unsigned int mask);
-       void (*clear_status_bits)(struct dc *dc, unsigned int mask);
-
-       bool (*set_backlight_level)(struct pipe_ctx *pipe_ctx,
-                       uint32_t backlight_pwm_u16_16,
-                       uint32_t frame_ramp);
-
-       void (*set_abm_immediate_disable)(struct pipe_ctx *pipe_ctx);
-
-       void (*set_pipe)(struct pipe_ctx *pipe_ctx);
-
-       void (*enable_dp_link_output)(struct dc_link *link,
-                       const struct link_resource *link_res,
-                       enum signal_type signal,
-                       enum clock_source_id clock_source,
-                       const struct dc_link_settings *link_settings);
-       void (*enable_tmds_link_output)(struct dc_link *link,
-                       const struct link_resource *link_res,
-                       enum signal_type signal,
-                       enum clock_source_id clock_source,
-                       enum dc_color_depth color_depth,
-                       uint32_t pixel_clock);
-       void (*enable_lvds_link_output)(struct dc_link *link,
-                       const struct link_resource *link_res,
-                       enum clock_source_id clock_source,
-                       uint32_t pixel_clock);
-       void (*disable_link_output)(struct dc_link *link,
-                       const struct link_resource *link_res,
-                       enum signal_type signal);
-
-       void (*get_dcc_en_bits)(struct dc *dc, int *dcc_en_bits);
-
-       /* Idle Optimization Related */
-       bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable);
-
-       bool (*does_plane_fit_in_mall)(struct dc *dc, struct dc_plane_state *plane,
-                       struct dc_cursor_attributes *cursor_attr);
-       void (*commit_subvp_config)(struct dc *dc, struct dc_state *context);
-       void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context);
-       void (*subvp_pipe_control_lock)(struct dc *dc,
-                       struct dc_state *context,
-                       bool lock,
-                       bool should_lock_all_pipes,
-                       struct pipe_ctx *top_pipe_to_program,
-                       bool subvp_prev_use);
-       void (*subvp_pipe_control_lock_fast)(union block_sequence_params *params);
-
-       void (*z10_restore)(const struct dc *dc);
-       void (*z10_save_init)(struct dc *dc);
-       bool (*is_abm_supported)(struct dc *dc,
-                       struct dc_state *context, struct dc_stream_state *stream);
-
-       void (*set_disp_pattern_generator)(const struct dc *dc,
-                       struct pipe_ctx *pipe_ctx,
-                       enum controller_dp_test_pattern test_pattern,
-                       enum controller_dp_color_space color_space,
-                       enum dc_color_depth color_depth,
-                       const struct tg_color *solid_color,
-                       int width, int height, int offset);
-       void (*blank_phantom)(struct dc *dc,
-                       struct timing_generator *tg,
-                       int width,
-                       int height);
-       void (*update_visual_confirm_color)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx,
-                       int mpcc_id);
-       void (*update_phantom_vp_position)(struct dc *dc,
-                       struct dc_state *context,
-                       struct pipe_ctx *phantom_pipe);
-       void (*apply_update_flags_for_phantom)(struct pipe_ctx *phantom_pipe);
-
-       void (*calc_blocks_to_gate)(struct dc *dc, struct dc_state *context,
-               struct pg_block_update *update_state);
-       void (*calc_blocks_to_ungate)(struct dc *dc, struct dc_state *context,
-               struct pg_block_update *update_state);
-       void (*block_power_control)(struct dc *dc,
-               struct pg_block_update *update_state, bool power_on);
-       void (*root_clock_control)(struct dc *dc,
-               struct pg_block_update *update_state, bool power_on);
-       void (*set_idle_state)(const struct dc *dc, bool allow_idle);
-       uint32_t (*get_idle_state)(const struct dc *dc);
-       bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
-                       const struct dc_state *cur_ctx,
-                       const struct dc_state *new_ctx);
-};
-
-void color_space_to_black_color(
-       const struct dc *dc,
-       enum dc_color_space colorspace,
-       struct tg_color *black_color);
-
-bool hwss_wait_for_blank_complete(
-               struct timing_generator *tg);
-
-const uint16_t *find_color_matrix(
-               enum dc_color_space color_space,
-               uint32_t *array_size);
-
-void get_surface_tile_visual_confirm_color(
-               struct pipe_ctx *pipe_ctx,
-               struct tg_color *color);
-void get_surface_visual_confirm_color(
-               const struct pipe_ctx *pipe_ctx,
-               struct tg_color *color);
-
-void get_hdr_visual_confirm_color(
-               struct pipe_ctx *pipe_ctx,
-               struct tg_color *color);
-void get_mpctree_visual_confirm_color(
-               struct pipe_ctx *pipe_ctx,
-               struct tg_color *color);
-
-void get_subvp_visual_confirm_color(
-       struct dc *dc,
-       struct dc_state *context,
-       struct pipe_ctx *pipe_ctx,
-       struct tg_color *color);
-
-void get_mclk_switch_visual_confirm_color(
-               struct dc *dc,
-               struct dc_state *context,
-               struct pipe_ctx *pipe_ctx,
-               struct tg_color *color);
-
-void hwss_execute_sequence(struct dc *dc,
-               struct block_sequence block_sequence[],
-               int num_steps);
-
-void hwss_build_fast_sequence(struct dc *dc,
-               struct dc_dmub_cmd *dc_dmub_cmd,
-               unsigned int dmub_cmd_count,
-               struct block_sequence block_sequence[],
-               int *num_steps,
-               struct pipe_ctx *pipe_ctx);
-
-void hwss_send_dmcub_cmd(union block_sequence_params *params);
-
-void hwss_program_manual_trigger(union block_sequence_params *params);
-
-void hwss_setup_dpp(union block_sequence_params *params);
-
-void hwss_program_bias_and_scale(union block_sequence_params *params);
-
-void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params);
-
-void hwss_set_output_csc(union block_sequence_params *params);
-
-void hwss_set_ocsc_default(union block_sequence_params *params);
-
-void hwss_subvp_save_surf_addr(union block_sequence_params *params);
-
-#endif /* __DC_HW_SEQUENCER_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
deleted file mode 100644 (file)
index 82c5921..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2015 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_HW_SEQUENCER_PRIVATE_H__
-#define __DC_HW_SEQUENCER_PRIVATE_H__
-
-#include "dc_types.h"
-
-enum pipe_gating_control {
-       PIPE_GATING_CONTROL_DISABLE = 0,
-       PIPE_GATING_CONTROL_ENABLE,
-       PIPE_GATING_CONTROL_INIT
-};
-
-struct dce_hwseq_wa {
-       bool blnd_crtc_trigger;
-       bool DEGVIDCN10_253;
-       bool false_optc_underflow;
-       bool DEGVIDCN10_254;
-       bool DEGVIDCN21;
-       bool disallow_self_refresh_during_multi_plane_transition;
-       bool dp_hpo_and_otg_sequence;
-       bool wait_hubpret_read_start_during_mpo_transition;
-};
-
-struct hwseq_wa_state {
-       bool DEGVIDCN10_253_applied;
-       bool disallow_self_refresh_during_multi_plane_transition_applied;
-       unsigned int disallow_self_refresh_during_multi_plane_transition_applied_on_frame;
-};
-
-struct pipe_ctx;
-struct dc_state;
-struct dc_stream_status;
-struct dc_writeback_info;
-struct dchub_init_data;
-struct dc_static_screen_params;
-struct resource_pool;
-struct resource_context;
-struct stream_resource;
-struct dc_phy_addr_space_config;
-struct dc_virtual_addr_space_config;
-struct hubp;
-struct dpp;
-struct dce_hwseq;
-struct timing_generator;
-struct tg_color;
-struct output_pixel_processor;
-struct mpcc_blnd_cfg;
-
-struct hwseq_private_funcs {
-
-       void (*disable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx);
-       void (*enable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx);
-       void (*init_pipes)(struct dc *dc, struct dc_state *context);
-       void (*reset_hw_ctx_wrap)(struct dc *dc, struct dc_state *context);
-       void (*update_plane_addr)(const struct dc *dc,
-                       struct pipe_ctx *pipe_ctx);
-       void (*plane_atomic_disconnect)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx);
-       void (*update_mpcc)(struct dc *dc, struct pipe_ctx *pipe_ctx);
-       bool (*set_input_transfer_func)(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state);
-       bool (*set_output_transfer_func)(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               const struct dc_stream_state *stream);
-       void (*power_down)(struct dc *dc);
-       void (*enable_display_pipe_clock_gating)(struct dc_context *ctx,
-                                       bool clock_gating);
-       bool (*enable_display_power_gating)(struct dc *dc,
-                                       uint8_t controller_id,
-                                       struct dc_bios *dcb,
-                                       enum pipe_gating_control power_gating);
-       void (*blank_pixel_data)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx,
-                       bool blank);
-       enum dc_status (*enable_stream_timing)(
-                       struct pipe_ctx *pipe_ctx,
-                       struct dc_state *context,
-                       struct dc *dc);
-       void (*edp_backlight_control)(struct dc_link *link,
-                       bool enable);
-       void (*setup_vupdate_interrupt)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx);
-       bool (*did_underflow_occur)(struct dc *dc, struct pipe_ctx *pipe_ctx);
-       void (*init_blank)(struct dc *dc, struct timing_generator *tg);
-       void (*disable_vga)(struct dce_hwseq *hws);
-       void (*bios_golden_init)(struct dc *dc);
-       void (*plane_atomic_power_down)(struct dc *dc,
-                       struct dpp *dpp,
-                       struct hubp *hubp);
-       void (*plane_atomic_disable)(struct dc *dc, struct pipe_ctx *pipe_ctx);
-       void (*enable_power_gating_plane)(struct dce_hwseq *hws,
-               bool enable);
-       void (*dpp_root_clock_control)(
-                       struct dce_hwseq *hws,
-                       unsigned int dpp_inst,
-                       bool clock_on);
-       void (*dpp_pg_control)(struct dce_hwseq *hws,
-                       unsigned int dpp_inst,
-                       bool power_on);
-       void (*hubp_pg_control)(struct dce_hwseq *hws,
-                       unsigned int hubp_inst,
-                       bool power_on);
-       void (*dsc_pg_control)(struct dce_hwseq *hws,
-                       unsigned int dsc_inst,
-                       bool power_on);
-       bool (*dsc_pg_status)(struct dce_hwseq *hws,
-                       unsigned int dsc_inst);
-       void (*update_odm)(struct dc *dc, struct dc_state *context,
-                       struct pipe_ctx *pipe_ctx);
-       void (*program_all_writeback_pipes_in_tree)(struct dc *dc,
-                       const struct dc_stream_state *stream,
-                       struct dc_state *context);
-       bool (*s0i3_golden_init_wa)(struct dc *dc);
-       void (*set_hdr_multiplier)(struct pipe_ctx *pipe_ctx);
-       void (*verify_allow_pstate_change_high)(struct dc *dc);
-       void (*program_pipe)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx,
-                       struct dc_state *context);
-       bool (*wait_for_blank_complete)(struct output_pixel_processor *opp);
-       void (*dccg_init)(struct dce_hwseq *hws);
-       bool (*set_blend_lut)(struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_state *plane_state);
-       bool (*set_shaper_3dlut)(struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_state *plane_state);
-       bool (*set_mcm_luts)(struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_state *plane_state);
-       void (*PLAT_58856_wa)(struct dc_state *context,
-                       struct pipe_ctx *pipe_ctx);
-       void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
-       void (*enable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx,
-                              struct dc_state *context);
-#ifdef CONFIG_DRM_AMD_DC_FP
-       void (*program_mall_pipe_config)(struct dc *dc, struct dc_state *context);
-       void (*update_force_pstate)(struct dc *dc, struct dc_state *context);
-       void (*update_mall_sel)(struct dc *dc, struct dc_state *context);
-       unsigned int (*calculate_dccg_k1_k2_values)(struct pipe_ctx *pipe_ctx,
-                       unsigned int *k1_div,
-                       unsigned int *k2_div);
-       void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx);
-       void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc,
-                       struct dc_state *context);
-       bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx);
-#endif
-};
-
-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;
-       struct dce_hwseq_wa wa;
-       struct hwseq_wa_state wa_state;
-       struct hwseq_private_funcs funcs;
-
-       PHYSICAL_ADDRESS_LOC fb_base;
-       PHYSICAL_ADDRESS_LOC fb_top;
-       PHYSICAL_ADDRESS_LOC fb_offset;
-       PHYSICAL_ADDRESS_LOC uma_top;
-};
-
-#endif /* __DC_HW_SEQUENCER_PRIVATE_H__ */
index 50686fe..bc907ae 100644 (file)
@@ -2306,7 +2306,7 @@ struct dmub_cmd_psr_copy_settings_data {
         */
        uint8_t relock_delay_frame_cnt;
        /**
-        * Explicit padding to 2 byte boundary.
+        * Explicit padding to 4 byte boundary.
         */
        uint8_t pad3;
        /**
@@ -3139,6 +3139,7 @@ enum hw_lock_client {
         * PSR SU is the client of HW Lock Manager.
         */
        HW_LOCK_CLIENT_PSR_SU           = 1,
+       HW_LOCK_CLIENT_SUBVP = 3,
        /**
         * Replay is the client of HW Lock Manager.
         */