diff options
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 |
5 files changed, 27 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 81e6856ffa11..fde8fcd46b58 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -880,7 +880,8 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value) return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value); } -static int pp_dpm_read_sensor(void *handle, int idx, void *value) +static int pp_dpm_read_sensor(void *handle, int idx, + void *value, int *size) { struct pp_hwmgr *hwmgr; struct pp_instance *pp_handle = (struct pp_instance *)handle; @@ -898,7 +899,7 @@ static int pp_dpm_read_sensor(void *handle, int idx, void *value) return 0; } - return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value); + return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value, size); } static struct amd_vce_state* diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index edc3029df785..7aa5ca815a3a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1813,7 +1813,8 @@ static int cz_thermal_get_temperature(struct pp_hwmgr *hwmgr) return actual_temp; } -static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value) +static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, + void *value, int *size) { struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); @@ -1837,6 +1838,11 @@ static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value) uint16_t vddnb, vddgfx; int result; + /* size must be at least 4 bytes for all sensors */ + if (*size < 4) + return -EINVAL; + *size = 4; + switch (idx) { case AMDGPU_PP_SENSOR_GFX_SCLK: if (sclk_index < NUM_SCLK_LEVELS) { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 5a4ee43b3d65..13b35be3174c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3320,22 +3320,29 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, return 0; } -static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value) +static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, + void *value, int *size) { uint32_t sclk, mclk, activity_percent; uint32_t offset; struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + /* size must be at least 4 bytes for all sensors */ + if (*size < 4) + return -EINVAL; + switch (idx) { case AMDGPU_PP_SENSOR_GFX_SCLK: smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency); sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); *((uint32_t *)value) = sclk; + *size = 4; return 0; case AMDGPU_PP_SENSOR_GFX_MCLK: smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency); mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); *((uint32_t *)value) = mclk; + *size = 4; return 0; case AMDGPU_PP_SENSOR_GPU_LOAD: offset = data->soft_regs_start + smum_get_offsetof(hwmgr->smumgr, @@ -3346,17 +3353,24 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value) activity_percent += 0x80; activity_percent >>= 8; *((uint32_t *)value) = activity_percent > 100 ? 100 : activity_percent; + *size = 4; return 0; case AMDGPU_PP_SENSOR_GPU_TEMP: *((uint32_t *)value) = smu7_thermal_get_temperature(hwmgr); + *size = 4; return 0; case AMDGPU_PP_SENSOR_UVD_POWER: *((uint32_t *)value) = data->uvd_power_gated ? 0 : 1; + *size = 4; return 0; case AMDGPU_PP_SENSOR_VCE_POWER: *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; + *size = 4; return 0; case AMDGPU_PP_SENSOR_GPU_POWER: + if (*size < sizeof(struct pp_gpu_power)) + return -EINVAL; + *size = sizeof(struct pp_gpu_power); return smu7_get_gpu_power(hwmgr, (struct pp_gpu_power *)value); default: return -EINVAL; diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index ab99013eba77..c0bf3af6846d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -367,7 +367,7 @@ struct amd_powerplay_funcs { int (*set_sclk_od)(void *handle, uint32_t value); int (*get_mclk_od)(void *handle); int (*set_mclk_od)(void *handle, uint32_t value); - int (*read_sensor)(void *handle, int idx, void *value); + int (*read_sensor)(void *handle, int idx, void *value, int *size); struct amd_vce_state* (*get_vce_clock_state)(void *handle, unsigned idx); int (*reset_power_profile_state)(void *handle, struct amd_pp_profile *request); diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index fa3bf50eff82..8cf5aed055b6 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -355,7 +355,7 @@ struct pp_hwmgr_func { int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); int (*get_mclk_od)(struct pp_hwmgr *hwmgr); int (*set_mclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); - int (*read_sensor)(struct pp_hwmgr *hwmgr, int idx, void *value); + int (*read_sensor)(struct pp_hwmgr *hwmgr, int idx, void *value, int *size); int (*request_firmware)(struct pp_hwmgr *hwmgr); int (*release_firmware)(struct pp_hwmgr *hwmgr); int (*set_power_profile_state)(struct pp_hwmgr *hwmgr, |