#include "dmub/dmub_srv.h"
 
+#include "dcn30/dcn30_vpg.h"
+
 #include "i2caux_interface.h"
 #include "dce/dmub_hw_lock_mgr.h"
 
                enum surface_update_type update_type,
                struct dc_state *context)
 {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       struct vpg *vpg;
+#endif
        int j;
 
        // Stream updates
                                        stream_update->vrr_infopacket ||
                                        stream_update->vsc_infopacket ||
                                        stream_update->vsp_infopacket) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+                               vpg = pipe_ctx->stream_res.stream_enc->vpg;
+                               if (vpg && vpg->funcs->vpg_poweron)
+                                       vpg->funcs->vpg_poweron(vpg);
+#endif
                                resource_build_info_frame(pipe_ctx);
                                dc->hwss.update_info_frame(pipe_ctx);
                        }
 
 #include "inc/link_enc_cfg.h"
 #include "inc/link_dpcd.h"
 
+#include "dc/dcn30/dcn30_vpg.h"
+
 #define DC_LOGGER_INIT(logger)
 
 #define LINK_INFO(...) \
        struct link_encoder *link_enc;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
        enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
+       struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
 #endif
        DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 
 
                pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+               // Enable VPG before building infoframe
+               if (vpg && vpg->funcs->vpg_poweron)
+                       vpg->funcs->vpg_poweron(vpg);
+#endif
+
                resource_build_info_frame(pipe_ctx);
                dc->hwss.update_info_frame(pipe_ctx);
 
        struct dc  *dc = pipe_ctx->stream->ctx->dc;
        struct dc_stream_state *stream = pipe_ctx->stream;
        struct dc_link *link = stream->sink->link;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
+#endif
 
        if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
                        dc_is_virtual_signal(pipe_ctx->stream->signal))
                        pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
        }
 #endif
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       if (vpg && vpg->funcs->vpg_powerdown)
+               vpg->funcs->vpg_powerdown(vpg);
+#endif
 }
 
 void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
 
                bool cm: 1;
                bool mpc: 1;
                bool optc: 1;
+               bool vpg: 1;
+               bool afmt: 1;
        } bits;
        uint32_t u32All;
 };
 
 #include "hw_shared.h"
 #include "inc/link_dpcd.h"
 #include "dpcd_defs.h"
+#include "dcn30/dcn30_afmt.h"
 
 #define DC_LOGGER \
                enc1->base.ctx->logger
        struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
        uint32_t value = 0;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       if (enc->afmt && enc->afmt->funcs->afmt_powerdown)
