mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
ae6a58e409
commit
1c86380248
|
@ -34,30 +34,50 @@
|
|||
#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);
|
||||
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;
|
||||
}
|
||||
|
||||
if (adev->pp_enabled) {
|
||||
struct amd_pp_init *pp_init;
|
||||
static int amdgpu_pp_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amd_powerplay *amd_pp;
|
||||
int ret = 0;
|
||||
|
||||
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 = &(adev->powerplay);
|
||||
adev->pp_enabled = false;
|
||||
amd_pp->pp_handle = (void *)adev;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_TOPAZ:
|
||||
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:
|
||||
|
@ -82,44 +102,15 @@ static int amdgpu_powerplay_init(struct amdgpu_device *adev)
|
|||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdgpu_pp_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret = 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_TOPAZ:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
adev->pp_enabled = true;
|
||||
break;
|
||||
/* These chips don't have powerplay implemenations */
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
case CHIP_KAVERI:
|
||||
default:
|
||||
adev->pp_enabled = false;
|
||||
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)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,10 +169,77 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns once the part of the register indicated by the mask has
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue