diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2016-12-28 19:43:23 +0800 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-01-27 11:12:58 -0500 |
commit | 1c86380248467b99a0d9a9f7fdd0834fa0c6c5aa (patch) | |
tree | 45b21f37f3b7478c4c3e1e6cd654a2fb0c6769a9 | |
parent | ae6a58e4090365f0ed6b24e0a67b8a08f6b55856 (diff) |
drm/amd/powerplay: refine powerplay interface.
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>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 108 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 709 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 114 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/eventmgr.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/pp_instance.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/smumgr.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | 17 |
10 files changed, 518 insertions, 479 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index b1921c7da36b..8856eccc37fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -34,63 +34,34 @@ #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) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index fbbac6ba0d17..429f18b99323 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -32,162 +32,152 @@ #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; } diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c index fb88e4e5d625..781e53dcf128 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c @@ -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; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index bd4ca681e260..6bc63f26623d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -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; } diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 6d52a397ff88..6dd5f0e9ef87 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -29,7 +29,10 @@ #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); diff --git a/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h b/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h index d63ef83b2628..7bd8a7e57080 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h @@ -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_ */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 3b7450ee7163..0d93801f21ea 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -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, diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h index 4d8ed1f33de4..ab8494fb5c6b 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h +++ b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h @@ -31,6 +31,11 @@ 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; diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h index 2139072065cc..0e5937295835 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h @@ -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); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index 45737cd3c055..d5244c16d2d5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c @@ -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) { |