drm/amd/powerplay: refine powerplay interface.
authorRex Zhu <Rex.Zhu@amd.com>
Wed, 28 Dec 2016 11:43:23 +0000 (19:43 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 27 Jan 2017 16:12:58 +0000 (11:12 -0500)
v2: add pp_check function to check pp_instance
   valid.

1. powerplay export two new interface to amdgpu,
   amd_powerplay_create/amd_powerplay_destroy.
2. create pp_instance/smumgr/hwmgr/eventmgr in
   early init, destroy them when lata_fini.
3. in sw_init, create and init asic private smumgr
   data, and free them when sw_fini.
4. in hw_init, create and init asic private hwmgr
   data, and free them when hw_fini.
5. export powerplay state: PP_DPM_DISABLED.
   when user disabled powerplay or hwmgr/eventmgr
   init failed, powerplay return this state to amdgpu.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
drivers/gpu/drm/amd/powerplay/inc/eventmgr.h
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
drivers/gpu/drm/amd/powerplay/inc/pp_instance.h
drivers/gpu/drm/amd/powerplay/inc/smumgr.h
drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c

index b1921c7da36b8a1484abf8050fa0bb43e9ba6f48..8856eccc37fad48959e031ea4aa0581910db26ec 100644 (file)
 #include "cik_dpm.h"
 #include "vi_dpm.h"
 
-static int amdgpu_powerplay_init(struct amdgpu_device *adev)
+static int amdgpu_create_pp_handle(struct amdgpu_device *adev)
 {
-       int ret = 0;
+       struct amd_pp_init pp_init;
        struct amd_powerplay *amd_pp;
+       int ret;
 
        amd_pp = &(adev->powerplay);
-
-       if (adev->pp_enabled) {
-               struct amd_pp_init *pp_init;
-
-               pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL);
-
-               if (pp_init == NULL)
-                       return -ENOMEM;
-
-               pp_init->chip_family = adev->family;
-               pp_init->chip_id = adev->asic_type;
-               pp_init->device = amdgpu_cgs_create_device(adev);
-               ret = amd_powerplay_init(pp_init, amd_pp);
-               kfree(pp_init);
-       } else {
-               amd_pp->pp_handle = (void *)adev;
-
-               switch (adev->asic_type) {
-#ifdef CONFIG_DRM_AMDGPU_SI
-               case CHIP_TAHITI:
-               case CHIP_PITCAIRN:
-               case CHIP_VERDE:
-               case CHIP_OLAND:
-               case CHIP_HAINAN:
-                       amd_pp->ip_funcs = &si_dpm_ip_funcs;
-               break;
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
-               case CHIP_BONAIRE:
-               case CHIP_HAWAII:
-                       amd_pp->ip_funcs = &ci_dpm_ip_funcs;
-                       break;
-               case CHIP_KABINI:
-               case CHIP_MULLINS:
-               case CHIP_KAVERI:
-                       amd_pp->ip_funcs = &kv_dpm_ip_funcs;
-                       break;
-#endif
-               default:
-                       ret = -EINVAL;
-                       break;
-               }
-       }
-       return ret;
+       pp_init.chip_family = adev->family;
+       pp_init.chip_id = adev->asic_type;
+       pp_init.pm_en = amdgpu_dpm != 0 ? true : false;
+       pp_init.feature_mask = amdgpu_pp_feature_mask;
+       pp_init.device = amdgpu_cgs_create_device(adev);
+       ret = amd_powerplay_create(&pp_init, &(amd_pp->pp_handle));
+       if (ret)
+               return -EINVAL;
+       return 0;
 }
 
 static int amdgpu_pp_early_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       struct amd_powerplay *amd_pp;
        int ret = 0;
 
+       amd_pp = &(adev->powerplay);
+       adev->pp_enabled = false;
+       amd_pp->pp_handle = (void *)adev;
+
        switch (adev->asic_type) {
        case CHIP_POLARIS11:
        case CHIP_POLARIS10:
@@ -101,25 +72,45 @@ static int amdgpu_pp_early_init(void *handle)
        case CHIP_CARRIZO:
        case CHIP_STONEY:
                adev->pp_enabled = true;
+               if (amdgpu_create_pp_handle(adev))
+                       return -EINVAL;
+               amd_pp->ip_funcs = &pp_ip_funcs;
+               amd_pp->pp_funcs = &pp_dpm_funcs;
                break;
        /* These chips don't have powerplay implemenations */
+#ifdef CONFIG_DRM_AMDGPU_SI
+       case CHIP_TAHITI:
+       case CHIP_PITCAIRN:
+       case CHIP_VERDE:
+       case CHIP_OLAND:
+       case CHIP_HAINAN:
+               amd_pp->ip_funcs = &si_dpm_ip_funcs;
+       break;
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
        case CHIP_BONAIRE:
        case CHIP_HAWAII:
+               amd_pp->ip_funcs = &ci_dpm_ip_funcs;
+               break;
        case CHIP_KABINI:
        case CHIP_MULLINS:
        case CHIP_KAVERI:
+               amd_pp->ip_funcs = &kv_dpm_ip_funcs;
+               break;
+#endif
        default:
-               adev->pp_enabled = false;
+               ret = -EINVAL;
                break;
        }
 
