]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drm/amd/display: Rename more dc_surface stuff to plane_state
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / display / dc / dcn10 / dcn10_hw_sequencer.c
index 6cb3924225da996b99f55fc4530eb692db778227..5922cf8272f5d239553ee180e88f0cc46921b5a9 100644 (file)
  */
 
 #include "dm_services.h"
-#include "dc.h"
-#include "core_dc.h"
 #include "core_types.h"
-#include "core_status.h"
 #include "resource.h"
-#include "hw_sequencer.h"
+#include "custom_float.h"
 #include "dcn10_hw_sequencer.h"
 #include "dce110/dce110_hw_sequencer.h"
+#include "dce/dce_hwseq.h"
 #include "abm.h"
-
-#include "dcn10/dcn10_transform.h"
+#include "dcn10/dcn10_mem_input.h"
+#include "dcn10/dcn10_dpp.h"
 #include "dcn10/dcn10_mpc.h"
-#include "dcn10/dcn10_timing_generator.h"
-
-#include "mem_input.h"
 #include "timing_generator.h"
 #include "opp.h"
 #include "ipp.h"
-
-#include "dc_bios_types.h"
-
+#include "mpc.h"
 #include "raven1/DCN/dcn_1_0_offset.h"
 #include "raven1/DCN/dcn_1_0_sh_mask.h"
 #include "vega10/soc15ip.h"
+#include "reg_helper.h"
 
-#include "custom_float.h"
-
-
-struct dcn10_hwseq_reg_offsets {
-       uint32_t dchubp;
-       uint32_t dpp;
-       uint32_t otg;
-       uint32_t vtg;
-       uint32_t fmt;
-};
-
-/* TODO: move to resource */
-static const struct dcn10_hwseq_reg_offsets reg_offsets[] = {
-       {
-               .dchubp = (mmHUBP0_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
-               .dpp = (mmCM0_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
-               .otg = (mmOTG0_OTG_CONTROL - mmOTG0_OTG_CONTROL),
-               .vtg = (mmVTG0_CONTROL - mmVTG0_CONTROL),
-               .fmt = (mmFMT0_FMT_BIT_DEPTH_CONTROL -
-                               mmFMT0_FMT_BIT_DEPTH_CONTROL),
-       },
-       {
-               .dchubp = (mmHUBP1_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
-               .dpp = (mmCM1_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
-               .otg = (mmOTG1_OTG_CONTROL - mmOTG0_OTG_CONTROL),
-               .vtg = (mmVTG1_CONTROL - mmVTG0_CONTROL),
-               .fmt = (mmFMT1_FMT_BIT_DEPTH_CONTROL -
-                               mmFMT0_FMT_BIT_DEPTH_CONTROL),
-       },
-       {
-               .dchubp = (mmHUBP2_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
-               .dpp = (mmCM2_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
-               .otg = (mmOTG2_OTG_CONTROL - mmOTG0_OTG_CONTROL),
-               .vtg = (mmVTG2_CONTROL - mmVTG0_CONTROL),
-               .fmt = (mmFMT2_FMT_BIT_DEPTH_CONTROL -
-                               mmFMT0_FMT_BIT_DEPTH_CONTROL),
-       },
-       {
-               .dchubp = (mmHUBP3_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
-               .dpp = (mmCM3_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
-               .otg = (mmOTG3_OTG_CONTROL - mmOTG0_OTG_CONTROL),
-               .vtg = (mmVTG3_CONTROL - mmVTG0_CONTROL),
-               .fmt = (mmFMT3_FMT_BIT_DEPTH_CONTROL -
-                               mmFMT0_FMT_BIT_DEPTH_CONTROL),
-       }
-};
-
-#define HWSEQ_REG_UPDATE_N(reg_name, n, ...)   \
-               generic_reg_update_soc15(ctx, inst_offset, reg_name, n, __VA_ARGS__)
-
-#define HWSEQ_REG_SET_N(reg_name, n, ...)      \
-               generic_reg_set_soc15(ctx, inst_offset, reg_name, n, __VA_ARGS__)
+#define CTX \
+       hws->ctx
+#define REG(reg)\
+       hws->regs->reg
 
-#define HWSEQ_REG_UPDATE(reg, field, val)      \
-               HWSEQ_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
+#undef FN
+#define FN(reg_name, field_name) \
+       hws->shifts->field_name, hws->masks->field_name
 
-#define HWSEQ_REG_UPDATE_2(reg, field1, val1, field2, val2)    \
-               HWSEQ_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
 
-#define HWSEQ_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3)      \
-               HWSEQ_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-
-
-#define HWSEQ_REG_SET(reg, field, val) \
-               HWSEQ_REG_SET_N(reg, 1, FD(reg##__##field), val)
-
-/* TODO should be moved to OTG */
-static void lock_otg_master_update(
-       struct dc_context *ctx,
-       uint8_t inst)
-{
-       uint32_t inst_offset = reg_offsets[inst].otg;
-
-       HWSEQ_REG_UPDATE(OTG0_OTG_GLOBAL_CONTROL0,
-                       OTG_MASTER_UPDATE_LOCK_SEL, inst);
-
-       /* unlock master locker */
-       HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK,
-                       OTG_MASTER_UPDATE_LOCK, 1);
-
-       /* wait for unlock happens */
-       if (!wait_reg(ctx, inst_offset, OTG0_OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, 1))
-                       BREAK_TO_DEBUGGER();
-
-}
-
-static bool unlock_master_tg_and_wait(
-       struct dc_context *ctx,
-       uint8_t inst)
+static void verify_allow_pstate_change_high(
+       struct dce_hwseq *hws)
 {
-       uint32_t inst_offset = reg_offsets[inst].otg;
+       /* pstate latency is ~20us so if we wait over 40us and pstate allow
+        * still not asserted, we are probably stuck and going to hang
+        */
+       static unsigned int pstate_wait_timeout_us = 40;
+       static unsigned int max_sampled_pstate_wait_us; /* data collection */
+       static bool forced_pstate_allow; /* help with revert wa */
 
-       HWSEQ_REG_UPDATE(OTG0_OTG_GLOBAL_SYNC_STATUS,
-                       VUPDATE_NO_LOCK_EVENT_CLEAR, 1);
-       HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, 0);
+       unsigned int debug_index = 0x7;
+       unsigned int debug_data;
+       unsigned int force_allow_pstate = 0x30;
+       unsigned int i;
 
-       if (!wait_reg(ctx, inst_offset, OTG0_OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_OCCURRED, 1)) {
-               dm_logger_write(ctx->logger, LOG_ERROR,
-                               "wait for VUPDATE_NO_LOCK_EVENT_OCCURRED failed\n");
-               BREAK_TO_DEBUGGER();
-               return false;
+       if (forced_pstate_allow) {
+               /* we hacked to force pstate allow to prevent hang last time
+                * we verify_allow_pstate_change_high.  so disable force
+                * here so we can check status
+                */
+               REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0);
+               forced_pstate_allow = false;
        }
-       return true;
-}
-
-/* TODO: should be  moved to OTG ? */
-static void unlock_otg_master(
-       struct dc_context *ctx,
-       uint8_t inst)
-{
-       uint32_t inst_offset = reg_offsets[inst].otg;
-
-       /* unlock master locker */
-       HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK,
-                       OTG_MASTER_UPDATE_LOCK, 0);
-}
-
-
-static void wait_no_outstanding_request(
-       struct dc_context *ctx,
-       uint8_t plane_id)
-{
-       uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
-       if (!wait_reg(ctx, inst_offset, HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, 1))
-                               BREAK_TO_DEBUGGER();
-}
-
-static void disable_clocks(
-       struct dc_context *ctx,
-       uint8_t plane_id)
-{
-       uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
-       generic_reg_update_soc15(ctx, inst_offset, HUBP0_HUBP_CLK_CNTL, 1,
-                       FD(HUBP0_HUBP_CLK_CNTL__HUBP_CLOCK_ENABLE), 0);
-
-       inst_offset = reg_offsets[plane_id].dpp;
-       generic_reg_update_soc15(ctx, inst_offset, DPP_TOP0_DPP_CONTROL, 1,
-                               FD(DPP_TOP0_DPP_CONTROL__DPP_CLOCK_ENABLE), 0);
-}
 
-/* TODO: This is one time program during system boot up,
- * this should be done within BIOS or CAIL
- */
-static void dchubp_map_fb_to_mc(struct dc_context *ctx)
-{
-       /* TODO: do not know where to program
-        * DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB
-        */
-       /*
-        * TODO: For real ASIC, FB_OFFSET may be need change to the same value
-        * as FB_BASE. Need re-visit this for real ASIC.
+       /* description "3-0:   Pipe0 cursor0 QOS
+        * 7-4:   Pipe1 cursor0 QOS
+        * 11-8:  Pipe2 cursor0 QOS
+        * 15-12: Pipe3 cursor0 QOS
+        * 16:    Pipe0 Plane0 Allow Pstate Change
+        * 17:    Pipe1 Plane0 Allow Pstate Change
+        * 18:    Pipe2 Plane0 Allow Pstate Change
+        * 19:    Pipe3 Plane0 Allow Pstate Change
+        * 20:    Pipe0 Plane1 Allow Pstate Change
+        * 21:    Pipe1 Plane1 Allow Pstate Change
+        * 22:    Pipe2 Plane1 Allow Pstate Change
+        * 23:    Pipe3 Plane1 Allow Pstate Change
+        * 24:    Pipe0 cursor0 Allow Pstate Change
+        * 25:    Pipe1 cursor0 Allow Pstate Change
+        * 26:    Pipe2 cursor0 Allow Pstate Change
+        * 27:    Pipe3 cursor0 Allow Pstate Change
+        * 28:    WB0 Allow Pstate Change
+        * 29:    WB1 Allow Pstate Change
+        * 30:    Arbiter's allow_pstate_change
+        * 31:    SOC pstate change request
         */
-       dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_BASE, 0, 0x80);
-       dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_OFFSET, 0, 0);
-       dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_TOP, 0, 0xFF);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_CFG0, 7,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_DATA_RESPONSE_STATUS_CLEAR), 0,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_REQ_CREDIT_ERROR_CLEAR), 0,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_FLUSH_REQ_CREDIT_EN), 0,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_REQ_CREDIT_EN), 0,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_PORT_CONTROL), 1,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_UNIT_ID_BITMASK), 0xd3,
-                       FD(DCHUBBUB_SDPIF_CFG0__SDPIF_CREDIT_DISCONNECT_DELAY), 0xc);
-
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_CFG1, 4,
-                       FD(DCHUBBUB_SDPIF_CFG1__SDPIF_INSIDE_FB_IO), 0,
-                       FD(DCHUBBUB_SDPIF_CFG1__SDPIF_INSIDE_FB_VC), 6,
-                       FD(DCHUBBUB_SDPIF_CFG1__SDPIF_OUTSIDE_FB_IO), 1,
-                       FD(DCHUBBUB_SDPIF_CFG1__SDPIF_OUTSIDE_FB_VC), 6);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_FB_BASE, 1,
-                       FD(DCHUBBUB_SDPIF_FB_BASE__SDPIF_FB_BASE), 0x000080);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_FB_TOP, 1,
-                       FD(DCHUBBUB_SDPIF_FB_TOP__SDPIF_FB_TOP), 0x0000ff);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_BOT, 1,
-                       FD(DCHUBBUB_SDPIF_AGP_BOT__SDPIF_AGP_BOT), 0x0000040);
 
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_TOP, 1,
-                       FD(DCHUBBUB_SDPIF_AGP_TOP__SDPIF_AGP_TOP), 0x00001ff);
+       REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index);
 
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_BASE, 1,
-                       FD(DCHUBBUB_SDPIF_AGP_BASE__SDPIF_AGP_BASE), 0x0000080);
+       for (i = 0; i < pstate_wait_timeout_us; i++) {
+               debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
 
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_APER_TOP, 1,
-                       FD(DCHUBBUB_SDPIF_APER_TOP__SDPIF_APER_TOP), 0x00007ff);
+               if (debug_data & (1 << 30))
+                       return;
 
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_APER_DEF_0, 1,
-                       FD(DCHUBBUB_SDPIF_APER_DEF_0__SDPIF_APER_DEF_0), 0xdeadbeef);
+               if (max_sampled_pstate_wait_us < i)
+                       max_sampled_pstate_wait_us = i;
 
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_0, 2,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_0__SDPIF_MARC_EN_0), 0,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_0__SDPIF_MARC_RELOC_LO_0), 0x90000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_0, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_0__SDPIF_MARC_LENGTH_LO_0), 0x10000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_1, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_BASE_LO_1__SDPIF_MARC_BASE_LO_1), 0x10000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_1, 2,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_1__SDPIF_MARC_EN_1), 0,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_1__SDPIF_MARC_RELOC_LO_1), 0xa0000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_1, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_1__SDPIF_MARC_LENGTH_LO_1), 0x10000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_2, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_BASE_LO_2__SDPIF_MARC_BASE_LO_2), 0x20000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_2, 2,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_2__SDPIF_MARC_EN_2), 0,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_2__SDPIF_MARC_RELOC_LO_2), 0xb0000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_2, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_2__SDPIF_MARC_LENGTH_LO_2), 0x10000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_3, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_BASE_LO_3__SDPIF_MARC_BASE_LO_3), 0x30000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_3, 2,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_3__SDPIF_MARC_EN_3), 0,
-                       FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_3__SDPIF_MARC_RELOC_LO_3), 0xc0000);
-
-       generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_3, 1,
-                       FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_3__SDPIF_MARC_LENGTH_LO_3), 0x10000);
+               udelay(1);
+       }
 
