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 /drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 114 |
1 files changed, 84 insertions, 30 deletions
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; } |