+               enc->afmt->funcs->afmt_powerdown(enc->afmt);
+#endif
+
        /* Disable Audio packets */
        REG_UPDATE_5(DP_SEC_CNTL,
                        DP_SEC_ASP_ENABLE, 0,
 void enc1_se_hdmi_audio_disable(
        struct stream_encoder *enc)
 {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       if (enc->afmt && enc->afmt->funcs->afmt_powerdown)
+               enc->afmt->funcs->afmt_powerdown(enc->afmt);
+#endif
        enc1_se_enable_audio_clock(enc, false);
 }
 
 
        afmt3->base.ctx
 
 
-static void afmt3_setup_hdmi_audio(
+void afmt3_setup_hdmi_audio(
        struct afmt *afmt)
 {
        struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
 
+       if (afmt->funcs->afmt_poweron)
+               afmt->funcs->afmt_poweron(afmt);
+
        /* AFMT_AUDIO_PACKET_CONTROL */
        REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
 
        return cea_channels;
 }
 
-static void afmt3_se_audio_setup(
+void afmt3_se_audio_setup(
        struct afmt *afmt,
        unsigned int az_inst,
        struct audio_info *audio_info)
        REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);
 
        /* Disable forced mem power off */
-       REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
+       if (afmt->funcs->afmt_poweron == NULL)
+               REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
 }
 
-static void afmt3_audio_mute_control(
+void afmt3_audio_mute_control(
        struct afmt *afmt,
        bool mute)
 {
        struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
-
+       if (mute && afmt->funcs->afmt_powerdown)
+               afmt->funcs->afmt_powerdown(afmt);
+       if (!mute && afmt->funcs->afmt_poweron)
+               afmt->funcs->afmt_poweron(afmt);
        /* enable/disable transmission of audio packets */
        REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
 }
 
-static void afmt3_audio_info_immediate_update(
+void afmt3_audio_info_immediate_update(
        struct afmt *afmt)
 {
        struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
        REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
 }
 
-static void afmt3_setup_dp_audio(
+void afmt3_setup_dp_audio(
                struct afmt *afmt)
 {
        struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
 
+       if (afmt->funcs->afmt_poweron)
+               afmt->funcs->afmt_poweron(afmt);
+
        /* AFMT_AUDIO_PACKET_CONTROL */
        REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
 
 
 
        void (*setup_dp_audio)(
                struct afmt *afmt);
+
+       void (*afmt_poweron)(
+               struct afmt *afmt);
+
+       void (*afmt_powerdown)(
+               struct afmt *afmt);
 };
 
 struct afmt {
        const struct dcn30_afmt_mask *afmt_mask;
 };
 
+void afmt3_setup_hdmi_audio(
+       struct afmt *afmt);
+
+void afmt3_se_audio_setup(
+       struct afmt *afmt,
+       unsigned int az_inst,
+       struct audio_info *audio_info);
+
+void afmt3_audio_mute_control(
+       struct afmt *afmt,
+       bool mute);
+
+void afmt3_audio_info_immediate_update(
+       struct afmt *afmt);
+
+void afmt3_setup_dp_audio(
+               struct afmt *afmt);
+
 void afmt3_construct(struct dcn30_afmt *afmt3,
        struct dc_context *ctx,
        uint32_t inst,
 
 static void enc3_se_dp_audio_enable(
        struct stream_encoder *enc)
 {
+       if (enc->afmt->funcs->afmt_poweron)
+               enc->afmt->funcs->afmt_poweron(enc->afmt);
        enc1_se_enable_audio_clock(enc, true);
        enc3_se_setup_dp_audio(enc);
        enc1_se_enable_dp_audio(enc);
 
        vpg3->base.ctx
 
 
-static void vpg3_update_generic_info_packet(
+void vpg3_update_generic_info_packet(
        struct vpg *vpg,
        uint32_t packet_index,
        const struct dc_info_packet *info_packet)
 
                struct vpg *vpg,
                uint32_t packet_index,
                const struct dc_info_packet *info_packet);
+
+       void (*vpg_poweron)(
+               struct vpg *vpg);
+
+       void (*vpg_powerdown)(
+               struct vpg *vpg);
 };
 
 struct vpg {
        const struct dcn30_vpg_mask *vpg_mask;
 };
 
+void vpg3_update_generic_info_packet(
+       struct vpg *vpg,
+       uint32_t packet_index,
+       const struct dc_info_packet *info_packet);
+
 void vpg3_construct(struct dcn30_vpg *vpg3,
        struct dc_context *ctx,
        uint32_t inst,
 
 
 DCN31 = dcn31_resource.o dcn31_hubbub.o dcn31_hwseq.o dcn31_init.o dcn31_hubp.o \
        dcn31_dccg.o dcn31_optc.o dcn31_dio_link_encoder.o dcn31_panel_cntl.o \
-       dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o
+       dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o \
+       dcn31_afmt.o dcn31_vpg.o
 
 ifdef CONFIG_X86
 CFLAGS_$(AMDDALPATH)/dc/dcn31/dcn31_resource.o := -msse
 
--- /dev/null
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dc_bios_types.h"
+#include "hw_shared.h"
+#include "dcn30/dcn30_afmt.h"
+#include "dcn31_afmt.h"
+#include "reg_helper.h"
+#include "dc/dc.h"
+
+#define DC_LOGGER \
+               afmt31->base.ctx->logger
+
+#define REG(reg)\
+       (afmt31->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+       afmt31->afmt_shift->field_name, afmt31->afmt_mask->field_name
+
+
+#define CTX \
+       afmt31->base.ctx
+
+static struct afmt_funcs dcn31_afmt_funcs = {
+       .setup_hdmi_audio               = afmt3_setup_hdmi_audio,
+       .se_audio_setup                 = afmt3_se_audio_setup,
+       .audio_mute_control             = afmt3_audio_mute_control,
+       .audio_info_immediate_update    = afmt3_audio_info_immediate_update,
+       .setup_dp_audio                 = afmt3_setup_dp_audio,
+       .afmt_powerdown                 = afmt31_powerdown,
+       .afmt_poweron                   = afmt31_poweron
+};
+
+void afmt31_powerdown(struct afmt *afmt)
+{
+       struct dcn31_afmt *afmt31 = DCN31_AFMT_FROM_AFMT(afmt);
+
+       if (afmt->ctx->dc->debug.enable_mem_low_power.bits.afmt == false)
+               return;
+
+       REG_UPDATE_2(AFMT_MEM_PWR, AFMT_MEM_PWR_DIS, 0, AFMT_MEM_PWR_FORCE, 1);
+}
+
+void afmt31_poweron(struct afmt *afmt)
+{
+       struct dcn31_afmt *afmt31 = DCN31_AFMT_FROM_AFMT(afmt);
+
+       if (afmt->ctx->dc->debug.enable_mem_low_power.bits.afmt == false)
+               return;
+
+       REG_UPDATE_2(AFMT_MEM_PWR, AFMT_MEM_PWR_DIS, 1, AFMT_MEM_PWR_FORCE, 0);
+}
+
+void afmt31_construct(struct dcn31_afmt *afmt31,
+       struct dc_context *ctx,
+       uint32_t inst,
+       const struct dcn31_afmt_registers *afmt_regs,
+       const struct dcn31_afmt_shift *afmt_shift,
+       const struct dcn31_afmt_mask *afmt_mask)
+{
+       afmt31->base.ctx = ctx;
+
+       afmt31->base.inst = inst;
+       afmt31->base.funcs = &dcn31_afmt_funcs;
+
+       afmt31->regs = afmt_regs;
+       afmt31->afmt_shift = afmt_shift;
+       afmt31->afmt_mask = afmt_mask;
+}
 
--- /dev/null
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_DCN31_AFMT_H__
+#define __DAL_DCN31_AFMT_H__
+
+
+#define DCN31_AFMT_FROM_AFMT(afmt)\
+       container_of(afmt, struct dcn31_afmt, base)
+
+#define AFMT_DCN31_REG_LIST(id) \
+       SRI(AFMT_INFOFRAME_CONTROL0, AFMT, id), \
+       SRI(AFMT_VBI_PACKET_CONTROL, AFMT, id), \
+       SRI(AFMT_AUDIO_PACKET_CONTROL, AFMT, id), \
+       SRI(AFMT_AUDIO_PACKET_CONTROL2, AFMT, id), \
+       SRI(AFMT_AUDIO_SRC_CONTROL, AFMT, id), \
+       SRI(AFMT_60958_0, AFMT, id), \
+       SRI(AFMT_60958_1, AFMT, id), \
+       SRI(AFMT_60958_2, AFMT, id), \
+       SRI(AFMT_MEM_PWR, AFMT, id)
+
+struct dcn31_afmt_registers {
+       uint32_t AFMT_INFOFRAME_CONTROL0;
+       uint32_t AFMT_VBI_PACKET_CONTROL;
+       uint32_t AFMT_AUDIO_PACKET_CONTROL;
+       uint32_t AFMT_AUDIO_PACKET_CONTROL2;
+       uint32_t AFMT_AUDIO_SRC_CONTROL;
+       uint32_t AFMT_60958_0;
+       uint32_t AFMT_60958_1;
+       uint32_t AFMT_60958_2;
+       uint32_t AFMT_MEM_PWR;
+};
+
+#define DCN31_AFMT_MASK_SH_LIST(mask_sh)\
+       SE_SF(AFMT0_AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, mask_sh),\
+       SE_SF(AFMT0_AFMT_AUDIO_SRC_CONTROL, AFMT_AUDIO_SRC_SELECT, mask_sh),\
+       SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, mask_sh),\
+       SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, mask_sh),\
+       SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_LAYOUT_OVRD, mask_sh),\
+       SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_60958_OSF_OVRD, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_0, AFMT_60958_CS_CHANNEL_NUMBER_L, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_2, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_3, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_4, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_5, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_6, mask_sh),\
+       SE_SF(AFMT0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_7, mask_sh),\
+       SE_SF(AFMT0_AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, mask_sh),\
+       SE_SF(AFMT0_AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, mask_sh),\
+       SE_SF(AFMT0_AFMT_MEM_PWR, AFMT_MEM_PWR_DIS, mask_sh),\
+       SE_SF(AFMT0_AFMT_MEM_PWR, AFMT_MEM_PWR_STATE, mask_sh)
+
+#define AFMT_DCN31_REG_FIELD_LIST(type) \
+               type AFMT_AUDIO_INFO_UPDATE;\
+               type AFMT_AUDIO_SRC_SELECT;\
+               type AFMT_AUDIO_CHANNEL_ENABLE;\
+               type AFMT_60958_CS_UPDATE;\
+               type AFMT_AUDIO_LAYOUT_OVRD;\
+               type AFMT_60958_OSF_OVRD;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_L;\
+               type AFMT_60958_CS_CLOCK_ACCURACY;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_R;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_2;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_3;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_4;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_5;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_6;\
+               type AFMT_60958_CS_CHANNEL_NUMBER_7;\
+               type AFMT_AUDIO_SAMPLE_SEND;\
+               type AFMT_MEM_PWR_FORCE;\
+               type AFMT_MEM_PWR_DIS;\
+               type AFMT_MEM_PWR_STATE
+
+struct dcn31_afmt_shift {
+       AFMT_DCN31_REG_FIELD_LIST(uint8_t);
+};
+
+struct dcn31_afmt_mask {
+       AFMT_DCN31_REG_FIELD_LIST(uint32_t);
+};
+
+struct dcn31_afmt {
+       struct afmt base;
+       const struct dcn31_afmt_registers *regs;
+       const struct dcn31_afmt_shift *afmt_shift;
+       const struct dcn31_afmt_mask *afmt_mask;
+};
+
+void afmt31_poweron(
+               struct afmt *afmt);
+
+void afmt31_powerdown(
+               struct afmt *afmt);
+
+void afmt31_construct(struct dcn31_afmt *afmt31,
+       struct dc_context *ctx,
+       uint32_t inst,
+       const struct dcn31_afmt_registers *afmt_regs,
+       const struct dcn31_afmt_shift *afmt_shift,
+       const struct dcn31_afmt_mask *afmt_mask);
+
+#endif
 
 #include "dcn31/dcn31_hpo_dp_link_encoder.h"
 #include "dcn31/dcn31_apg.h"
 #include "dcn31/dcn31_dio_link_encoder.h"
+#include "dcn31/dcn31_vpg.h"
+#include "dcn31/dcn31_afmt.h"
 #include "dce/dce_clock_source.h"
 #include "dce/dce_audio.h"
 #include "dce/dce_hwseq.h"
 
 #define vpg_regs(id)\
 [id] = {\
-       VPG_DCN3_REG_LIST(id)\
+       VPG_DCN31_REG_LIST(id)\
 }
 
-static const struct dcn30_vpg_registers vpg_regs[] = {
+static const struct dcn31_vpg_registers vpg_regs[] = {
        vpg_regs(0),
        vpg_regs(1),
        vpg_regs(2),
        vpg_regs(9),
 };
 
-static const struct dcn30_vpg_shift vpg_shift = {
-       DCN3_VPG_MASK_SH_LIST(__SHIFT)
+static const struct dcn31_vpg_shift vpg_shift = {
+       DCN31_VPG_MASK_SH_LIST(__SHIFT)
 };
 
-static const struct dcn30_vpg_mask vpg_mask = {
-       DCN3_VPG_MASK_SH_LIST(_MASK)
+static const struct dcn31_vpg_mask vpg_mask = {
+       DCN31_VPG_MASK_SH_LIST(_MASK)
 };
 
 #define afmt_regs(id)\
 [id] = {\
-       AFMT_DCN3_REG_LIST(id)\
+       AFMT_DCN31_REG_LIST(id)\
 }
 
-static const struct dcn30_afmt_registers afmt_regs[] = {
+static const struct dcn31_afmt_registers afmt_regs[] = {
        afmt_regs(0),
        afmt_regs(1),
        afmt_regs(2),
        afmt_regs(5)
 };
 
-static const struct dcn30_afmt_shift afmt_shift = {
-       DCN3_AFMT_MASK_SH_LIST(__SHIFT)
+static const struct dcn31_afmt_shift afmt_shift = {
+       DCN31_AFMT_MASK_SH_LIST(__SHIFT)
 };
 
-static const struct dcn30_afmt_mask afmt_mask = {
-       DCN3_AFMT_MASK_SH_LIST(_MASK)
+static const struct dcn31_afmt_mask afmt_mask = {
+       DCN31_AFMT_MASK_SH_LIST(_MASK)
 };
 
 #define apg_regs(id)\
                        .cm = false,
                        .mpc = false,
                        .optc = false,
+                       .vpg = false,
+                       .afmt = false,
                }
        },
        .optimize_edp_link_rate = true,
        struct dc_context *ctx,
        uint32_t inst)
 {
-       struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
+       struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
 
-       if (!vpg3)
+       if (!vpg31)
                return NULL;
 
-       vpg3_construct(vpg3, ctx, inst,
+       vpg31_construct(vpg31, ctx, inst,
                        &vpg_regs[inst],
                        &vpg_shift,
                        &vpg_mask);
 
-       return &vpg3->base;
+       // Will re-enable hw block when we enable stream
+       // Check for enabled stream before powering down?
+       vpg31_powerdown(&vpg31->base);
+
+       return &vpg31->base;
 }
 
 static struct afmt *dcn31_afmt_create(
        struct dc_context *ctx,
        uint32_t inst)
 {
-       struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
+       struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL);
 
-       if (!afmt3)
+       if (!afmt31)
                return NULL;
 
-       afmt3_construct(afmt3, ctx, inst,
+       afmt31_construct(afmt31, ctx, inst,
                        &afmt_regs[inst],
                        &afmt_shift,
                        &afmt_mask);
 
-       return &afmt3->base;
+       // Light sleep by default, no need to power down here
+
+       return &afmt31->base;
 }
 
 static struct apg *dcn31_apg_create(
 
--- /dev/null
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dc_bios_types.h"
+#include "dcn30/dcn30_vpg.h"
+#include "dcn31_vpg.h"
+#include "reg_helper.h"
+#include "dc/dc.h"
+
+#define DC_LOGGER \
+               vpg31->base.ctx->logger
+
+#define REG(reg)\
+       (vpg31->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+       vpg31->vpg_shift->field_name, vpg31->vpg_mask->field_name
+
+
+#define CTX \
+       vpg31->base.ctx
+
+static struct vpg_funcs dcn31_vpg_funcs = {
+       .update_generic_info_packet     = vpg3_update_generic_info_packet,
+       .vpg_poweron = vpg31_poweron,
+       .vpg_powerdown = vpg31_powerdown,
+};
+
+void vpg31_powerdown(struct vpg *vpg)
+{
+       struct dcn31_vpg *vpg31 = DCN31_VPG_FROM_VPG(vpg);
+
+       if (vpg->ctx->dc->debug.enable_mem_low_power.bits.vpg == false)
+               return;
+
+       REG_UPDATE_2(VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, 0, VPG_GSP_LIGHT_SLEEP_FORCE, 1);
+}
+
+void vpg31_poweron(struct vpg *vpg)
+{
+       struct dcn31_vpg *vpg31 = DCN31_VPG_FROM_VPG(vpg);
+
+       if (vpg->ctx->dc->debug.enable_mem_low_power.bits.vpg == false)
+               return;
+
+       REG_UPDATE_2(VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, 1, VPG_GSP_LIGHT_SLEEP_FORCE, 0);
+}
+
+void vpg31_construct(struct dcn31_vpg *vpg31,
+       struct dc_context *ctx,
+       uint32_t inst,
+       const struct dcn31_vpg_registers *vpg_regs,
+       const struct dcn31_vpg_shift *vpg_shift,
+       const struct dcn31_vpg_mask *vpg_mask)
+{
+       vpg31->base.ctx = ctx;
+
+       vpg31->base.inst = inst;
+       vpg31->base.funcs = &dcn31_vpg_funcs;
+
+       vpg31->regs = vpg_regs;
+       vpg31->vpg_shift = vpg_shift;
+       vpg31->vpg_mask = vpg_mask;
+}
 
--- /dev/null
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_DCN31_VPG_H__
+#define __DAL_DCN31_VPG_H__
+
+
+#define DCN31_VPG_FROM_VPG(vpg)\
+       container_of(vpg, struct dcn31_vpg, base)
+
+#define VPG_DCN31_REG_LIST(id) \
+       SRI(VPG_GENERIC_STATUS, VPG, id), \
+       SRI(VPG_GENERIC_PACKET_ACCESS_CTRL, VPG, id), \
+       SRI(VPG_GENERIC_PACKET_DATA, VPG, id), \
+       SRI(VPG_GSP_FRAME_UPDATE_CTRL, VPG, id), \
+       SRI(VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG, id), \
+       SRI(VPG_MEM_PWR, VPG, id)
+
+struct dcn31_vpg_registers {
+       uint32_t VPG_GENERIC_STATUS;
+       uint32_t VPG_GENERIC_PACKET_ACCESS_CTRL;
+       uint32_t VPG_GENERIC_PACKET_DATA;
+       uint32_t VPG_GSP_FRAME_UPDATE_CTRL;
+       uint32_t VPG_GSP_IMMEDIATE_UPDATE_CTRL;
+       uint32_t VPG_MEM_PWR;
+};
+
+#define DCN31_VPG_MASK_SH_LIST(mask_sh)\
+       SE_SF(VPG0_VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_ACCESS_CTRL, VPG_GENERIC_DATA_INDEX, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE0, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE1, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE2, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE3, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC0_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC1_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC2_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC3_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC4_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC5_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC6_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC7_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC8_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC9_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC10_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC11_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC12_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC13_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC14_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC0_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC1_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC2_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC3_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC4_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC5_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC6_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC7_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC8_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC9_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC10_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC11_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC12_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC13_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC14_IMMEDIATE_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, mask_sh),\
+       SE_SF(VPG0_VPG_MEM_PWR, VPG_GSP_LIGHT_SLEEP_FORCE, mask_sh),\
+       SE_SF(VPG0_VPG_MEM_PWR, VPG_GSP_MEM_PWR_STATE, mask_sh)
+
+#define VPG_DCN31_REG_FIELD_LIST(type) \
+       type VPG_GENERIC_CONFLICT_OCCURED;\
+       type VPG_GENERIC_CONFLICT_CLR;\
+       type VPG_GENERIC_DATA_INDEX;\
+       type VPG_GENERIC_DATA_BYTE0;\
+       type VPG_GENERIC_DATA_BYTE1;\
+       type VPG_GENERIC_DATA_BYTE2;\
+       type VPG_GENERIC_DATA_BYTE3;\
+       type VPG_GENERIC0_FRAME_UPDATE;\
+       type VPG_GENERIC1_FRAME_UPDATE;\
+       type VPG_GENERIC2_FRAME_UPDATE;\
+       type VPG_GENERIC3_FRAME_UPDATE;\
+       type VPG_GENERIC4_FRAME_UPDATE;\
+       type VPG_GENERIC5_FRAME_UPDATE;\
+       type VPG_GENERIC6_FRAME_UPDATE;\
+       type VPG_GENERIC7_FRAME_UPDATE;\
+       type VPG_GENERIC8_FRAME_UPDATE;\
+       type VPG_GENERIC9_FRAME_UPDATE;\
+       type VPG_GENERIC10_FRAME_UPDATE;\
+       type VPG_GENERIC11_FRAME_UPDATE;\
+       type VPG_GENERIC12_FRAME_UPDATE;\
+       type VPG_GENERIC13_FRAME_UPDATE;\
+       type VPG_GENERIC14_FRAME_UPDATE;\
+       type VPG_GENERIC0_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC1_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC2_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC3_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC4_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC5_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC6_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC7_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC8_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC9_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC10_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC11_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC12_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC13_IMMEDIATE_UPDATE;\
+       type VPG_GENERIC14_IMMEDIATE_UPDATE;\
+       type VPG_GSP_MEM_LIGHT_SLEEP_DIS;\
+       type VPG_GSP_LIGHT_SLEEP_FORCE;\
+       type VPG_GSP_MEM_PWR_STATE
+
+struct dcn31_vpg_shift {
+       VPG_DCN31_REG_FIELD_LIST(uint8_t);
+};
+
+struct dcn31_vpg_mask {
+       VPG_DCN31_REG_FIELD_LIST(uint32_t);
+};
+
+struct dcn31_vpg {
+       struct vpg base;
+       const struct dcn31_vpg_registers *regs;
+       const struct dcn31_vpg_shift *vpg_shift;
+       const struct dcn31_vpg_mask *vpg_mask;
+};
+
+void vpg31_poweron(
+               struct vpg *vpg);
+
+void vpg31_powerdown(
+               struct vpg *vpg);
+
+void vpg31_construct(struct dcn31_vpg *vpg31,
+       struct dc_context *ctx,
+       uint32_t inst,
+       const struct dcn31_vpg_registers *vpg_regs,
+       const struct dcn31_vpg_shift *vpg_shift,
+       const struct dcn31_vpg_mask *vpg_mask);
+
+#endif