-       /* TODO: Is DCN_VM_SYSTEM_APERTURE address one time programming?
-        * Are all 4 hubp programmed with the same address?
+       /* force pstate allow to prevent system hang
+        * and break to debugger to investigate
         */
-       dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-
-       dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-
-       dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-
-       dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
-       dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
-       dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-}
-
-/* TODO: This is one time program during system boot up,
- * this should be done within BIOS
- */
-static void dchubup_setup_timer(struct dc_context *ctx)
-{
-       dm_write_reg_soc15(ctx, mmREFCLK_CNTL, 0, 0);
-
-       generic_reg_update_soc15(ctx, 0, DCHUBBUB_GLOBAL_TIMER_CNTL, 1,
-                       FD(DCHUBBUB_GLOBAL_TIMER_CNTL__DCHUBBUB_GLOBAL_TIMER_ENABLE), 1);
-}
-
-/* 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
- */
-static void select_vtg(
-       struct dc_context *ctx,
-       uint8_t plane_id,
-       uint8_t inst)
-{
-       uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
-       HWSEQ_REG_UPDATE(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, inst);
-}
-
-static void enable_dcfclk(
-       struct dc_context *ctx,
-       uint8_t plane_id,
-       uint32_t requested_pix_clk,
-       bool dppclk_div)
-{
-       uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
-       HWSEQ_REG_UPDATE(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, 1);
+       REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate);
+       forced_pstate_allow = true;
+       BREAK_TO_DEBUGGER();
 }
 
 static void enable_dppclk(
-       struct dc_context *ctx,
+       struct dce_hwseq *hws,
        uint8_t plane_id,
        uint32_t requested_pix_clk,
        bool dppclk_div)
 {
-       uint32_t inst_offset = reg_offsets[plane_id].dpp;
-
-       dm_logger_write(ctx->logger, LOG_SURFACE,
+       dm_logger_write(hws->ctx->logger, LOG_SURFACE,
                        "dppclk_rate_control for pipe %d programed to %d\n",
                        plane_id,
                        dppclk_div);
 
-       /* TODO: find condition for DPP clock to DISPCLK or 1/2 DISPCLK */
-       if (dppclk_div) {
-               /* 1/2 DISPCLK*/
-               HWSEQ_REG_UPDATE_2(DPP_TOP0_DPP_CONTROL,
-                       DPPCLK_RATE_CONTROL, 1,
+       if (hws->shifts->DPPCLK_RATE_CONTROL)
+               REG_UPDATE_2(DPP_CONTROL[plane_id],
+                       DPPCLK_RATE_CONTROL, dppclk_div,
                        DPP_CLOCK_ENABLE, 1);
-       } else {
-               /* DISPCLK */
-               HWSEQ_REG_UPDATE_2(DPP_TOP0_DPP_CONTROL,
-                       DPPCLK_RATE_CONTROL, 0,
+       else
+               REG_UPDATE(DPP_CONTROL[plane_id],
                        DPP_CLOCK_ENABLE, 1);
-       }
 }
 
 static void enable_power_gating_plane(
-       struct dc_context *ctx,
+       struct dce_hwseq *hws,
        bool enable)
 {
-       uint32_t inst_offset = 0; /* each register only has one instance */
        bool force_on = 1; /* disable power gating */
 
        if (enable)
                force_on = 0;
 
        /* DCHUBP0/1/2/3 */
-       HWSEQ_REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
-       HWSEQ_REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
-       HWSEQ_REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
-       HWSEQ_REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
+       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 */
-       HWSEQ_REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
-       HWSEQ_REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
-       HWSEQ_REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
-       HWSEQ_REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
-
-       if (ctx->dc->debug.disable_clock_gate) {
-               /* probably better to just write entire register to 0xffff to
-                * ensure all clock gating is disabled
-                */
-               HWSEQ_REG_UPDATE_3(DCCG_GATE_DISABLE_CNTL,
-                               DISPCLK_R_DCCG_GATE_DISABLE, 1,
-                               DPREFCLK_R_DCCG_GATE_DISABLE, 1,
-                               REFCLK_R_DIG_GATE_DISABLE, 1);
-               HWSEQ_REG_UPDATE(DCFCLK_CNTL,
-                               DCFCLK_GATE_DIS, 1);
-       }
+       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);
+}
 
+static void 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);
 }
 
 static void dpp_pg_control(
-               struct dc_context *ctx,
+               struct dce_hwseq *hws,
                unsigned int dpp_inst,
                bool power_on)
 {
-       uint32_t inst_offset = 0;
        uint32_t power_gate = power_on ? 0 : 1;
        uint32_t pwr_status = power_on ? 0 : 2;
 
-       if (ctx->dc->debug.disable_dpp_power_gate)
+       if (hws->ctx->dc->debug.disable_dpp_power_gate)
                return;
 
        switch (dpp_inst) {
        case 0: /* DPP0 */
-               HWSEQ_REG_UPDATE(DOMAIN1_PG_CONFIG,
+               REG_UPDATE(DOMAIN1_PG_CONFIG,
                                DOMAIN1_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN1_PG_STATUS,
-                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN1_PG_STATUS,
+                               DOMAIN1_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        case 1: /* DPP1 */
-               HWSEQ_REG_UPDATE(DOMAIN3_PG_CONFIG,
+               REG_UPDATE(DOMAIN3_PG_CONFIG,
                                DOMAIN3_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN3_PG_STATUS,
-                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN3_PG_STATUS,
+                               DOMAIN3_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        case 2: /* DPP2 */
-               HWSEQ_REG_UPDATE(DOMAIN5_PG_CONFIG,
+               REG_UPDATE(DOMAIN5_PG_CONFIG,
                                DOMAIN5_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN5_PG_STATUS,
-                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN5_PG_STATUS,
+                               DOMAIN5_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        case 3: /* DPP3 */
-               HWSEQ_REG_UPDATE(DOMAIN7_PG_CONFIG,
+               REG_UPDATE(DOMAIN7_PG_CONFIG,
                                DOMAIN7_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN7_PG_STATUS,
-                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN7_PG_STATUS,
+                               DOMAIN7_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        default:
                BREAK_TO_DEBUGGER();
@@ -459,46 +218,345 @@ static void dpp_pg_control(
        }
 }
 
+static uint32_t convert_and_clamp(
+       uint32_t wm_ns,
+       uint32_t refclk_mhz,
+       uint32_t clamp_value)
+{
+       uint32_t ret_val = 0;
+       ret_val = wm_ns * refclk_mhz;
+       ret_val /= 1000;
+
+       if (ret_val > clamp_value)
+               ret_val = clamp_value;
+
+       return ret_val;
+}
+
+static void program_watermarks(
+               struct dce_hwseq *hws,
+               struct dcn_watermark_set *watermarks,
+               unsigned int refclk_mhz)
+{
+       uint32_t force_en = hws->ctx->dc->debug.disable_stutter ? 1 : 0;
+       /*
+        * Need to clamp to max of the register values (i.e. no wrap)
+        * for dcn1, all wm registers are 21-bit wide
+        */
+       uint32_t prog_wm_value;
+
+       /* Repeat for water mark set A, B, C and D. */
+       /* clock state A */
+       prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
+
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "URGENCY_WATERMARK_A calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->a.urgent_ns, prog_wm_value);
+
+       prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->a.pte_meta_urgent_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
+                       refclk_mhz, 0x1fffff);
+
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->a.cstate_pstate.cstate_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_EXIT_WATERMARK_A calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->a.cstate_pstate.pstate_change_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
+               "HW register value = 0x%x\n\n",
+               watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+
+       /* clock state B */
+       prog_wm_value = convert_and_clamp(
+                       watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "URGENCY_WATERMARK_B calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->b.urgent_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->b.pte_meta_urgent_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->b.pte_meta_urgent_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_ENTER_WATERMARK_B calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->b.cstate_pstate.cstate_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_EXIT_WATERMARK_B calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->b.cstate_pstate.pstate_change_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
+               "HW register value = 0x%x\n",
+               watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+       /* clock state C */
+       prog_wm_value = convert_and_clamp(
+                       watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "URGENCY_WATERMARK_C calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->c.urgent_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->c.pte_meta_urgent_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->c.pte_meta_urgent_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_ENTER_WATERMARK_C calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->c.cstate_pstate.cstate_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_EXIT_WATERMARK_C calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->c.cstate_pstate.pstate_change_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
+               "HW register value = 0x%x\n",
+               watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+       /* clock state D */
+       prog_wm_value = convert_and_clamp(
+                       watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "URGENCY_WATERMARK_D calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->d.urgent_ns, prog_wm_value);
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->d.pte_meta_urgent_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->d.pte_meta_urgent_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_ENTER_WATERMARK_D calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->d.cstate_pstate.cstate_exit_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "SR_EXIT_WATERMARK_D calculated =%d\n"
+               "HW register value = 0x%x\n",
+               watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+
+       prog_wm_value = convert_and_clamp(
+                       watermarks->d.cstate_pstate.pstate_change_ns,
+                       refclk_mhz, 0x1fffff);
+       REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
+       dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+               "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
+               "HW register value = 0x%x\n\n",
+               watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+       REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
+                       DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
+       REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
+                       DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0);
+       REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
+                       DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
+       REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
+                       DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
+
+       REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+                       DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
+                       DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en);
+
+#if 0
+       REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
+                       DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
+                       DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
+#endif
+}
+
+
+static void dcn10_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(DCHUBBUB_SDPIF_FB_TOP,
+                               SDPIF_FB_TOP, 0);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
+                               SDPIF_FB_BASE, 0x0FFFF);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
+                               SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
+                               SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
+                               SDPIF_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(DCHUBBUB_SDPIF_AGP_BASE,
+                               SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
+                               SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
+                               SDPIF_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(DCHUBBUB_SDPIF_AGP_BASE,
+                               SDPIF_AGP_BASE, 0);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
+                               SDPIF_AGP_BOT, 0X03FFFF);
+
+               REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
+                               SDPIF_AGP_TOP, 0);
+               break;
+       default:
+               break;
+       }
+
+       dh_data->dchub_initialzied = true;
+       dh_data->dchub_info_valid = false;
+}
+
 static void hubp_pg_control(
-               struct dc_context *ctx,
+               struct dce_hwseq *hws,
                unsigned int hubp_inst,
                bool power_on)
 {
-       uint32_t inst_offset = 0;
        uint32_t power_gate = power_on ? 0 : 1;
        uint32_t pwr_status = power_on ? 0 : 2;
 
-       if (ctx->dc->debug.disable_hubp_power_gate)
+       if (hws->ctx->dc->debug.disable_hubp_power_gate)
                return;
 
        switch (hubp_inst) {
        case 0: /* DCHUBP0 */
-               HWSEQ_REG_UPDATE(DOMAIN0_PG_CONFIG,
+               REG_UPDATE(DOMAIN0_PG_CONFIG,
                                DOMAIN0_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN0_PG_STATUS,
-                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN0_PG_STATUS,
+                               DOMAIN0_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        case 1: /* DCHUBP1 */
-               HWSEQ_REG_UPDATE(DOMAIN2_PG_CONFIG,
+               REG_UPDATE(DOMAIN2_PG_CONFIG,
                                DOMAIN2_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN2_PG_STATUS,
-                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN2_PG_STATUS,
+                               DOMAIN2_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        case 2: /* DCHUBP2 */
-               HWSEQ_REG_UPDATE(DOMAIN4_PG_CONFIG,
+               REG_UPDATE(DOMAIN4_PG_CONFIG,
                                DOMAIN4_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN4_PG_STATUS,
-                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN4_PG_STATUS,
+                               DOMAIN4_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        case 3: /* DCHUBP3 */
-               HWSEQ_REG_UPDATE(DOMAIN6_PG_CONFIG,
+               REG_UPDATE(DOMAIN6_PG_CONFIG,
                                DOMAIN6_POWER_GATE, power_gate);
 
-               wait_reg(ctx, 0, DOMAIN6_PG_STATUS,
-                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status);
+               REG_WAIT(DOMAIN6_PG_STATUS,
+                               DOMAIN6_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
                break;
        default:
                BREAK_TO_DEBUGGER();
@@ -507,60 +565,17 @@ static void hubp_pg_control(
 }
 
 static void power_on_plane(
-       struct dc_context *ctx,
-       uint8_t plane_id,
-       uint8_t inst)
+       struct dce_hwseq *hws,
+       int plane_id)
 {
-       uint32_t inst_offset = 0;
-
-       /* disable clock power gating */
-
-       /* DCCG_GATE_DISABLE_CNTL only has one instance */
-       HWSEQ_REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL,
-                       DISPCLK_DCCG_GATE_DISABLE, 1,
-                       DPPCLK_GATE_DISABLE, 1);
-       /* DCFCLK_CNTL only has one instance */
-       HWSEQ_REG_UPDATE(DCFCLK_CNTL,
-                       DCFCLK_GATE_DIS, 1);
-
-       HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
                        IP_REQUEST_EN, 1);
-       dpp_pg_control(ctx, plane_id, true);
-       hubp_pg_control(ctx, plane_id, true);
-       HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
+       dpp_pg_control(hws, plane_id, true);
+       hubp_pg_control(hws, plane_id, true);
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
                        IP_REQUEST_EN, 0);
-
-       if (ctx->dc->debug.disable_clock_gate) {
-               HWSEQ_REG_UPDATE(DCCG_GATE_DISABLE_CNTL,
-                               DISPCLK_DCCG_GATE_DISABLE, 0);
-       } else {
-               /* DCCG_GATE_DISABLE_CNTL only has one instance. inst_offset = 0 */
-               HWSEQ_REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL,
-                               DISPCLK_DCCG_GATE_DISABLE, 0,
-                               DPPCLK_GATE_DISABLE, 0);
-               /* DCFCLK_CNTL only has one instance. inst_offset = 0 */
-               HWSEQ_REG_UPDATE(DCFCLK_CNTL,
-                               DCFCLK_GATE_DIS, 0);
-       }
-}
-
-/* fully check bios enabledisplaypowergating table. dal only need dce init
- * other power, clock gate register will be handle by dal itself.
- * further may be put within init_hw
- */
-static bool dcn10_enable_display_power_gating(
-       struct core_dc *dc,
-       uint8_t controller_id,
-       struct dc_bios *dcb,
-       enum pipe_gating_control power_gating)
-{
-       /* TODOFPGA */
-#if 0
-       if (power_gating != PIPE_GATING_CONTROL_ENABLE)
-               dce110_init_pte(ctx);
-#endif
-
-       return true;
+       dm_logger_write(hws->ctx->logger, LOG_DC,
+                       "Un-gated front end for pipe %d\n", plane_id);
 }
 
 static void bios_golden_init(struct core_dc *dc)
@@ -579,63 +594,52 @@ static void bios_golden_init(struct core_dc *dc)
        }
 }
 
-static void init_hw(struct core_dc *dc)
+static void dcn10_init_hw(struct core_dc *dc)
 {
        int i;
-       struct dc_bios *bp;
-       struct transform *xfm;
-       struct abm *abm;
-
-       bp = dc->ctx->dc_bios;
+       struct abm *abm = dc->res_pool->abm;
+       struct dce_hwseq *hws = dc->hwseq;
 
        if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-               /* TODO: this will be moved to Diag or BIOS */
-               dchubup_setup_timer(dc->ctx);
+               REG_WRITE(REFCLK_CNTL, 0);
+               REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
+               REG_WRITE(DIO_MEM_PWR_CTRL, 0);
 
-               /* TODO: dchubp_map_fb_to_mc will be moved to dchub interface
-                * between dc and kmd
-                */
-               dchubp_map_fb_to_mc(dc->ctx);
+               if (!dc->public.debug.disable_clock_gate) {
+                       /* enable all DCN clock gating */
+                       REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
 
-               enable_power_gating_plane(dc->ctx, true);
+                       REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+                       REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+               }
+
+               enable_power_gating_plane(dc->hwseq, true);
                return;
        }
        /* end of FPGA. Below if real ASIC */
 
        bios_golden_init(dc);
 
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               xfm = dc->res_pool->transforms[i];
-               xfm->funcs->transform_reset(xfm);
-
-               /* TODOFPGA: may need later */
-#if 0
-               xfm->funcs->transform_power_up(xfm);
-               dc->hwss.enable_display_pipe_clock_gating(
-                       dc->ctx,
-                       true);
-#endif
-       }
-       /* TODOFPGA: light sleep */
-#if 0
-       dc->hwss.clock_gating_power_up(dc->ctx, false);
-#endif
+       disable_vga(dc->hwseq);
 
        for (i = 0; i < dc->link_count; i++) {
                /* Power up AND update implementation according to the
                 * required signal (which may be different from the
                 * default signal on connector).
                 */
-               struct core_link *link = dc->links[i];
+               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];
+               struct transform *xfm = dc->res_pool->transforms[i];
+               struct timing_generator *tg = dc->res_pool->timing_generators[i];
 
-               tg->funcs->disable_vga(tg);
+               xfm->funcs->transform_reset(xfm);
+               dc->res_pool->mpc->funcs->remove(
+                               dc->res_pool->mpc, dc->res_pool->opps[i], i);
 
                /* Blank controller using driver code instead of
                 * command table.
@@ -650,30 +654,24 @@ static void init_hw(struct core_dc *dc)
                audio->funcs->hw_init(audio);
        }
 
-       abm = dc->res_pool->abm;
        if (abm != NULL) {
                abm->funcs->init_backlight(abm);
                abm->funcs->abm_init(abm);
        }
 
        /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
-       generic_reg_set_soc15(dc->ctx, 0, DIO_MEM_PWR_CTRL, 7,
-                       FD(DIO_MEM_PWR_CTRL__HDMI0_MEM_PWR_FORCE), 0,
-                       FD(DIO_MEM_PWR_CTRL__HDMI1_MEM_PWR_FORCE), 0,
-                       FD(DIO_MEM_PWR_CTRL__HDMI2_MEM_PWR_FORCE), 0,
-                       FD(DIO_MEM_PWR_CTRL__HDMI3_MEM_PWR_FORCE), 0,
-                       FD(DIO_MEM_PWR_CTRL__HDMI4_MEM_PWR_FORCE), 0,
-                       FD(DIO_MEM_PWR_CTRL__HDMI5_MEM_PWR_FORCE), 0,
-                       FD(DIO_MEM_PWR_CTRL__HDMI6_MEM_PWR_FORCE), 0);
-
-       /* This power gating should be one-time program for DAL.
-        * It can only change by registry key
-        * TODO: new task will for this.
-        * if power gating is disable, power_on_plane and power_off_plane
-        * should be skip. Otherwise, hand will be met in power_off_plane
-        */
+       REG_WRITE(DIO_MEM_PWR_CTRL, 0);
 
-       enable_power_gating_plane(dc->ctx, true);
+       if (!dc->public.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);
+       }
+
+       enable_power_gating_plane(dc->hwseq, true);
 }
 
 static enum dc_status dcn10_prog_pixclk_crtc_otg(
@@ -681,12 +679,12 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
                struct validate_context *context,
                struct core_dc *dc)
 {
-       struct core_stream *stream = pipe_ctx->stream;
+       struct dc_stream_state *stream = pipe_ctx->stream;
        enum dc_color_space color_space;
        struct tg_color black_color = {0};
-       bool enableStereo    = stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_NONE ?
+       bool enableStereo    = stream->timing.timing_3d_format == TIMING_3D_FORMAT_NONE ?
                        false:true;
-       bool rightEyePolarity = stream->public.timing.flags.RIGHT_EYE_3D_POLARITY;
+       bool rightEyePolarity = stream->timing.flags.RIGHT_EYE_3D_POLARITY;
 
 
        /* by upper caller loop, pipe0 is parent pipe and be called first.
@@ -719,7 +717,7 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
 
        pipe_ctx->tg->funcs->program_timing(
                        pipe_ctx->tg,
-                       &stream->public.timing,
+                       &stream->timing,
                        true);
 
        pipe_ctx->opp->funcs->opp_set_stereo_polarity(
@@ -739,7 +737,7 @@ static enum dc_status dcn10_prog_pixclk_crtc_otg(
                                &stream->clamping);
 #endif
        /* program otg blank color */
-       color_space = stream->public.output_color_space;
+       color_space = stream->output_color_space;
        color_space_to_black_color(dc, color_space, &black_color);
        pipe_ctx->tg->funcs->set_blank_color(
                        pipe_ctx->tg,
@@ -771,9 +769,6 @@ static void reset_back_end_for_pipe(
                struct validate_context *context)
 {
        int i;
-       struct dc_bios *bp;
-
-       bp = dc->ctx->dc_bios;
 
        if (pipe_ctx->stream_enc == NULL) {
                pipe_ctx->stream = NULL;
@@ -810,112 +805,258 @@ static void reset_back_end_for_pipe(
                return;
 
        pipe_ctx->stream = NULL;
+       dm_logger_write(dc->ctx->logger, LOG_DC,
+                                       "Reset back end for pipe %d, tg:%d\n",
+                                       pipe_ctx->pipe_idx, pipe_ctx->tg->inst);
 }
 
-static void reset_front_end_for_pipe(
+/* trigger HW to start disconnect plane from stream on the next vsync */
+static void plane_atomic_disconnect(struct core_dc *dc,
+               int fe_idx)
+{
+       struct mem_input *mi = dc->res_pool->mis[fe_idx];
+       struct mpc *mpc = dc->res_pool->mpc;
+       int opp_id, z_idx;
+       int mpcc_id = -1;
+
+       /* look at tree rather than mi here to know if we already reset */
+       for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
+               struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
+
+               for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) {
+                       if (opp->mpc_tree.dpp[z_idx] == fe_idx) {
+                               mpcc_id = opp->mpc_tree.mpcc[z_idx];
+                               break;
+                       }
+               }
+               if (mpcc_id != -1)
+                       break;
+       }
+       /*Already reset*/
+       if (opp_id == dc->res_pool->pipe_count)
+               return;
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+       mi->funcs->dcc_control(mi, false, false);
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+
+       mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx);
+}
+
+/* disable HW used by plane.
+ * note:  cannot disable until disconnect is complete */
+static void plane_atomic_disable(struct core_dc *dc,
+               int fe_idx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct mem_input *mi = dc->res_pool->mis[fe_idx];
+       struct mpc *mpc = dc->res_pool->mpc;
+       int opp_id = mi->opp_id;
+
+       if (opp_id == 0xf)
+               return;
+
+       mpc->funcs->wait_for_idle(mpc, mi->mpcc_id);
+       dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false;
+       /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+                       "[debug_mpo: atomic disable finished on mpcc %d]\n",
+                       fe_idx);*/
+
+       mi->funcs->set_blank(mi, true);
+       /*todo: unhack this*/
+       mi->opp_id = 0xf;
+       mi->mpcc_id = 0xf;
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+
+       REG_UPDATE(HUBP_CLK_CNTL[fe_idx],
+                       HUBP_CLOCK_ENABLE, 0);
+       REG_UPDATE(DPP_CONTROL[fe_idx],
+                       DPP_CLOCK_ENABLE, 0);
+
+       if (dc->res_pool->opps[opp_id]->mpc_tree.num_pipes == 0)
+               REG_UPDATE(OPP_PIPE_CONTROL[opp_id],
+                               OPP_PIPE_CLOCK_EN, 0);
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+}
+
+/*
+ * kill power to plane hw
+ * note: cannot power down until plane is disable
+ */
+static void plane_atomic_power_down(struct core_dc *dc, int fe_idx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct transform *xfm = dc->res_pool->transforms[fe_idx];
+
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 1);
+       dpp_pg_control(hws, fe_idx, false);
+       hubp_pg_control(hws, fe_idx, false);
+       xfm->funcs->transform_reset(xfm);
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 0);
+       dm_logger_write(dc->ctx->logger, LOG_DC,
+                       "Power gated front end %d\n", fe_idx);
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+}
+
+
+static void reset_front_end(
                struct core_dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               struct validate_context *context)
+               int fe_idx)
 {
-       struct dcn10_mpc *mpc = TO_DCN10_MPC(dc->res_pool->mpc);
-       struct mpc_tree_cfg *tree_cfg = NULL;
+       struct dce_hwseq *hws = dc->hwseq;
+       struct timing_generator *tg;
+       int opp_id = dc->res_pool->mis[fe_idx]->opp_id;
 
-       if (!pipe_ctx->surface)
+       /*Already reset*/
+       if (opp_id == 0xf)
                return;
 
-       lock_otg_master_update(dc->ctx, pipe_ctx->tg->inst);
+       tg = dc->res_pool->timing_generators[opp_id];
+       tg->funcs->lock(tg);
 
-       /* TODO: build stream pipes group id. For now, use stream otg
-        * id as pipe group id
-        */
-       tree_cfg = &dc->current_context->res_ctx.mpc_tree[pipe_ctx->mpc_idx];
-
-       if (pipe_ctx->top_pipe == NULL)
-               dcn10_delete_mpc_tree(mpc, tree_cfg);
-       else {
-               if (dcn10_remove_dpp(mpc, tree_cfg, pipe_ctx->pipe_idx))
-                       pipe_ctx->top_pipe->bottom_pipe = NULL;
-               else {
-                       dm_logger_write(dc->ctx->logger, LOG_RESOURCE,
-                               "%s: failed to find dpp to be removed!\n",
-                               __func__);
-               }
-       }
+       plane_atomic_disconnect(dc, fe_idx);
 
-       pipe_ctx->top_pipe = NULL;
-       pipe_ctx->bottom_pipe = NULL;
-       pipe_ctx->mpc_idx = -1;
+       REG_UPDATE(OTG_GLOBAL_SYNC_STATUS[tg->inst], VUPDATE_NO_LOCK_EVENT_CLEAR, 1);
+       tg->funcs->unlock(tg);
 
-       unlock_master_tg_and_wait(dc->ctx, pipe_ctx->tg->inst);
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(hws);
 
-       pipe_ctx->mi->funcs->disable_request(pipe_ctx->mi);
+       if (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
+               REG_WAIT(OTG_GLOBAL_SYNC_STATUS[tg->inst],
+                               VUPDATE_NO_LOCK_EVENT_OCCURRED, 1, 20000, 200000);
 
-       wait_no_outstanding_request(dc->ctx, pipe_ctx->pipe_idx);
+       plane_atomic_disable(dc, fe_idx);
 
-       wait_mpcc_idle(mpc, pipe_ctx->pipe_idx);
+       dm_logger_write(dc->ctx->logger, LOG_DC,
+                                       "Reset front end %d\n",
+                                       fe_idx);
+}
 
-       disable_clocks(dc->ctx, pipe_ctx->pipe_idx);
+static void dcn10_power_down_fe(struct core_dc *dc, int fe_idx)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       struct transform *xfm = dc->res_pool->transforms[fe_idx];
 
-       pipe_ctx->xfm->funcs->transform_reset(pipe_ctx->xfm);
+       reset_front_end(dc, fe_idx);
 
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 1);
+       dpp_pg_control(hws, fe_idx, false);
+       hubp_pg_control(hws, fe_idx, false);
+       xfm->funcs->transform_reset(xfm);
+       REG_SET(DC_IP_REQUEST_CNTL, 0,
+                       IP_REQUEST_EN, 0);
        dm_logger_write(dc->ctx->logger, LOG_DC,
-                                       "Reset front end for pipe %d\n",
-                                       pipe_ctx->pipe_idx);
+                       "Power gated front end %d\n", fe_idx);
 
-       pipe_ctx->surface = NULL;
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
 }
 
-static void reset_hw_ctx(struct core_dc *dc,
-               struct validate_context *context,
-               void (*reset)(struct core_dc *dc,
-                               struct pipe_ctx *pipe_ctx,
-                               struct validate_context *context))
+static void reset_hw_ctx_wrap(
+               struct core_dc *dc,
+               struct validate_context *context)
 {
        int i;
 
+       /* Reset Front End*/
+       /* Lock*/
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *cur_pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[i];
+               struct timing_generator *tg = cur_pipe_ctx->tg;
+
+               if (cur_pipe_ctx->stream)
+                       tg->funcs->lock(tg);
+       }
+       /* Disconnect*/
        for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
                struct pipe_ctx *pipe_ctx_old =
                        &dc->current_context->res_ctx.pipe_ctx[i];
                struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
 
-               if (!pipe_ctx_old->stream)
+               if (!pipe_ctx->stream ||
+                               !pipe_ctx->plane_state ||
+                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+
+                       plane_atomic_disconnect(dc, i);
+               }
+       }
+       /* Unlock*/
+       for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+               struct pipe_ctx *cur_pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[i];
+               struct timing_generator *tg = cur_pipe_ctx->tg;
+
+               if (cur_pipe_ctx->stream)
+                       tg->funcs->unlock(tg);
+       }
+
+       /* Disable and Powerdown*/
+       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
+               struct pipe_ctx *pipe_ctx_old =
+                       &dc->current_context->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->stream && pipe_ctx->plane_state
+                               && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
                        continue;
 