-       ret = amdgpu_powerplay_init(adev);
-       if (ret)
-               return ret;
-
        if (adev->powerplay.ip_funcs->early_init)
                ret = adev->powerplay.ip_funcs->early_init(
                                        adev->powerplay.pp_handle);
+
+       if (ret == PP_DPM_DISABLED) {
+               adev->pm.dpm_enabled = false;
+               return 0;
+       }
        return ret;
 }
 
@@ -179,6 +170,11 @@ static int amdgpu_pp_hw_init(void *handle)
                ret = adev->powerplay.ip_funcs->hw_init(
                                        adev->powerplay.pp_handle);
 
+       if (ret == PP_DPM_DISABLED) {
+               adev->pm.dpm_enabled = false;
+               return 0;
+       }
+
        if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev))
                adev->pm.dpm_enabled = true;
 
@@ -204,14 +200,14 @@ static void amdgpu_pp_late_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (adev->pp_enabled) {
-               amdgpu_pm_sysfs_fini(adev);
-               amd_powerplay_fini(adev->powerplay.pp_handle);
-       }
-
        if (adev->powerplay.ip_funcs->late_fini)
                adev->powerplay.ip_funcs->late_fini(
                          adev->powerplay.pp_handle);
+
+       if (adev->pp_enabled && adev->pm.dpm_enabled)
+               amdgpu_pm_sysfs_fini(adev);
+
+       amd_powerplay_destroy(adev->powerplay.pp_handle);
 }
 
 static int amdgpu_pp_suspend(void *handle)
index fbbac6ba0d1776f49f48d018001a67f9d1506b23..429f18b9932345ff31c9e8a3b8897a1761f2a5fa 100644 (file)
 #include "eventmanager.h"
 
 
-#define PP_CHECK(handle)                                               \
-       do {                                                            \
-               if ((handle) == NULL || (handle)->pp_valid != PP_VALID) \
-                       return -EINVAL;                                 \
-       } while (0)
-
-#define PP_CHECK_HW(hwmgr)                                             \
-       do {                                                            \
-               if ((hwmgr) == NULL || (hwmgr)->hwmgr_func == NULL)     \
-                       return 0;                                       \
-       } while (0)
-
-static int pp_early_init(void *handle)
+static inline int pp_check(struct pp_instance *handle)
 {
-       return 0;
-}
-
-static int pp_sw_init(void *handle)
-{
-       struct pp_instance *pp_handle;
-       struct pp_hwmgr  *hwmgr;
-       int ret = 0;
+       if (handle == NULL || handle->pp_valid != PP_VALID)
+               return -EINVAL;
 
-       if (handle == NULL)
+       if (handle->smu_mgr == NULL || handle->smu_mgr->smumgr_funcs == NULL)
                return -EINVAL;
 
-       pp_handle = (struct pp_instance *)handle;
-       hwmgr = pp_handle->hwmgr;
+       if (handle->pm_en == 0)
+               return PP_DPM_DISABLED;
 
-       PP_CHECK_HW(hwmgr);
+       if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL
+               || handle->eventmgr == NULL)
+               return PP_DPM_DISABLED;
 
-       if (hwmgr->pptable_func == NULL ||
-           hwmgr->pptable_func->pptable_init == NULL ||
-           hwmgr->hwmgr_func->backend_init == NULL)
-               return -EINVAL;
+       return 0;
+}
 
