uint32_t mc_addr_low,
                                        uint32_t mc_addr_hi,
                                        uint32_t size);
+       int (*set_power_limit)(void *handle, uint32_t n);
+       int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit);
 /* export to DC */
        u32 (*get_sclk)(void *handle, bool low);
        u32 (*get_mclk)(void *handle, bool low);
 
        return ret;
 }
 
+static int pp_set_power_limit(void *handle, uint32_t limit)
+{
+       struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
+
+       ret = pp_check(pp_handle);
+
+       if (ret)
+               return ret;
+
+       hwmgr = pp_handle->hwmgr;
+
+       if (hwmgr->hwmgr_func->set_power_limit == NULL) {
+               pr_info("%s was not implemented.\n", __func__);
+               return -EINVAL;
+       }
+
+       if (limit == 0)
+               limit = hwmgr->default_power_limit;
+
+       if (limit > hwmgr->default_power_limit)
+               return -EINVAL;
+
+       mutex_lock(&pp_handle->pp_lock);
+       hwmgr->hwmgr_func->set_power_limit(hwmgr, limit);
+       hwmgr->power_limit = limit;
+       mutex_unlock(&pp_handle->pp_lock);
+       return ret;
+}
+
+static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
+{
+       struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
+
+       ret = pp_check(pp_handle);
+
+       if (ret)
+               return ret;
+
+       if (limit == NULL)
+               return -EINVAL;
+
+       hwmgr = pp_handle->hwmgr;
+
+       mutex_lock(&pp_handle->pp_lock);
+
+       if (default_limit)
+               *limit = hwmgr->default_power_limit;
+       else
+               *limit = hwmgr->power_limit;
+
+       mutex_unlock(&pp_handle->pp_lock);
+
+       return ret;
+}
+
 static int pp_display_configuration_change(void *handle,
        const struct amd_pp_display_configuration *display_config)
 {
        .get_power_profile_mode = pp_get_power_profile_mode,
        .set_power_profile_mode = pp_set_power_profile_mode,
        .odn_edit_dpm_table = pp_odn_edit_dpm_table,
+       .set_power_limit = pp_set_power_limit,
+       .get_power_limit = pp_get_power_limit,
 /* export to DC */
        .get_sclk = pp_dpm_get_sclk,
        .get_mclk = pp_dpm_get_mclk,
 
        .get_max_high_clocks = smu7_get_max_high_clocks,
        .get_thermal_temperature_range = smu7_get_thermal_temperature_range,
        .odn_edit_dpm_table = smu7_odn_edit_dpm_table,
+       .set_power_limit = smu7_set_power_limit,
 };
 
 uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
 
 {
        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 
+       n = (n & 0xff) << 8;
+
        if (data->power_containment_features &
                        POWERCONTAINMENT_FEATURE_PkgPwrLimit)
                return smum_send_msg_to_smc_with_parameter(hwmgr,
                        PP_ASSERT_WITH_CODE((0 == smc_result),
                                        "Failed to enable PkgPwrTracking in SMC.", result = -1;);
                        if (0 == smc_result) {
-                               uint32_t default_limit =
-                                       (uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256);
+                               hwmgr->default_power_limit = hwmgr->power_limit =
+                                               cac_table->usMaximumPowerDeliveryLimit;
                                data->power_containment_features |=
                                                POWERCONTAINMENT_FEATURE_PkgPwrLimit;
 
-                               if (smu7_set_power_limit(hwmgr, default_limit))
+                               if (smu7_set_power_limit(hwmgr, hwmgr->power_limit))
                                        pr_err("Failed to set Default Power Limit in SMC!");
                        }
                }
 
        .start_thermal_controller = vega10_start_thermal_controller,
        .get_power_profile_mode = vega10_get_power_profile_mode,
        .set_power_profile_mode = vega10_set_power_profile_mode,
+       .set_power_limit = vega10_set_power_limit,
 };
 
 int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
 
        struct phm_ppt_v2_information *table_info =
                        (struct phm_ppt_v2_information *)(hwmgr->pptable);
        struct phm_tdp_table *tdp_table = table_info->tdp_table;
-       uint32_t default_pwr_limit =
-                       (uint32_t)(tdp_table->usMaximumPowerDeliveryLimit);
        int result = 0;
 
+       hwmgr->default_power_limit = hwmgr->power_limit =
+                       (uint32_t)(tdp_table->usMaximumPowerDeliveryLimit);
+
        if (PP_CAP(PHM_PlatformCaps_PowerContainment)) {
                if (data->smu_features[GNLD_PPT].supported)
                        PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
                                        "Attempt to enable PPT feature Failed!",
                                        data->smu_features[GNLD_TDC].supported = false);
 
-               result = vega10_set_power_limit(hwmgr, default_pwr_limit);
+               result = vega10_set_power_limit(hwmgr, hwmgr->power_limit);
                PP_ASSERT_WITH_CODE(!result,
                                "Failed to set Default Power Limit in SMC!",
                                return result);
 
        int (*odn_edit_dpm_table)(struct pp_hwmgr *hwmgr,
                                        enum PP_OD_DPM_TABLE_COMMAND type,
                                        long *input, uint32_t size);
+       int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n);
        int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr);
 };
 
        uint32_t pstate_sclk;
        uint32_t pstate_mclk;
        bool od_enabled;
+       uint32_t power_limit;
+       uint32_t default_power_limit;
 };
 
 struct cgs_irq_src_funcs {