-               if (!pipe_ctx->stream ||
-                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
-                       reset(dc, pipe_ctx_old, dc->current_context);
+               plane_atomic_disable(dc, i);
+
+               if (!pipe_ctx->stream || !pipe_ctx->plane_state)
+                       plane_atomic_power_down(dc, i);
        }
-}
 
-static void reset_hw_ctx_wrap(
-               struct core_dc *dc,
-               struct validate_context *context)
-{
-       /* Reset Front End*/
-       reset_hw_ctx(dc, context, reset_front_end_for_pipe);
        /* Reset Back End*/
-       reset_hw_ctx(dc, context, reset_back_end_for_pipe);
+       for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
+               struct pipe_ctx *pipe_ctx_old =
+                       &dc->current_context->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
 
-       memcpy(context->res_ctx.mpc_tree,
-                       dc->current_context->res_ctx.mpc_tree,
-                       sizeof(struct mpc_tree_cfg) * dc->res_pool->pipe_count);
+               if (!pipe_ctx_old->stream)
+                       continue;
+
+               if (!pipe_ctx->stream ||
+                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
+                       reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_context);
+       }
 }
 
-static bool patch_address_for_sbs_tb_stereo(struct pipe_ctx *pipe_ctx,
-                                                                                       PHYSICAL_ADDRESS_LOC *addr)
+static bool patch_address_for_sbs_tb_stereo(
+               struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
 {
-       struct core_surface *surface = pipe_ctx->surface;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
        bool sec_split = pipe_ctx->top_pipe &&
-                       pipe_ctx->top_pipe->surface == pipe_ctx->surface;
-       if (sec_split && surface->public.address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
-               (pipe_ctx->stream->public.timing.timing_3d_format ==
+                       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->public.timing.timing_3d_format ==
+                pipe_ctx->stream->timing.timing_3d_format ==
                 TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
-               *addr = surface->public.address.grph_stereo.left_addr;
-               surface->public.address.grph_stereo.left_addr =\
-               surface->public.address.grph_stereo.right_addr;
+               *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;
+               }
        }
        return false;
 }
@@ -924,38 +1065,41 @@ static void update_plane_addr(const struct core_dc *dc, struct pipe_ctx *pipe_ct
 {
        bool addr_patched = false;
        PHYSICAL_ADDRESS_LOC addr;
-       struct core_surface *surface = pipe_ctx->surface;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 
-       if (surface == NULL)
+       if (plane_state == NULL)
                return;
        addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
        pipe_ctx->mi->funcs->mem_input_program_surface_flip_and_addr(
                        pipe_ctx->mi,
-                       &surface->public.address,
-                       surface->public.flip_immediate);
-       surface->status.requested_address = surface->public.address;
+                       &plane_state->address,
+                       plane_state->flip_immediate);
+       plane_state->status.requested_address = plane_state->address;
        if (addr_patched)
-               pipe_ctx->surface->public.address.grph_stereo.left_addr = addr;
+               pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
 }
 
 static bool dcn10_set_input_transfer_func(
-       struct pipe_ctx *pipe_ctx,
-       const struct core_surface *surface)
+       struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
 {
        struct input_pixel_processor *ipp = pipe_ctx->ipp;
-       const struct core_transfer_func *tf = NULL;
+       const struct dc_transfer_func *tf = NULL;
        bool result = true;
 
        if (ipp == NULL)
                return false;
 
-       if (surface->public.in_transfer_func)
-               tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func);
+       if (plane_state->in_transfer_func)
+               tf = plane_state->in_transfer_func;
+
+       if (plane_state->gamma_correction && dce_use_lut(plane_state))
+               ipp->funcs->ipp_program_input_lut(ipp,
+                               plane_state->gamma_correction);
 
        if (tf == NULL)
                ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
-       else if (tf->public.type == TF_TYPE_PREDEFINED) {
-               switch (tf->public.tf) {
+       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);
@@ -975,7 +1119,7 @@ static bool dcn10_set_input_transfer_func(
                        result = false;
                        break;
                }
-       } else if (tf->public.type == TF_TYPE_BYPASS) {
+       } else if (tf->type == TF_TYPE_BYPASS) {
                ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
        } else {
                /*TF_TYPE_DISTRIBUTED_POINTS*/
@@ -1301,27 +1445,27 @@ static bool dcn10_translate_regamma_to_hw_format(const struct dc_transfer_func
 
 static bool dcn10_set_output_transfer_func(
        struct pipe_ctx *pipe_ctx,
-       const struct core_stream *stream)
+       const struct dc_stream_state *stream)
 {
-       struct output_pixel_processor *opp = pipe_ctx->opp;
+       struct transform *xfm = pipe_ctx->xfm;
 
-       if (opp == NULL)
+       if (xfm == NULL)
                return false;
 
-       opp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
+       xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
 
-       if (stream->public.out_transfer_func &&
-               stream->public.out_transfer_func->type ==
+       if (stream->out_transfer_func &&
+               stream->out_transfer_func->type ==
                        TF_TYPE_PREDEFINED &&
-               stream->public.out_transfer_func->tf ==
+               stream->out_transfer_func->tf ==
                        TRANSFER_FUNCTION_SRGB) {
-               opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB);
+               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
        } else if (dcn10_translate_regamma_to_hw_format(
-                               stream->public.out_transfer_func, &opp->regamma_params)) {
-                       opp->funcs->opp_program_regamma_pwl(opp, &opp->regamma_params);
-                       opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER);
+                               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 {
-               opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS);
+               xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
        }
 
        return true;
@@ -1332,18 +1476,24 @@ static void dcn10_pipe_control_lock(
        struct pipe_ctx *pipe,
        bool lock)
 {
-       struct dce_hwseq *hws = hws = dc->hwseq;
-
+       struct mem_input *mi = NULL;
+       mi = dc->res_pool->mis[pipe->pipe_idx];
        /* 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->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+
        if (lock)
-               dcn10_lock(pipe->tg);
+               pipe->tg->funcs->lock(pipe->tg);
        else
-               dcn10_unlock(pipe->tg);
+               pipe->tg->funcs->unlock(pipe->tg);
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
 }
 
 static bool wait_for_reset_trigger_to_occur(
@@ -1412,64 +1562,182 @@ static void dcn10_enable_timing_synchronization(
        DC_SYNC_INFO("Sync complete\n");
 }
 
+static void print_rq_dlg_ttu(
+               struct core_dc *core_dc,
+               struct pipe_ctx *pipe_ctx)
+{
+       dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+                       "\n============== DML TTU Output parameters [%d] ==============\n"
+                       "qos_level_low_wm: %d, \n"
+                       "qos_level_high_wm: %d, \n"
+                       "min_ttu_vblank: %d, \n"
+                       "qos_level_flip: %d, \n"
+                       "refcyc_per_req_delivery_l: %d, \n"
+                       "qos_level_fixed_l: %d, \n"
+                       "qos_ramp_disable_l: %d, \n"
+                       "refcyc_per_req_delivery_pre_l: %d, \n"
+                       "refcyc_per_req_delivery_c: %d, \n"
+                       "qos_level_fixed_c: %d, \n"
+                       "qos_ramp_disable_c: %d, \n"
+                       "refcyc_per_req_delivery_pre_c: %d\n"
+                       "=============================================================\n",
+                       pipe_ctx->pipe_idx,
+                       pipe_ctx->ttu_regs.qos_level_low_wm,
+                       pipe_ctx->ttu_regs.qos_level_high_wm,
+                       pipe_ctx->ttu_regs.min_ttu_vblank,
+                       pipe_ctx->ttu_regs.qos_level_flip,
+                       pipe_ctx->ttu_regs.refcyc_per_req_delivery_l,
+                       pipe_ctx->ttu_regs.qos_level_fixed_l,
+                       pipe_ctx->ttu_regs.qos_ramp_disable_l,
+                       pipe_ctx->ttu_regs.refcyc_per_req_delivery_pre_l,
+                       pipe_ctx->ttu_regs.refcyc_per_req_delivery_c,
+                       pipe_ctx->ttu_regs.qos_level_fixed_c,
+                       pipe_ctx->ttu_regs.qos_ramp_disable_c,
+                       pipe_ctx->ttu_regs.refcyc_per_req_delivery_pre_c
+                       );
+
+       dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+                       "\n============== DML DLG Output parameters [%d] ==============\n"
+                       "refcyc_h_blank_end: %d, \n"
+                       "dlg_vblank_end: %d, \n"
+                       "min_dst_y_next_start: %d, \n"
+                       "refcyc_per_htotal: %d, \n"
+                       "refcyc_x_after_scaler: %d, \n"
+                       "dst_y_after_scaler: %d, \n"
+                       "dst_y_prefetch: %d, \n"
+                       "dst_y_per_vm_vblank: %d, \n"
+                       "dst_y_per_row_vblank: %d, \n"
+                       "ref_freq_to_pix_freq: %d, \n"
+                       "vratio_prefetch: %d, \n"
+                       "refcyc_per_pte_group_vblank_l: %d, \n"
+                       "refcyc_per_meta_chunk_vblank_l: %d, \n"
+                       "dst_y_per_pte_row_nom_l: %d, \n"
+                       "refcyc_per_pte_group_nom_l: %d, \n",
+                       pipe_ctx->pipe_idx,
+                       pipe_ctx->dlg_regs.refcyc_h_blank_end,
+                       pipe_ctx->dlg_regs.dlg_vblank_end,
+                       pipe_ctx->dlg_regs.min_dst_y_next_start,
+                       pipe_ctx->dlg_regs.refcyc_per_htotal,
+                       pipe_ctx->dlg_regs.refcyc_x_after_scaler,
+                       pipe_ctx->dlg_regs.dst_y_after_scaler,
+                       pipe_ctx->dlg_regs.dst_y_prefetch,
+                       pipe_ctx->dlg_regs.dst_y_per_vm_vblank,
+                       pipe_ctx->dlg_regs.dst_y_per_row_vblank,
+                       pipe_ctx->dlg_regs.ref_freq_to_pix_freq,
+                       pipe_ctx->dlg_regs.vratio_prefetch,
+                       pipe_ctx->dlg_regs.refcyc_per_pte_group_vblank_l,
+                       pipe_ctx->dlg_regs.refcyc_per_meta_chunk_vblank_l,
+                       pipe_ctx->dlg_regs.dst_y_per_pte_row_nom_l,
+                       pipe_ctx->dlg_regs.refcyc_per_pte_group_nom_l
+                       );
+
+       dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+                       "\ndst_y_per_meta_row_nom_l: %d, \n"
+                       "refcyc_per_meta_chunk_nom_l: %d, \n"
+                       "refcyc_per_line_delivery_pre_l: %d, \n"
+                       "refcyc_per_line_delivery_l: %d, \n"
+                       "vratio_prefetch_c: %d, \n"
+                       "refcyc_per_pte_group_vblank_c: %d, \n"
+                       "refcyc_per_meta_chunk_vblank_c: %d, \n"
+                       "dst_y_per_pte_row_nom_c: %d, \n"
+                       "refcyc_per_pte_group_nom_c: %d, \n"
+                       "dst_y_per_meta_row_nom_c: %d, \n"
+                       "refcyc_per_meta_chunk_nom_c: %d, \n"
+                       "refcyc_per_line_delivery_pre_c: %d, \n"
+                       "refcyc_per_line_delivery_c: %d \n"
+                       "========================================================\n",
+                       pipe_ctx->dlg_regs.dst_y_per_meta_row_nom_l,
+                       pipe_ctx->dlg_regs.refcyc_per_meta_chunk_nom_l,
+                       pipe_ctx->dlg_regs.refcyc_per_line_delivery_pre_l,
+                       pipe_ctx->dlg_regs.refcyc_per_line_delivery_l,
+                       pipe_ctx->dlg_regs.vratio_prefetch_c,
+                       pipe_ctx->dlg_regs.refcyc_per_pte_group_vblank_c,
+                       pipe_ctx->dlg_regs.refcyc_per_meta_chunk_vblank_c,
+                       pipe_ctx->dlg_regs.dst_y_per_pte_row_nom_c,
+                       pipe_ctx->dlg_regs.refcyc_per_pte_group_nom_c,
+                       pipe_ctx->dlg_regs.dst_y_per_meta_row_nom_c,
+                       pipe_ctx->dlg_regs.refcyc_per_meta_chunk_nom_c,
+                       pipe_ctx->dlg_regs.refcyc_per_line_delivery_pre_c,
+                       pipe_ctx->dlg_regs.refcyc_per_line_delivery_c
+                       );
+
+       dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+                       "\n============== DML RQ Output parameters [%d] ==============\n"
+                       "chunk_size: %d \n"
+                       "min_chunk_size: %d \n"
+                       "meta_chunk_size: %d \n"
+                       "min_meta_chunk_size: %d \n"
+                       "dpte_group_size: %d \n"
+                       "mpte_group_size: %d \n"
+                       "swath_height: %d \n"
+                       "pte_row_height_linear: %d \n"
+                       "========================================================\n",
+                       pipe_ctx->pipe_idx,
+                       pipe_ctx->rq_regs.rq_regs_l.chunk_size,
+                       pipe_ctx->rq_regs.rq_regs_l.min_chunk_size,
+                       pipe_ctx->rq_regs.rq_regs_l.meta_chunk_size,
+                       pipe_ctx->rq_regs.rq_regs_l.min_meta_chunk_size,
+                       pipe_ctx->rq_regs.rq_regs_l.dpte_group_size,
+                       pipe_ctx->rq_regs.rq_regs_l.mpte_group_size,
+                       pipe_ctx->rq_regs.rq_regs_l.swath_height,
+                       pipe_ctx->rq_regs.rq_regs_l.pte_row_height_linear
+                       );
+}
+
 static void dcn10_power_on_fe(
        struct core_dc *dc,
        struct pipe_ctx *pipe_ctx,
        struct validate_context *context)
 {
-       struct dc_surface *dc_surface = &pipe_ctx->surface->public;
-
-       /* power up DCHUP and DPP from pseudo code pipe_move.c */
-        /*TODO: function: power_on_plane. If already power up, skip
-        */
-       {
-               power_on_plane(dc->ctx,
-                       pipe_ctx->pipe_idx, pipe_ctx->tg->inst);
-
-               /* enable DCFCLK current DCHUB */
-               enable_dcfclk(dc->ctx,
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       struct dce_hwseq *hws = dc->hwseq;
+
+       power_on_plane(dc->hwseq,
+               pipe_ctx->pipe_idx);
+
+       /* enable DCFCLK current DCHUB */
+       REG_UPDATE(HUBP_CLK_CNTL[pipe_ctx->pipe_idx],
+                       HUBP_CLOCK_ENABLE, 1);
+
+       /* make sure OPP_PIPE_CLOCK_EN = 1 */
+       REG_UPDATE(OPP_PIPE_CONTROL[pipe_ctx->tg->inst],
+                       OPP_PIPE_CLOCK_EN, 1);
+       /*TODO: REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, 0x1f);*/
+
+       if (plane_state) {
+               dm_logger_write(dc->ctx->logger, LOG_DC,
+                               "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,
-                               pipe_ctx->pix_clk_params.requested_pix_clk,
-                               context->bw.dcn.calc_clk.dppclk_div);
-               dc->current_context->bw.dcn.cur_clk.dppclk_div =
-                               context->bw.dcn.calc_clk.dppclk_div;
-               context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div;
-
-               if (dc_surface) {
-                       dm_logger_write(dc->ctx->logger, LOG_DC,
-                                       "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,
-                                       dc_surface,
-                                       dc_surface->address.grph.addr.high_part,
-                                       dc_surface->address.grph.addr.low_part,
-                                       dc_surface->src_rect.x,
-                                       dc_surface->src_rect.y,
-                                       dc_surface->src_rect.width,
-                                       dc_surface->src_rect.height,
-                                       dc_surface->dst_rect.x,
-                                       dc_surface->dst_rect.y,
-                                       dc_surface->dst_rect.width,
-                                       dc_surface->dst_rect.height);
-
-                       dm_logger_write(dc->ctx->logger, LOG_HW_SET_MODE,
-                                       "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->scl_data.viewport.width,
-                                       pipe_ctx->scl_data.viewport.height,
-                                       pipe_ctx->scl_data.viewport.x,
-                                       pipe_ctx->scl_data.viewport.y,
-                                       pipe_ctx->scl_data.recout.width,
-                                       pipe_ctx->scl_data.recout.height,
-                                       pipe_ctx->scl_data.recout.x,
-                                       pipe_ctx->scl_data.recout.y);
-               }
+                               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);
+
+               dm_logger_write(dc->ctx->logger, LOG_HW_SET_MODE,
+                               "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->scl_data.viewport.width,
+                               pipe_ctx->scl_data.viewport.height,
+                               pipe_ctx->scl_data.viewport.x,
+                               pipe_ctx->scl_data.viewport.y,
+                               pipe_ctx->scl_data.recout.width,
+                               pipe_ctx->scl_data.recout.height,
+                               pipe_ctx->scl_data.recout.x,
+                               pipe_ctx->scl_data.recout.y);
+               print_rq_dlg_ttu(dc, pipe_ctx);
        }
-
 }
 
 static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
@@ -1479,60 +1747,168 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
        adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
 
 
-       if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) {
+       if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
                adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
                adjust.temperature_matrix[0] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[0];
+                               gamut_remap_matrix.matrix[0];
                adjust.temperature_matrix[1] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[1];
+                               gamut_remap_matrix.matrix[1];
                adjust.temperature_matrix[2] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[2];
+                               gamut_remap_matrix.matrix[2];
                adjust.temperature_matrix[3] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[4];
+                               gamut_remap_matrix.matrix[4];
                adjust.temperature_matrix[4] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[5];
+                               gamut_remap_matrix.matrix[5];
                adjust.temperature_matrix[5] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[6];
+                               gamut_remap_matrix.matrix[6];
                adjust.temperature_matrix[6] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[8];
+                               gamut_remap_matrix.matrix[8];
                adjust.temperature_matrix[7] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[9];
+                               gamut_remap_matrix.matrix[9];
                adjust.temperature_matrix[8] =
                                pipe_ctx->stream->
-                               public.gamut_remap_matrix.matrix[10];
+                               gamut_remap_matrix.matrix[10];
        }
 
        pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust);
 }
 