-       ret = hwmgr->pptable_func->pptable_init(hwmgr);
-       if (ret)
-               goto err;
+static int pp_early_init(void *handle)
+{
+       int ret;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
 
-       ret = hwmgr->hwmgr_func->backend_init(hwmgr);
+       ret = smum_early_init(pp_handle);
        if (ret)
-               goto err1;
+               return ret;
+
+       if ((pp_handle->pm_en == 0)
+               || cgs_is_virtualization_enabled(pp_handle->device))
+               return PP_DPM_DISABLED;
 
-       if (hwmgr->hwmgr_func->request_firmware) {
-               ret = hwmgr->hwmgr_func->request_firmware(hwmgr);
-               if (ret)
-                       goto err2;
+       ret = hwmgr_early_init(pp_handle);
+       if (ret) {
+               pp_handle->pm_en = 0;
+               return PP_DPM_DISABLED;
        }
 
-       pr_info("initialized.\n");
+       ret = eventmgr_early_init(pp_handle);
+       if (ret) {
+               kfree(pp_handle->hwmgr);
+               pp_handle->hwmgr = NULL;
+               pp_handle->pm_en = 0;
+               return PP_DPM_DISABLED;
+       }
 
        return 0;
-err2:
-       if (hwmgr->hwmgr_func->backend_fini)
-               hwmgr->hwmgr_func->backend_fini(hwmgr);
-err1:
-       if (hwmgr->pptable_func->pptable_fini)
-               hwmgr->pptable_func->pptable_fini(hwmgr);
-err:
-       pr_err("initialization failed\n");
-       return ret;
 }
 
-static int pp_sw_fini(void *handle)
+static int pp_sw_init(void *handle)
 {
-       struct pp_instance *pp_handle;
-       struct pp_hwmgr  *hwmgr;
+       struct pp_smumgr *smumgr;
        int ret = 0;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       pp_handle = (struct pp_instance *)handle;
-       hwmgr = pp_handle->hwmgr;
+       if (ret == 0 || ret == PP_DPM_DISABLED) {
+               smumgr = pp_handle->smu_mgr;
 
-       PP_CHECK_HW(hwmgr);
+               if (smumgr->smumgr_funcs->smu_init == NULL)
+                       return -EINVAL;
 
-       if (hwmgr->hwmgr_func->release_firmware)
-                ret = hwmgr->hwmgr_func->release_firmware(hwmgr);
+               ret = smumgr->smumgr_funcs->smu_init(smumgr);
 
-       if (hwmgr->hwmgr_func->backend_fini != NULL)
-               ret = hwmgr->hwmgr_func->backend_fini(hwmgr);
+               pr_info("amdgpu: powerplay sw initialized\n");
+       }
+       return ret;
+}
 
-       if (hwmgr->pptable_func->pptable_fini)
-               hwmgr->pptable_func->pptable_fini(hwmgr);
+static int pp_sw_fini(void *handle)
+{
+       struct pp_smumgr *smumgr;
+       int ret = 0;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+
+       ret = pp_check(pp_handle);
+       if (ret == 0 || ret == PP_DPM_DISABLED) {
+               smumgr = pp_handle->smu_mgr;
 
+               if (smumgr->smumgr_funcs->smu_fini == NULL)
+                       return -EINVAL;
+
+               ret = smumgr->smumgr_funcs->smu_fini(smumgr);
+       }
        return ret;
 }
 
 static int pp_hw_init(void *handle)
 {
-       struct pp_instance *pp_handle;
        struct pp_smumgr *smumgr;
        struct pp_eventmgr *eventmgr;
-       struct pp_hwmgr  *hwmgr;
        int ret = 0;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       pp_handle = (struct pp_instance *)handle;
-       smumgr = pp_handle->smu_mgr;
-       hwmgr = pp_handle->hwmgr;
-
-       if (smumgr == NULL || smumgr->smumgr_funcs == NULL ||
-               smumgr->smumgr_funcs->smu_init == NULL ||
-               smumgr->smumgr_funcs->start_smu == NULL)
-               return -EINVAL;
+       if (ret == 0 || ret == PP_DPM_DISABLED) {
+               smumgr = pp_handle->smu_mgr;
 
-       ret = smumgr->smumgr_funcs->smu_init(smumgr);
-       if (ret) {
-               pr_err("smc initialization failed\n");
-               return ret;
-       }
+               if (smumgr->smumgr_funcs->start_smu == NULL)
+                       return -EINVAL;
 
-       ret = smumgr->smumgr_funcs->start_smu(smumgr);
-       if (ret) {
-               pr_err("smc start failed\n");
-               smumgr->smumgr_funcs->smu_fini(smumgr);
-               return ret;
+               if(smumgr->smumgr_funcs->start_smu(smumgr)) {
+                       pr_err("smc start failed\n");
+                       smumgr->smumgr_funcs->smu_fini(smumgr);
+                       return -EINVAL;;
+               }
+               if (ret == PP_DPM_DISABLED)
+                       return PP_DPM_DISABLED;
        }
 
-       PP_CHECK_HW(hwmgr);
-
-       hw_init_power_state_table(hwmgr);
+       ret = hwmgr_hw_init(pp_handle);
+       if (ret)
+               goto err;
 
        eventmgr = pp_handle->eventmgr;
-       if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL)
-               return -EINVAL;
+       if (eventmgr->pp_eventmgr_init == NULL ||
+               eventmgr->pp_eventmgr_init(eventmgr))
+               goto err;
 
-       ret = eventmgr->pp_eventmgr_init(eventmgr);
        return 0;
+err:
+       pp_handle->pm_en = 0;
+       kfree(pp_handle->eventmgr);
+       kfree(pp_handle->hwmgr);
+       pp_handle->hwmgr = NULL;
+       pp_handle->eventmgr = NULL;
+       return PP_DPM_DISABLED;
 }
 
 static int pp_hw_fini(void *handle)
 {
-       struct pp_instance *pp_handle;
-       struct pp_smumgr *smumgr;
        struct pp_eventmgr *eventmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
-
-       pp_handle = (struct pp_instance *)handle;
-       eventmgr = pp_handle->eventmgr;
-
-       if (eventmgr != NULL && eventmgr->pp_eventmgr_fini != NULL)
-               eventmgr->pp_eventmgr_fini(eventmgr);
+       ret = pp_check(pp_handle);
 
-       smumgr = pp_handle->smu_mgr;
+       if (ret == 0) {
+               eventmgr = pp_handle->eventmgr;
 
-       if (smumgr != NULL && smumgr->smumgr_funcs != NULL &&
-               smumgr->smumgr_funcs->smu_fini != NULL)
-               smumgr->smumgr_funcs->smu_fini(smumgr);
+               if (eventmgr->pp_eventmgr_fini != NULL)
+                       eventmgr->pp_eventmgr_fini(eventmgr);
 
+               hwmgr_hw_fini(pp_handle);
+       }
        return 0;
 }
 
@@ -210,13 +200,15 @@ static int pp_sw_reset(void *handle)
 int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -230,13 +222,15 @@ static int pp_set_powergating_state(void *handle,
                                    enum amd_powergating_state state)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -250,37 +244,38 @@ static int pp_set_powergating_state(void *handle,
 
 static int pp_suspend(void *handle)
 {
-       struct pp_instance *pp_handle;
        struct pp_eventmgr *eventmgr;
        struct pem_event_data event_data = { {0} };
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
+
+       if (ret != 0)
+               return ret;
 
-       pp_handle = (struct pp_instance *)handle;
        eventmgr = pp_handle->eventmgr;
+       pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
 
-       if (eventmgr != NULL)
-               pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
        return 0;
 }
 
 static int pp_resume(void *handle)
 {
-       struct pp_instance *pp_handle;
        struct pp_eventmgr *eventmgr;
        struct pem_event_data event_data = { {0} };
        struct pp_smumgr *smumgr;
-       int ret;
+       int ret, ret1;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret1 = pp_check(pp_handle);
+
+       if (ret1 != 0 && ret1 != PP_DPM_DISABLED)
+               return ret1;
 
-       pp_handle = (struct pp_instance *)handle;
        smumgr = pp_handle->smu_mgr;
 
-       if (smumgr == NULL || smumgr->smumgr_funcs == NULL ||
-               smumgr->smumgr_funcs->start_smu == NULL)
+       if (smumgr->smumgr_funcs->start_smu == NULL)
                return -EINVAL;
 
        ret = smumgr->smumgr_funcs->start_smu(smumgr);
@@ -290,9 +285,12 @@ static int pp_resume(void *handle)
                return ret;
        }
 
+       if (ret1 == PP_DPM_DISABLED)
+               return ret1;
+
        eventmgr = pp_handle->eventmgr;
-       if (eventmgr != NULL)
-               pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
+
+       pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
 
        return 0;
 }
@@ -327,18 +325,17 @@ static int pp_dpm_fw_loading_complete(void *handle)
 static int pp_dpm_force_performance_level(void *handle,
                                        enum amd_dpm_forced_level level)
 {
-       struct pp_instance *pp_handle;
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       pp_handle = (struct pp_instance *)handle;
+       if (ret != 0)
+               return ret;
 
        hwmgr = pp_handle->hwmgr;
 
-       PP_CHECK_HW(hwmgr);
-
        if (hwmgr->hwmgr_func->force_dpm_level == NULL) {
                pr_info("%s was not implemented.\n", __func__);
                return 0;
@@ -353,27 +350,31 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level(
                                                                void *handle)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
-       return (((struct pp_instance *)handle)->hwmgr->dpm_level);
+       return hwmgr->dpm_level;
 }
 
 static int pp_dpm_get_sclk(void *handle, bool low)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_sclk == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -386,13 +387,15 @@ static int pp_dpm_get_sclk(void *handle, bool low)
 static int pp_dpm_get_mclk(void *handle, bool low)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_mclk == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -405,13 +408,15 @@ static int pp_dpm_get_mclk(void *handle, bool low)
 static int pp_dpm_powergate_vce(void *handle, bool gate)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->powergate_vce == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -424,13 +429,15 @@ static int pp_dpm_powergate_vce(void *handle, bool gate)
 static int pp_dpm_powergate_uvd(void *handle, bool gate)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -458,16 +465,13 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id,
                void *input, void *output)
 {
        int ret = 0;
-       struct pp_instance *pp_handle;
        struct pem_event_data data = { {0} };
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
 
-       pp_handle = (struct pp_instance *)handle;
+       ret = pp_check(pp_handle);
 
-       if (pp_handle == NULL)
-               return -EINVAL;
-
-       if (pp_handle->eventmgr == NULL)
-               return 0;
+       if (ret != 0)
+               return ret;
 
        switch (event_id) {
        case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE:
@@ -501,13 +505,17 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
 {
        struct pp_hwmgr *hwmgr;
        struct pp_power_state *state;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       if (hwmgr == NULL || hwmgr->current_ps == NULL)
+       hwmgr = pp_handle->hwmgr;
+
+       if (hwmgr->current_ps == NULL)
                return -EINVAL;
 
        state = hwmgr->current_ps;
@@ -530,13 +538,15 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
 static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -549,13 +559,15 @@ static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
 static int pp_dpm_get_fan_control_mode(void *handle)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -568,13 +580,15 @@ static int pp_dpm_get_fan_control_mode(void *handle)
 static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -587,13 +601,15 @@ static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
 static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -606,13 +622,15 @@ static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
 static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL)
                return -EINVAL;
@@ -623,13 +641,15 @@ static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
 static int pp_dpm_get_temperature(void *handle)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_temperature == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -644,13 +664,17 @@ static int pp_dpm_get_pp_num_states(void *handle,
 {
        struct pp_hwmgr *hwmgr;
        int i;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
+
+       hwmgr = pp_handle->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->ps == NULL)
+       if (hwmgr->ps == NULL)
                return -EINVAL;
 
        data->nums = hwmgr->num_ps;
@@ -682,13 +706,15 @@ static int pp_dpm_get_pp_num_states(void *handle,
 static int pp_dpm_get_pp_table(void *handle, char **table)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (!hwmgr->soft_pp_table)
                return -EINVAL;
@@ -701,13 +727,15 @@ static int pp_dpm_get_pp_table(void *handle, char **table)
 static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (!hwmgr->hardcode_pp_table) {
                hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table,
@@ -729,13 +757,15 @@ static int pp_dpm_force_clock_level(void *handle,
                enum pp_clock_type type, uint32_t mask)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->force_clock_level == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -749,13 +779,15 @@ static int pp_dpm_print_clock_levels(void *handle,
                enum pp_clock_type type, char *buf)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -767,13 +799,15 @@ static int pp_dpm_print_clock_levels(void *handle,
 static int pp_dpm_get_sclk_od(void *handle)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_sclk_od == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -786,13 +820,15 @@ static int pp_dpm_get_sclk_od(void *handle)
 static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->set_sclk_od == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -805,13 +841,15 @@ static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
 static int pp_dpm_get_mclk_od(void *handle)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->get_mclk_od == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -824,13 +862,15 @@ static int pp_dpm_get_mclk_od(void *handle)
 static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->set_mclk_od == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -843,13 +883,15 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
 static int pp_dpm_read_sensor(void *handle, int idx, int32_t *value)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (!handle)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        if (hwmgr->hwmgr_func->read_sensor == NULL) {
                pr_info("%s was not implemented.\n", __func__);
@@ -863,13 +905,18 @@ static struct amd_vce_state*
 pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
 {
        struct pp_hwmgr *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       if (handle) {
-               hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       ret = pp_check(pp_handle);
 
-               if (hwmgr && idx < hwmgr->num_vce_state_tables)
-                       return &hwmgr->vce_states[idx];
-       }
+       if (ret != 0)
+               return NULL;
+
+       hwmgr = pp_handle->hwmgr;
+
+       if (hwmgr && idx < hwmgr->num_vce_state_tables)
+               return &hwmgr->vce_states[idx];
 
        return NULL;
 }
@@ -904,89 +951,44 @@ const struct amd_powerplay_funcs pp_dpm_funcs = {
        .get_vce_clock_state = pp_dpm_get_vce_clock_state,
 };
 
-static int amd_pp_instance_init(struct amd_pp_init *pp_init,
-                               struct amd_powerplay *amd_pp)
+int amd_powerplay_create(struct amd_pp_init *pp_init,
+                               void **handle)
 {
-       int ret;
-       struct pp_instance *handle;
-
-       handle = kzalloc(sizeof(struct pp_instance), GFP_KERNEL);
-       if (handle == NULL)
-               return -ENOMEM;
-
-       handle->pp_valid = PP_VALID;
-
-       ret = smum_init(pp_init, handle);
-       if (ret)
-               goto fail_smum;
-
-
-       amd_pp->pp_handle = handle;
+       struct pp_instance *instance;
 
-       if ((amdgpu_dpm == 0)
-               || cgs_is_virtualization_enabled(pp_init->device))
-               return 0;
+       if (pp_init == NULL || handle == NULL)
+               return -EINVAL;
 
-       ret = hwmgr_init(pp_init, handle);
-       if (ret)
-               goto fail_hwmgr;
+       instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL);
+       if (instance == NULL)
+               return -ENOMEM;
 
-       ret = eventmgr_init(handle);
-       if (ret)
-               goto fail_eventmgr;
+       instance->pp_valid = PP_VALID;
+       instance->chip_family = pp_init->chip_family;
+       instance->chip_id = pp_init->chip_id;
+       instance->pm_en = pp_init->pm_en;
+       instance->feature_mask = pp_init->feature_mask;
+       instance->device = pp_init->device;
+       *handle = instance;
 
        return 0;
-
-fail_eventmgr:
-       hwmgr_fini(handle->hwmgr);
-fail_hwmgr:
-       smum_fini(handle->smu_mgr);
-fail_smum:
-       kfree(handle);
-       return ret;
 }
 
-static int amd_pp_instance_fini(void *handle)
+int amd_powerplay_destroy(void *handle)
 {
        struct pp_instance *instance = (struct pp_instance *)handle;
 
-       if (instance == NULL)
-               return -EINVAL;
-
-       if ((amdgpu_dpm != 0)
-               && !cgs_is_virtualization_enabled(instance->smu_mgr->device)) {
-               eventmgr_fini(instance->eventmgr);
-               hwmgr_fini(instance->hwmgr);
+       if (instance->pm_en) {
+               kfree(instance->eventmgr);
+               kfree(instance->hwmgr);
+               instance->hwmgr = NULL;
+               instance->eventmgr = NULL;
        }
 
-       smum_fini(instance->smu_mgr);
-       kfree(handle);
-       return 0;
-}
-
-int amd_powerplay_init(struct amd_pp_init *pp_init,
-                      struct amd_powerplay *amd_pp)
-{
-       int ret;
-
-       if (pp_init == NULL || amd_pp == NULL)
-               return -EINVAL;
-
-       ret = amd_pp_instance_init(pp_init, amd_pp);
-
-       if (ret)
-               return ret;
-
-       amd_pp->ip_funcs = &pp_ip_funcs;
-       amd_pp->pp_funcs = &pp_dpm_funcs;
-
-       return 0;
-}
-
-int amd_powerplay_fini(void *handle)
-{
-       amd_pp_instance_fini(handle);
-
+       kfree(instance->smu_mgr);
+       instance->smu_mgr = NULL;
+       kfree(instance);
+       instance = NULL;
        return 0;
 }
 
@@ -997,33 +999,25 @@ int amd_powerplay_reset(void *handle)
        struct pem_event_data event_data = { {0} };
        int ret;
 
-       if (instance == NULL)
-               return -EINVAL;
-
-       eventmgr = instance->eventmgr;
-       if (!eventmgr || !eventmgr->pp_eventmgr_fini)
-               return -EINVAL;
-
-       eventmgr->pp_eventmgr_fini(eventmgr);
+       if (cgs_is_virtualization_enabled(instance->smu_mgr->device))
+               return PP_DPM_DISABLED;
 
-       ret = pp_sw_fini(handle);
-       if (ret)
+       ret = pp_check(instance);
+       if (ret != 0)
                return ret;
 
-       kfree(instance->hwmgr->ps);
-
-       ret = pp_sw_init(handle);
+       ret = pp_hw_fini(handle);
        if (ret)
                return ret;
 
-       if ((amdgpu_dpm == 0)
-               || cgs_is_virtualization_enabled(instance->smu_mgr->device))
-               return 0;
+       ret = hwmgr_hw_init(instance);
+       if (ret)
+               return PP_DPM_DISABLED;
 
-       hw_init_power_state_table(instance->hwmgr);
+       eventmgr = instance->eventmgr;
 
-       if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL)
-               return -EINVAL;
+       if (eventmgr->pp_eventmgr_init == NULL)
+               return PP_DPM_DISABLED;
 
        ret = eventmgr->pp_eventmgr_init(eventmgr);
        if (ret)
@@ -1038,12 +1032,15 @@ int amd_powerplay_display_configuration_change(void *handle,
        const struct amd_pp_display_configuration *display_config)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       PP_CHECK((struct pp_instance *)handle);
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        phm_store_dal_configuration_data(hwmgr, display_config);
 
@@ -1054,15 +1051,18 @@ int amd_powerplay_get_display_power_level(void *handle,
                struct amd_pp_simple_clock_info *output)
 {
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       PP_CHECK((struct pp_instance *)handle);
+       ret = pp_check(pp_handle);
 
-       if (output == NULL)
-               return -EINVAL;
+       if (ret != 0)
+               return ret;
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       hwmgr = pp_handle->hwmgr;
 
-       PP_CHECK_HW(hwmgr);
+       if (output == NULL)
+               return -EINVAL;
 
        return phm_get_dal_power_level(hwmgr, output);
 }
@@ -1070,18 +1070,18 @@ int amd_powerplay_get_display_power_level(void *handle,
 int amd_powerplay_get_current_clocks(void *handle,
                struct amd_pp_clock_info *clocks)
 {
-       struct pp_hwmgr  *hwmgr;
        struct amd_pp_simple_clock_info simple_clocks;
        struct pp_clock_info hw_clocks;
+       struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       PP_CHECK((struct pp_instance *)handle);
-
-       if (clocks == NULL)
-               return -EINVAL;
+       ret = pp_check(pp_handle);
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+       if (ret != 0)
+               return ret;
 
-       PP_CHECK_HW(hwmgr);
+       hwmgr = pp_handle->hwmgr;
 
        phm_get_dal_power_level(hwmgr, &simple_clocks);
 
@@ -1117,18 +1117,20 @@ int amd_powerplay_get_current_clocks(void *handle,
 int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks)
 {
        int result = -1;
+       struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       struct pp_hwmgr *hwmgr;
+       ret = pp_check(pp_handle);
 
-       PP_CHECK((struct pp_instance *)handle);
+       if (ret != 0)
+               return ret;
+
+       hwmgr = pp_handle->hwmgr;
 
        if (clocks == NULL)
                return -EINVAL;
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
-
-       PP_CHECK_HW(hwmgr);
-
        result = phm_get_clock_by_type(hwmgr, type, clocks);
 
        return result;
@@ -1137,21 +1139,24 @@ int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, s
 int amd_powerplay_get_display_mode_validation_clocks(void *handle,
                struct amd_pp_simple_clock_info *clocks)
 {
-       int result = -1;
        struct pp_hwmgr  *hwmgr;
+       struct pp_instance *pp_handle = (struct pp_instance *)handle;
+       int ret = 0;
 
-       PP_CHECK((struct pp_instance *)handle);
+       ret = pp_check(pp_handle);
 
-       if (clocks == NULL)
-               return -EINVAL;
+       if (ret != 0)
+               return ret;
+
+       hwmgr = pp_handle->hwmgr;
 
-       hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       PP_CHECK_HW(hwmgr);
+       if (clocks == NULL)
+               return -EINVAL;
 
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState))
-               result = phm_get_max_high_clocks(hwmgr, clocks);
+               ret = phm_get_max_high_clocks(hwmgr, clocks);
 
-       return result;
+       return ret;
 }
 
index fb88e4e5d625815ab213b1011392bce0ef96eae6..781e53dcf1280ab1a70fd2d21402336ec8d69a8c 100644 (file)
@@ -60,9 +60,8 @@ static void pem_fini(struct pp_eventmgr *eventmgr)
        pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data);
 }
 
-int eventmgr_init(struct pp_instance *handle)
+int eventmgr_early_init(struct pp_instance *handle)
 {
-       int result = 0;
        struct pp_eventmgr *eventmgr;
 
        if (handle == NULL)
@@ -79,12 +78,6 @@ int eventmgr_init(struct pp_instance *handle)
        eventmgr->pp_eventmgr_init = pem_init;
        eventmgr->pp_eventmgr_fini = pem_fini;
 
-       return result;
-}
-
-int eventmgr_fini(struct pp_eventmgr *eventmgr)
-{
-       kfree(eventmgr);
        return 0;
 }
 
index bd4ca681e2605b0b7c3e380489aad8a5c58c5d02..6bc63f26623da90343c7203db7cb2be3bd003545 100644 (file)
@@ -50,11 +50,11 @@ uint8_t convert_to_vid(uint16_t vddc)
        return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25);
 }
 
-int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
+int hwmgr_early_init(struct pp_instance *handle)
 {
        struct pp_hwmgr *hwmgr;
 
-       if ((handle == NULL) || (pp_init == NULL))
+       if (handle == NULL)
                return -EINVAL;
 
        hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL);
@@ -63,9 +63,9 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
 
        handle->hwmgr = hwmgr;
        hwmgr->smumgr = handle->smu_mgr;
-       hwmgr->device = pp_init->device;
-       hwmgr->chip_family = pp_init->chip_family;
-       hwmgr->chip_id = pp_init->chip_id;
+       hwmgr->device = handle->device;
+       hwmgr->chip_family = handle->chip_family;
+       hwmgr->chip_id = handle->chip_id;
        hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
        hwmgr->power_source = PP_PowerSource_AC;
        hwmgr->pp_table_version = PP_TABLE_V1;
@@ -112,28 +112,7 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
        return 0;
 }
 
-int hwmgr_fini(struct pp_hwmgr *hwmgr)
-{
-       if (hwmgr == NULL || hwmgr->ps == NULL)
-               return -EINVAL;
-
-       /* do hwmgr finish*/
-       kfree(hwmgr->hardcode_pp_table);
-
-       kfree(hwmgr->backend);
-
-       kfree(hwmgr->start_thermal_controller.function_list);
-
-       kfree(hwmgr->set_temperature_range.function_list);
-
-       kfree(hwmgr->ps);
-       kfree(hwmgr->current_ps);
-       kfree(hwmgr->request_ps);
-       kfree(hwmgr);
-       return 0;
-}
-
-int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
+static int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
 {
        int result;
        unsigned int i;
@@ -157,12 +136,20 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
                return -ENOMEM;
 
        hwmgr->request_ps = kzalloc(size, GFP_KERNEL);
-       if (hwmgr->request_ps == NULL)
+       if (hwmgr->request_ps == NULL) {
+               kfree(hwmgr->ps);
+               hwmgr->ps = NULL;
                return -ENOMEM;
+       }
 
        hwmgr->current_ps = kzalloc(size, GFP_KERNEL);
-       if (hwmgr->current_ps == NULL)
+       if (hwmgr->current_ps == NULL) {
+               kfree(hwmgr->request_ps);
+               kfree(hwmgr->ps);
+               hwmgr->request_ps = NULL;
+               hwmgr->ps = NULL;
                return -ENOMEM;
+       }
 
        state = hwmgr->ps;
 
@@ -182,8 +169,75 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
                state = (struct pp_power_state *)((unsigned long)state + size);
        }
 
+       return 0;
+}
+
+static int hw_fini_power_state_table(struct pp_hwmgr *hwmgr)
+{
+       if (hwmgr == NULL)
+               return -EINVAL;
+
+       kfree(hwmgr->current_ps);
+       kfree(hwmgr->request_ps);
+       kfree(hwmgr->ps);
+       hwmgr->request_ps = NULL;
+       hwmgr->ps = NULL;
+       hwmgr->current_ps = NULL;
+       return 0;
+}
+
+int hwmgr_hw_init(struct pp_instance *handle)
+{
+       struct pp_hwmgr *hwmgr;
+       int ret = 0;
+
+       if (handle == NULL)
+               return -EINVAL;
+
+       hwmgr = handle->hwmgr;
+
+       if (hwmgr->pptable_func == NULL ||
+           hwmgr->pptable_func->pptable_init == NULL ||
+           hwmgr->hwmgr_func->backend_init == NULL)
+               return -EINVAL;
+
+       ret = hwmgr->pptable_func->pptable_init(hwmgr);
+       if (ret)
+               goto err;
+
+       ret = hwmgr->hwmgr_func->backend_init(hwmgr);
+       if (ret)
+               goto err1;
 
+       ret = hw_init_power_state_table(hwmgr);
+       if (ret)
+               goto err2;
        return 0;
+err2:
+       if (hwmgr->hwmgr_func->backend_fini)
+               hwmgr->hwmgr_func->backend_fini(hwmgr);
+err1:
+       if (hwmgr->pptable_func->pptable_fini)
+               hwmgr->pptable_func->pptable_fini(hwmgr);
+err:
+       pr_err("amdgpu: powerplay initialization failed\n");
+       return ret;
+}
+
+int hwmgr_hw_fini(struct pp_instance *handle)
+{
+       struct pp_hwmgr *hwmgr;
+
+       if (handle == NULL)
+               return -EINVAL;
+
+       hwmgr = handle->hwmgr;
+
+       if (hwmgr->hwmgr_func->backend_fini)
+               hwmgr->hwmgr_func->backend_fini(hwmgr);
+       if (hwmgr->pptable_func->pptable_fini)
+               hwmgr->pptable_func->pptable_fini(hwmgr);
+       return hw_fini_power_state_table(hwmgr);
 }
 
 
@@ -289,7 +343,7 @@ int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table)
 
        memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
        kfree(table);
-
+       table = NULL;
        return 0;
 }
 