+
+static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
+               enum dc_color_space colorspace,
+               uint16_t *matrix)
+{
+       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;
+
+                       //uint16_t matrix[12];
+                       for (i = 0; i < 12; i++)
+                               tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
+
+                       tbl_entry.color_space = color_space;
+                       //tbl_entry.regval = matrix;
+                       pipe_ctx->xfm->funcs->opp_set_csc_adjustment(pipe_ctx->xfm, &tbl_entry);
+       }
+}
+static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
+{
+       if (pipe_ctx->plane_state->visible)
+               return true;
+       if (pipe_ctx->bottom_pipe && is_lower_pipe_tree_visible(pipe_ctx->bottom_pipe))
+               return true;
+       return false;
+}
+
+static bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
+{
+       if (pipe_ctx->plane_state->visible)
+               return true;
+       if (pipe_ctx->top_pipe && is_upper_pipe_tree_visible(pipe_ctx->top_pipe))
+               return true;
+       return false;
+}
+
+static bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
+{
+       if (pipe_ctx->plane_state->visible)
+               return true;
+       if (pipe_ctx->top_pipe && is_upper_pipe_tree_visible(pipe_ctx->top_pipe))
+               return true;
+       if (pipe_ctx->bottom_pipe && is_lower_pipe_tree_visible(pipe_ctx->bottom_pipe))
+               return true;
+       return false;
+}
+
+static bool is_rgb_cspace(enum dc_color_space output_color_space)
+{
+       switch (output_color_space) {
+       case COLOR_SPACE_SRGB:
+       case COLOR_SPACE_SRGB_LIMITED:
+       case COLOR_SPACE_2020_RGB_FULLRANGE:
+       case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
+       case COLOR_SPACE_ADOBERGB:
+               return true;
+       case COLOR_SPACE_YCBCR601:
+       case COLOR_SPACE_YCBCR709:
+       case COLOR_SPACE_YCBCR601_LIMITED:
+       case COLOR_SPACE_YCBCR709_LIMITED:
+       case COLOR_SPACE_2020_YCBCR:
+               return false;
+       default:
+               /* Add a case to switch */
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+}
+
+static void dcn10_get_surface_visual_confirm_color(
+               const struct pipe_ctx *pipe_ctx,
+               struct tg_color *color)
+{
+       uint32_t color_value = MAX_TG_COLOR_VALUE;
+
+       switch (pipe_ctx->scl_data.format) {
+       case PIXEL_FORMAT_ARGB8888:
+               /* set boarder color to red */
+               color->color_r_cr = color_value;
+               break;
+
+       case PIXEL_FORMAT_ARGB2101010:
+               /* set boarder color to blue */
+               color->color_b_cb = color_value;
+               break;
+       case PIXEL_FORMAT_420BPP8:
+               /* set boarder color to green */
+               color->color_g_y = color_value;
+               break;
+       case PIXEL_FORMAT_420BPP10:
+               /* set boarder color to yellow */
+               color->color_g_y = color_value;
+               color->color_r_cr = color_value;
+               break;
+       case PIXEL_FORMAT_FP16:
+               /* set boarder color to white */
+               color->color_r_cr = color_value;
+               color->color_b_cb = color_value;
+               color->color_g_y = color_value;
+               break;
+       default:
+               break;
+       }
+}
+
 static void update_dchubp_dpp(
        struct core_dc *dc,
        struct pipe_ctx *pipe_ctx,
        struct validate_context *context)
 {
+       struct dce_hwseq *hws = dc->hwseq;
        struct mem_input *mi = pipe_ctx->mi;
        struct input_pixel_processor *ipp = pipe_ctx->ipp;
-       struct core_surface *surface = pipe_ctx->surface;
-       union plane_size size = surface->public.plane_size;
-       struct mpc_tree_cfg *tree_cfg = NULL;
+       struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+       union plane_size size = plane_state->plane_size;
        struct default_adjustment ocsc = {0};
-       enum dc_color_space color_space;
-       struct tg_color black_color = {0};
-       struct dcn10_mpc *mpc = TO_DCN10_MPC(dc->res_pool->mpc);
-
-       struct pipe_ctx *cur_pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
+       struct mpcc_cfg mpcc_cfg = {0};
+       struct pipe_ctx *top_pipe;
+       bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
 
+       /* TODO: proper fix once fpga works */
        /* depends on DML calculation, DPP clock value may change dynamically */
        enable_dppclk(
-               dc->ctx,
+               dc->hwseq,
                pipe_ctx->pipe_idx,
                pipe_ctx->pix_clk_params.requested_pix_clk,
                context->bw.dcn.calc_clk.dppclk_div);
@@ -1540,7 +1916,11 @@ static void update_dchubp_dpp(
                        context->bw.dcn.calc_clk.dppclk_div;
        context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div;
 
-       select_vtg(dc->ctx, pipe_ctx->pipe_idx, pipe_ctx->tg->inst);
+       /* 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
+        */
+       REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->tg->inst);
 
        update_plane_addr(dc, pipe_ctx);
 
@@ -1556,89 +1936,60 @@ static void update_dchubp_dpp(
        if (dc->public.config.gpu_vm_support)
                mi->funcs->mem_input_program_pte_vm(
                                pipe_ctx->mi,
-                               surface->public.format,
-                               &surface->public.tiling_info,
-                               surface->public.rotation);
+                               plane_state->format,
+                               &plane_state->tiling_info,
+                               plane_state->rotation);
 
        ipp->funcs->ipp_setup(ipp,
-                       surface->public.format,
+                       plane_state->format,
                        1,
                        IPP_OUTPUT_FORMAT_12_BIT_FIX);
 
-       /* mpc TODO un-hardcode object ids
-        * for pseudo code pipe_move.c :
-        * add_plane_mpcc(added_plane_inst, mpcc_inst, ...);
-        * Do we want to cache the tree_cfg?
-        */
-
-       /* TODO: build stream pipes group id. For now, use stream otg
-        * id as pipe group id
-        */
-       pipe_ctx->mpc_idx = pipe_ctx->tg->inst;
-       tree_cfg = &context->res_ctx.mpc_tree[pipe_ctx->mpc_idx];
-
-       /* enable when bottom pipe is present and
-        * it does not share a surface with current pipe
+       mpcc_cfg.mi = mi;
+       mpcc_cfg.opp = pipe_ctx->opp;
+       for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
+               mpcc_cfg.z_index++;
+       if (dc->public.debug.surface_visual_confirm)
+               dcn10_get_surface_visual_confirm_color(
+                               pipe_ctx, &mpcc_cfg.black_color);
+       else
+               color_space_to_black_color(
+                       dc, pipe_ctx->stream->output_color_space,
+                       &mpcc_cfg.black_color);
+       mpcc_cfg.per_pixel_alpha = per_pixel_alpha;
+       /* DCN1.0 has output CM before MPC which seems to screw with
+        * pre-multiplied alpha.
         */
-       if (pipe_ctx->bottom_pipe && surface != pipe_ctx->bottom_pipe->surface) {
-               pipe_ctx->scl_data.lb_params.alpha_en = 1;
-               tree_cfg->mode = TOP_BLND;
-       } else {
-               pipe_ctx->scl_data.lb_params.alpha_en = 0;
-               tree_cfg->mode = TOP_PASSTHRU;
-       }
-       if (!pipe_ctx->top_pipe && !cur_pipe_ctx->bottom_pipe) {
-               /* primary pipe, set mpc tree index 0 only */
-               tree_cfg->num_pipes = 1;
-               tree_cfg->opp_id = pipe_ctx->tg->inst;
-               tree_cfg->dpp[0] = pipe_ctx->pipe_idx;
-               tree_cfg->mpcc[0] = pipe_ctx->pipe_idx;
-       }
-
-       if (!cur_pipe_ctx->top_pipe && !pipe_ctx->top_pipe) {
-
-               if (!cur_pipe_ctx->bottom_pipe)
-                       dcn10_set_mpc_tree(mpc, tree_cfg);
-
-       } else if (!cur_pipe_ctx->top_pipe && pipe_ctx->top_pipe) {
-
-               dcn10_add_dpp(mpc, tree_cfg,
-                       pipe_ctx->pipe_idx, pipe_ctx->pipe_idx, 1);
-       } else {
-               /* nothing to be done here */
-               ASSERT(cur_pipe_ctx->top_pipe && pipe_ctx->top_pipe);
-       }
-
-
-       color_space = pipe_ctx->stream->public.output_color_space;
-       color_space_to_black_color(dc, color_space, &black_color);
-       dcn10_set_mpc_background_color(mpc, pipe_ctx->pipe_idx, &black_color);
+       mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
+                       pipe_ctx->stream->output_color_space)
+                                       && per_pixel_alpha;
+       dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
 
+       pipe_ctx->scl_data.lb_params.alpha_en = per_pixel_alpha;
        pipe_ctx->scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
        /* scaler configuration */
        pipe_ctx->xfm->funcs->transform_set_scaler(
                        pipe_ctx->xfm, &pipe_ctx->scl_data);
+       mi->funcs->mem_program_viewport(mi,
+                       &pipe_ctx->scl_data.viewport, &pipe_ctx->scl_data.viewport_c);
 
        /*gamut remap*/
        program_gamut_remap(pipe_ctx);
 
        /*TODO add adjustments parameters*/
-       ocsc.out_color_space = pipe_ctx->stream->public.output_color_space;
-       pipe_ctx->opp->funcs->opp_set_csc_default(pipe_ctx->opp, &ocsc);
+       ocsc.out_color_space = pipe_ctx->stream->output_color_space;
+       pipe_ctx->xfm->funcs->opp_set_csc_default(pipe_ctx->xfm, &ocsc);
 
        mi->funcs->mem_input_program_surface_config(
                mi,
-               surface->public.format,
-               &surface->public.tiling_info,
+               plane_state->format,
+               &plane_state->tiling_info,
                &size,
-               surface->public.rotation,
-               &surface->public.dcc,
-               surface->public.horizontal_mirror,
-               surface->public.visible);
-
-       /* Only support one plane for now. */
-       pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, !surface->public.visible);
+               plane_state->rotation,
+               &plane_state->dcc,
+               plane_state->horizontal_mirror);
 
+       mi->funcs->set_blank(mi, !is_pipe_tree_visible(pipe_ctx));
 }
 
 static void program_all_pipe_in_tree(
@@ -1648,19 +1999,21 @@ static void program_all_pipe_in_tree(
 {
        unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000;
 
-       if (pipe_ctx->surface->public.visible || pipe_ctx->top_pipe == NULL) {
-               dcn10_power_on_fe(dc, pipe_ctx, context);
+       if (pipe_ctx->top_pipe == NULL) {
 
                /* lock otg_master_update to process all pipes associated with
                 * this OTG. this is done only one time.
                 */
-               if (pipe_ctx->top_pipe == NULL) {
-                       /* watermark is for all pipes */
-                       pipe_ctx->mi->funcs->program_watermarks(
-                                       pipe_ctx->mi, &context->bw.dcn.watermarks, ref_clk_mhz);
-                       lock_otg_master_update(dc->ctx, pipe_ctx->tg->inst);
+               /* watermark is for all pipes */
+               program_watermarks(dc->hwseq, &context->bw.dcn.watermarks, ref_clk_mhz);
+
+               if (dc->public.debug.sanity_checks) {
+                       /* pstate stuck check after watermark update */
+                       verify_allow_pstate_change_high(dc->hwseq);
                }
 
+               pipe_ctx->tg->funcs->lock(pipe_ctx->tg);
+
                pipe_ctx->tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset;
                pipe_ctx->tg->dlg_otg_param.vstartup_start = pipe_ctx->pipe_dlg_param.vstartup_start;
                pipe_ctx->tg->dlg_otg_param.vupdate_offset = pipe_ctx->pipe_dlg_param.vupdate_offset;
@@ -1669,12 +2022,19 @@ static void program_all_pipe_in_tree(
 
                pipe_ctx->tg->funcs->program_global_sync(
                                pipe_ctx->tg);
+               pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, !is_pipe_tree_visible(pipe_ctx));
+       }
 
-
-
+       if (pipe_ctx->plane_state != NULL) {
+               dcn10_power_on_fe(dc, pipe_ctx, context);
                update_dchubp_dpp(dc, pipe_ctx, context);
        }
 
+       if (dc->public.debug.sanity_checks) {
+               /* pstate stuck check after each pipe is programmed */
+               verify_allow_pstate_change_high(dc->hwseq);
+       }
+
        if (pipe_ctx->bottom_pipe != NULL)
                program_all_pipe_in_tree(dc, pipe_ctx->bottom_pipe, context);
 }
@@ -1708,49 +2068,141 @@ static void dcn10_pplib_apply_display_requirements(
 
 static void dcn10_apply_ctx_for_surface(
                struct core_dc *dc,
-               struct core_surface *surface,
+               const struct dc_plane_state *plane_state,
                struct validate_context *context)
 {
-       int i;
+       int i, be_idx;
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
+
+       if (!plane_state)
+               return;
+
+       for (be_idx = 0; be_idx < dc->res_pool->pipe_count; be_idx++)
+               if (plane_state == context->res_ctx.pipe_ctx[be_idx].plane_state)
+                       break;
 
+       /* reset unused mpcc */
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *old_pipe_ctx =
+                               &dc->current_context->res_ctx.pipe_ctx[i];
 
-               if (!pipe_ctx->surface || pipe_ctx->surface != surface)
+               if (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state)
                        continue;
 
+               /*
+                * Powergate reused pipes that are not powergated
+                * fairly hacky right now, using opp_id as indicator
+                */
 
-               /* looking for top pipe to program */
-               if (!pipe_ctx->top_pipe) {
-                       memcpy(context->res_ctx.mpc_tree,
-                                       dc->current_context->res_ctx.mpc_tree,
-                                       sizeof(struct mpc_tree_cfg) * dc->res_pool->pipe_count);
+               if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
+                       if (pipe_ctx->mi->opp_id != 0xf && pipe_ctx->tg->inst == be_idx) {
+                               dcn10_power_down_fe(dc, pipe_ctx->pipe_idx);
+                               /*
+                                * power down fe will unlock when calling reset, need
+                                * to lock it back here. Messy, need rework.
+                                */
+                               pipe_ctx->tg->funcs->lock(pipe_ctx->tg);
+                       }
+               }
 
-                       program_all_pipe_in_tree(dc, pipe_ctx, context);
+
+               if ((!pipe_ctx->plane_state && old_pipe_ctx->plane_state)
+                               || (!pipe_ctx->stream && old_pipe_ctx->stream)) {
+                       if (old_pipe_ctx->tg->inst != be_idx)
+                               continue;
+
+                       if (!old_pipe_ctx->top_pipe) {
+                               ASSERT(0);
+                               continue;
+                       }
+
+                       /* reset mpc */
+                       dc->res_pool->mpc->funcs->remove(
+                                       dc->res_pool->mpc,
+                                       old_pipe_ctx->opp,
+                                       old_pipe_ctx->pipe_idx);
+                       old_pipe_ctx->opp->mpcc_disconnect_pending[old_pipe_ctx->mi->mpcc_id] = true;
+
+                       /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+                                       "[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n",
+                                       old_pipe_ctx->mpcc->inst);*/
+
+                       if (dc->public.debug.sanity_checks)
+                               verify_allow_pstate_change_high(dc->hwseq);
+
+                       old_pipe_ctx->top_pipe = NULL;
+                       old_pipe_ctx->bottom_pipe = NULL;
+                       old_pipe_ctx->plane_state = NULL;
+
+                       dm_logger_write(dc->ctx->logger, LOG_DC,
+                                       "Reset mpcc for pipe %d\n",
+                                       old_pipe_ctx->pipe_idx);
                }
        }
 
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
 
-               if (!pipe_ctx->surface || pipe_ctx->top_pipe)
+               if (pipe_ctx->plane_state != plane_state)
                        continue;
 
-               /* unlock master update lock */
-               unlock_otg_master(dc->ctx, pipe_ctx->tg->inst);
+               /* looking for top pipe to program */
+               if (!pipe_ctx->top_pipe)
+                       program_all_pipe_in_tree(dc, pipe_ctx, context);
        }
 
-       /* reset unused pipe */
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-               struct pipe_ctx *old_pipe_ctx =
-                               &dc->current_context->res_ctx.pipe_ctx[i];
-
-               if ((!pipe_ctx->surface && old_pipe_ctx->surface)
-                               || (!pipe_ctx->stream && old_pipe_ctx->stream))
-                       reset_front_end_for_pipe(dc,
-                                       old_pipe_ctx, dc->current_context);
-       }
+       dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+                       "\n============== Watermark parameters ==============\n"
+                       "a.urgent_ns: %d \n"
+                       "a.cstate_enter_plus_exit: %d \n"
+                       "a.cstate_exit: %d \n"
+                       "a.pstate_change: %d \n"
+                       "a.pte_meta_urgent: %d \n"
+                       "b.urgent_ns: %d \n"
+                       "b.cstate_enter_plus_exit: %d \n"
+                       "b.cstate_exit: %d \n"
+                       "b.pstate_change: %d \n"
+                       "b.pte_meta_urgent: %d \n",
+                       context->bw.dcn.watermarks.a.urgent_ns,
+                       context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns,
+                       context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns,
+                       context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns,
+                       context->bw.dcn.watermarks.a.pte_meta_urgent_ns,
+                       context->bw.dcn.watermarks.b.urgent_ns,
+                       context->bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns,
+                       context->bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns,
+                       context->bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns,
+                       context->bw.dcn.watermarks.b.pte_meta_urgent_ns
+                       );
+       dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+                       "\nc.urgent_ns: %d \n"
+                       "c.cstate_enter_plus_exit: %d \n"
+                       "c.cstate_exit: %d \n"
+                       "c.pstate_change: %d \n"
+                       "c.pte_meta_urgent: %d \n"
+                       "d.urgent_ns: %d \n"
+                       "d.cstate_enter_plus_exit: %d \n"
+                       "d.cstate_exit: %d \n"
+                       "d.pstate_change: %d \n"
+                       "d.pte_meta_urgent: %d \n"
+                       "========================================================\n",
+                       context->bw.dcn.watermarks.c.urgent_ns,
+                       context->bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns,
+                       context->bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns,
+                       context->bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns,
+                       context->bw.dcn.watermarks.c.pte_meta_urgent_ns,
+                       context->bw.dcn.watermarks.d.urgent_ns,
+                       context->bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns,
+                       context->bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns,
+                       context->bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns,
+                       context->bw.dcn.watermarks.d.pte_meta_urgent_ns
+                       );
+
+       if (dc->public.debug.sanity_checks)
+               verify_allow_pstate_change_high(dc->hwseq);
 }
 
 static void dcn10_set_bandwidth(
@@ -1810,23 +2262,8 @@ static void dcn10_set_bandwidth(
                                context->bw.dcn.calc_clk.min_active_dram_ccm_us;
        }
        dcn10_pplib_apply_display_requirements(dc, context);
-}
-
-static void dcn10_power_down_fe(struct core_dc *dc, struct pipe_ctx *pipe)
-{
-       struct dc_context *ctx = dc->ctx;
-       uint32_t inst_offset = 0;
-
-       HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
-                       IP_REQUEST_EN, 1);
-       dpp_pg_control(ctx, pipe->pipe_idx, false);
-       hubp_pg_control(ctx, pipe->pipe_idx, false);
-       HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
-                       IP_REQUEST_EN, 0);
 