index 6d52a397ff888fc6a27b9b616f3677eb2af26afe..6dd5f0e9ef87c6e55307d61ee1c8f9f787d9a205 100644 (file)
 #include "amd_shared.h"
 #include "cgs_common.h"
 
-extern int amdgpu_dpm;
+extern const struct amd_ip_funcs pp_ip_funcs;
+extern const struct amd_powerplay_funcs pp_dpm_funcs;
+
+#define PP_DPM_DISABLED 0xCCCC
 
 enum amd_pp_sensors {
        AMDGPU_PP_SENSOR_GFX_SCLK = 0,
@@ -139,6 +142,8 @@ struct amd_pp_init {
        struct cgs_device *device;
        uint32_t chip_family;
        uint32_t chip_id;
+       bool pm_en;
+       uint32_t feature_mask;
 };
 
 enum amd_pp_display_config_type{
@@ -364,10 +369,10 @@ struct amd_powerplay {
        const struct amd_powerplay_funcs *pp_funcs;
 };
 
-int amd_powerplay_init(struct amd_pp_init *pp_init,
-                      struct amd_powerplay *amd_pp);
+int amd_powerplay_create(struct amd_pp_init *pp_init,
+                               void **handle);
 
-int amd_powerplay_fini(void *handle);
+int amd_powerplay_destroy(void *handle);
 
 int amd_powerplay_reset(void *handle);
 
index d63ef83b2628a068a80eff01b1b6137499d8b166..7bd8a7e570808bd111a02e85c42581115c54c04f 100644 (file)
@@ -119,7 +119,6 @@ struct pp_eventmgr {
        void (*pp_eventmgr_fini)(struct pp_eventmgr *eventmgr);
 };
 
-int eventmgr_init(struct pp_instance *handle);
-int eventmgr_fini(struct pp_eventmgr *eventmgr);
+int eventmgr_early_init(struct pp_instance *handle);
 
 #endif /* _EVENTMGR_H_ */
index 3b7450ee7163a748e4dd9b42e9202bfa2d630a9b..0d93801f21ea1006e04b213075ab553e07413080 100644 (file)
@@ -653,19 +653,12 @@ struct pp_hwmgr {
        uint32_t feature_mask;
 };
 
-
-extern int hwmgr_init(struct amd_pp_init *pp_init,
-                     struct pp_instance *handle);
-
-extern int hwmgr_fini(struct pp_hwmgr *hwmgr);
-
-extern int hw_init_power_state_table(struct pp_hwmgr *hwmgr);
-
+extern int hwmgr_early_init(struct pp_instance *handle);
+extern int hwmgr_hw_init(struct pp_instance *handle);
+extern int hwmgr_hw_fini(struct pp_instance *handle);
 extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
                                uint32_t value, uint32_t mask);
 
-
-
 extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
                                uint32_t indirect_port,
                                uint32_t index,
index 4d8ed1f33de44648a6a7b388aab593236e065d27..ab8494fb5c6b1199e2557bc45490ea099b987dd5 100644 (file)
 
 struct pp_instance {
        uint32_t pp_valid;
+       uint32_t chip_family;
+       uint32_t chip_id;
+       bool pm_en;
+       uint32_t feature_mask;
+       void *device;
        struct pp_smumgr *smu_mgr;
        struct pp_hwmgr *hwmgr;
        struct pp_eventmgr *eventmgr;
index 2139072065cc7da6da4b5bf65fbba19c37b967ca..0e593729583587b1a52f3c50bb3ff7a1510a9c14 100644 (file)
@@ -133,11 +133,7 @@ struct pp_smumgr {
        const struct pp_smumgr_func *smumgr_funcs;
 };
 
-
-extern int smum_init(struct amd_pp_init *pp_init,
-                    struct pp_instance *handle);
-
-extern int smum_fini(struct pp_smumgr *smumgr);
+extern int smum_early_init(struct pp_instance *handle);
 
 extern int smum_get_argument(struct pp_smumgr *smumgr);
 
index 45737cd3c0556bfe8b9259bf928377c5b008a862..d5244c16d2d5fb40e5dd7ddce3a6e7ceca19eec2 100644 (file)
@@ -41,20 +41,20 @@ MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
 MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
 
-int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
+int smum_early_init(struct pp_instance *handle)
 {
        struct pp_smumgr *smumgr;
 
-       if ((handle == NULL) || (pp_init == NULL))
+       if (handle == NULL)
                return -EINVAL;
 
        smumgr = kzalloc(sizeof(struct pp_smumgr), GFP_KERNEL);
        if (smumgr == NULL)
                return -ENOMEM;
 
-       smumgr->device = pp_init->device;
-       smumgr->chip_family = pp_init->chip_family;
-       smumgr->chip_id = pp_init->chip_id;
+       smumgr->device = handle->device;
+       smumgr->chip_family = handle->chip_family;
+       smumgr->chip_id = handle->chip_id;
        smumgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
        smumgr->reload_fw = 1;
        handle->smu_mgr = smumgr;
@@ -91,13 +91,6 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
        return 0;
 }
 
-int smum_fini(struct pp_smumgr *smumgr)
-{
-       kfree(smumgr->device);
-       kfree(smumgr);
-       return 0;
-}
-
 int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr,
                void *input, void *output, void *storage, int result)
 {