-       if (pipe->xfm)
-               pipe->xfm->funcs->transform_reset(pipe->xfm);
-       memset(&pipe->scl_data, 0, sizeof(pipe->scl_data));
+       /* need to fix this function.  not doing the right thing here */
 }
 
 static void set_drr(struct pipe_ctx **pipe_ctx,
@@ -1883,13 +2320,196 @@ static void set_plane_config(
        program_gamut_remap(pipe_ctx);
 }
 
+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_INBAND_FA ||
+                       timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
+                       timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
+                       enum display_dongle_type dongle = \
+                                       stream->sink->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;
+}
+
+static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct core_dc *dc)
+{
+       struct crtc_stereo_flags flags = { 0 };
+       struct dc_stream_state *stream = pipe_ctx->stream;
+
+       dcn10_config_stereo_parameters(stream, &flags);
+
+       pipe_ctx->opp->funcs->opp_set_stereo_polarity(
+               pipe_ctx->opp,
+               flags.PROGRAM_STEREO == 1 ? true:false,
+               stream->timing.flags.RIGHT_EYE_3D_POLARITY == 1 ? true:false);
+
+       pipe_ctx->tg->funcs->program_stereo(
+               pipe_ctx->tg,
+               &stream->timing,
+               &flags);
+
+       return;
+}
+
+
+static void log_mpc_crc(struct core_dc *dc)
+{
+       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_hw_state(struct core_dc *dc)
+{
+       struct dc_context *dc_ctx = dc->ctx;
+       struct resource_pool *pool = dc->res_pool;
+       int i;
+
+       DTN_INFO_BEGIN();
+
+       DTN_INFO("HUBP:\t format \t addr_hi \t width \t height \t rotation \t"
+                       "mirror \t  sw_mode \t dcc_en \t blank_en \t ttu_dis \t"
+                       "min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
+
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct mem_input *mi = pool->mis[i];
+               struct dcn_hubp_state s;
+
+               dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s);
+
+               DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t %xh \t %xh \t "
+                               "%d \t %d \t %d \t %d \t"
+                               "%d \t %d \t %d \n",
+                               i,
+                               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.ttu_disable,
+                               s.min_ttu_vblank,
+                               s.qos_level_low_wm,
+                               s.qos_level_high_wm);
+       }
+       DTN_INFO("\n");
+
+       log_mpc_crc(dc);
+
+       DTN_INFO_END();
+}
+
+static void dcn10_wait_for_mpcc_disconnect(
+               struct core_dc *dc,
+               struct resource_pool *res_pool,
+               struct pipe_ctx *pipe_ctx)
+{
+       int i;
+
+       if (!pipe_ctx->opp)
+               return;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (pipe_ctx->opp->mpcc_disconnect_pending[i]) {
+                       res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
+                       pipe_ctx->opp->mpcc_disconnect_pending[i] = false;
+                       res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true);
+                       /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+                                       "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
+                                       i);*/
+               }
+       }
+
+}
+
+static bool dcn10_dummy_display_power_gating(
+       struct core_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->tg;
+
+       if (plane_state->ctx->dc->debug.sanity_checks) {
+               struct core_dc *dc = DC_TO_CORE(plane_state->ctx->dc);
+
+               verify_allow_pstate_change_high(dc->hwseq);
+       }
+
+       if (plane_state == NULL)
+               return;
+
+       plane_state->status.is_flip_pending =
+                       pipe_ctx->mi->funcs->mem_input_is_flip_pending(
+                                       pipe_ctx->mi);
+
+       /* DCN we read INUSE address in MI, do we still need this wa? */
+       if (plane_state->status.is_flip_pending &&
+                       !plane_state->visible) {
+               pipe_ctx->mi->current_address =
+                               pipe_ctx->mi->request_address;
+               BREAK_TO_DEBUGGER();
+       }
+
+       plane_state->status.current_address = pipe_ctx->mi->current_address;
+       if (pipe_ctx->mi->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->tg);
+       }
+}
+
 static const struct hw_sequencer_funcs dcn10_funcs = {
-       .init_hw = init_hw,
+       .program_gamut_remap = program_gamut_remap,
+       .program_csc_matrix = program_csc_matrix,
+       .init_hw = dcn10_init_hw,
        .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
        .apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
        .set_plane_config = set_plane_config,
        .update_plane_addr = update_plane_addr,
-       .update_pending_status = dce110_update_pending_status,
+       .update_dchub = dcn10_update_dchub,
+       .update_pending_status = dcn10_update_pending_status,
        .set_input_transfer_func = dcn10_set_input_transfer_func,
        .set_output_transfer_func = dcn10_set_output_transfer_func,
        .power_down = dce110_power_down,
@@ -1899,8 +2519,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .enable_stream = dce110_enable_stream,
        .disable_stream = dce110_disable_stream,
        .unblank_stream = dce110_unblank_stream,
-       .enable_display_pipe_clock_gating = NULL, /* TODOFPGA */
-       .enable_display_power_gating = dcn10_enable_display_power_gating,
+       .enable_display_power_gating = dcn10_dummy_display_power_gating,
        .power_down_front_end = dcn10_power_down_fe,
        .power_on_front_end = dcn10_power_on_fe,
        .pipe_control_lock = dcn10_pipe_control_lock,
@@ -1909,13 +2528,16 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .prog_pixclk_crtc_otg = dcn10_prog_pixclk_crtc_otg,
        .set_drr = set_drr,
        .get_position = get_position,
-       .set_static_screen_control = set_static_screen_control
+       .set_static_screen_control = set_static_screen_control,
+       .setup_stereo = dcn10_setup_stereo,
+       .set_avmute = dce110_set_avmute,
+       .log_hw_state = dcn10_log_hw_state,
+       .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect
 };
 
 
-bool dcn10_hw_sequencer_construct(struct core_dc *dc)
+void dcn10_hw_sequencer_construct(struct core_dc *dc)
 {
        dc->hwss = dcn10_funcs;
-       return true;
 }