diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/si_dpm.c | 41 |
4 files changed, 121 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index 5dd9daae9eef..8c96a4caa715 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | |||
@@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs { | |||
270 | struct amdgpu_ps *cps, | 270 | struct amdgpu_ps *cps, |
271 | struct amdgpu_ps *rps, | 271 | struct amdgpu_ps *rps, |
272 | bool *equal); | 272 | bool *equal); |
273 | int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value, | ||
274 | int *size); | ||
273 | 275 | ||
274 | struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device *adev, unsigned idx); | 276 | struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device *adev, unsigned idx); |
275 | int (*reset_power_profile_state)(struct amdgpu_device *adev, | 277 | int (*reset_power_profile_state)(struct amdgpu_device *adev, |
@@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs { | |||
293 | #define amdgpu_dpm_read_sensor(adev, idx, value, size) \ | 295 | #define amdgpu_dpm_read_sensor(adev, idx, value, size) \ |
294 | ((adev)->pp_enabled ? \ | 296 | ((adev)->pp_enabled ? \ |
295 | (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \ | 297 | (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \ |
296 | -EINVAL) | 298 | (adev)->pm.funcs->read_sensor((adev), (idx), (value), (size))) |
297 | 299 | ||
298 | #define amdgpu_dpm_get_temperature(adev) \ | 300 | #define amdgpu_dpm_get_temperature(adev) \ |
299 | ((adev)->pp_enabled ? \ | 301 | ((adev)->pp_enabled ? \ |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 578878d1d4c0..b00e81db522d 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
@@ -6936,6 +6936,48 @@ static int ci_dpm_switch_power_profile(struct amdgpu_device *adev, | |||
6936 | return 0; | 6936 | return 0; |
6937 | } | 6937 | } |
6938 | 6938 | ||
6939 | static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx, | ||
6940 | void *value, int *size) | ||
6941 | { | ||
6942 | u32 activity_percent = 50; | ||
6943 | int ret; | ||
6944 | |||
6945 | /* size must be at least 4 bytes for all sensors */ | ||
6946 | if (*size < 4) | ||
6947 | return -EINVAL; | ||
6948 | |||
6949 | switch (idx) { | ||
6950 | case AMDGPU_PP_SENSOR_GFX_SCLK: | ||
6951 | *((uint32_t *)value) = ci_get_average_sclk_freq(adev); | ||
6952 | *size = 4; | ||
6953 | return 0; | ||
6954 | case AMDGPU_PP_SENSOR_GFX_MCLK: | ||
6955 | *((uint32_t *)value) = ci_get_average_mclk_freq(adev); | ||
6956 | *size = 4; | ||
6957 | return 0; | ||
6958 | case AMDGPU_PP_SENSOR_GPU_TEMP: | ||
6959 | *((uint32_t *)value) = ci_dpm_get_temp(adev); | ||
6960 | *size = 4; | ||
6961 | return 0; | ||
6962 | case AMDGPU_PP_SENSOR_GPU_LOAD: | ||
6963 | ret = ci_read_smc_soft_register(adev, | ||
6964 | offsetof(SMU7_SoftRegisters, | ||
6965 | AverageGraphicsA), | ||
6966 | &activity_percent); | ||
6967 | if (ret == 0) { | ||
6968 | activity_percent += 0x80; | ||
6969 | activity_percent >>= 8; | ||
6970 | activity_percent = | ||
6971 | activity_percent > 100 ? 100 : activity_percent; | ||
6972 | } | ||
6973 | *((uint32_t *)value) = activity_percent; | ||
6974 | *size = 4; | ||
6975 | return 0; | ||
6976 | default: | ||
6977 | return -EINVAL; | ||
6978 | } | ||
6979 | } | ||
6980 | |||
6939 | const struct amd_ip_funcs ci_dpm_ip_funcs = { | 6981 | const struct amd_ip_funcs ci_dpm_ip_funcs = { |
6940 | .name = "ci_dpm", | 6982 | .name = "ci_dpm", |
6941 | .early_init = ci_dpm_early_init, | 6983 | .early_init = ci_dpm_early_init, |
@@ -6982,6 +7024,7 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = { | |||
6982 | .set_power_profile_state = ci_dpm_set_power_profile_state, | 7024 | .set_power_profile_state = ci_dpm_set_power_profile_state, |
6983 | .reset_power_profile_state = ci_dpm_reset_power_profile_state, | 7025 | .reset_power_profile_state = ci_dpm_reset_power_profile_state, |
6984 | .switch_power_profile = ci_dpm_switch_power_profile, | 7026 | .switch_power_profile = ci_dpm_switch_power_profile, |
7027 | .read_sensor = ci_dpm_read_sensor, | ||
6985 | }; | 7028 | }; |
6986 | 7029 | ||
6987 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) | 7030 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index f5a343cb0010..13f323745729 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c | |||
@@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct amdgpu_device *adev, | |||
3260 | return 0; | 3260 | return 0; |
3261 | } | 3261 | } |
3262 | 3262 | ||
3263 | static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx, | ||
3264 | void *value, int *size) | ||
3265 | { | ||
3266 | struct kv_power_info *pi = kv_get_pi(adev); | ||
3267 | uint32_t sclk; | ||
3268 | u32 pl_index = | ||
3269 | (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) & | ||
3270 | TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >> | ||
3271 | TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT; | ||
3272 | |||
3273 | /* size must be at least 4 bytes for all sensors */ | ||
3274 | if (*size < 4) | ||
3275 | return -EINVAL; | ||
3276 | |||
3277 | switch (idx) { | ||
3278 | case AMDGPU_PP_SENSOR_GFX_SCLK: | ||
3279 | if (pl_index < SMU__NUM_SCLK_DPM_STATE) { | ||
3280 | sclk = be32_to_cpu( | ||
3281 | pi->graphics_level[pl_index].SclkFrequency); | ||
3282 | *((uint32_t *)value) = sclk; | ||
3283 | *size = 4; | ||
3284 | return 0; | ||
3285 | } | ||
3286 | return -EINVAL; | ||
3287 | case AMDGPU_PP_SENSOR_GPU_TEMP: | ||
3288 | *((uint32_t *)value) = kv_dpm_get_temp(adev); | ||
3289 | *size = 4; | ||
3290 | return 0; | ||
3291 | default: | ||
3292 | return -EINVAL; | ||
3293 | } | ||
3294 | } | ||
3295 | |||
3263 | const struct amd_ip_funcs kv_dpm_ip_funcs = { | 3296 | const struct amd_ip_funcs kv_dpm_ip_funcs = { |
3264 | .name = "kv_dpm", | 3297 | .name = "kv_dpm", |
3265 | .early_init = kv_dpm_early_init, | 3298 | .early_init = kv_dpm_early_init, |
@@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs kv_dpm_funcs = { | |||
3292 | .enable_bapm = &kv_dpm_enable_bapm, | 3325 | .enable_bapm = &kv_dpm_enable_bapm, |
3293 | .get_vce_clock_state = amdgpu_get_vce_clock_state, | 3326 | .get_vce_clock_state = amdgpu_get_vce_clock_state, |
3294 | .check_state_equal = kv_check_state_equal, | 3327 | .check_state_equal = kv_check_state_equal, |
3328 | .read_sensor = &kv_dpm_read_sensor, | ||
3295 | }; | 3329 | }; |
3296 | 3330 | ||
3297 | static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev) | 3331 | static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index c5dec210d529..eb84c2a6d951 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | |||
@@ -7982,6 +7982,46 @@ static int si_check_state_equal(struct amdgpu_device *adev, | |||
7982 | return 0; | 7982 | return 0; |
7983 | } | 7983 | } |
7984 | 7984 | ||
7985 | static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx, | ||
7986 | void *value, int *size) | ||
7987 | { | ||
7988 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | ||
7989 | struct amdgpu_ps *rps = &eg_pi->current_rps; | ||
7990 | struct si_ps *ps = si_get_ps(rps); | ||
7991 | uint32_t sclk, mclk; | ||
7992 | u32 pl_index = | ||
7993 | (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >> | ||
7994 | CURRENT_STATE_INDEX_SHIFT; | ||
7995 | |||
7996 | /* size must be at least 4 bytes for all sensors */ | ||
7997 | if (*size < 4) | ||
7998 | return -EINVAL; | ||
7999 | |||
8000 | switch (idx) { | ||
8001 | case AMDGPU_PP_SENSOR_GFX_SCLK: | ||
8002 | if (pl_index < ps->performance_level_count) { | ||
8003 | sclk = ps->performance_levels[pl_index].sclk; | ||
8004 | *((uint32_t *)value) = sclk; | ||
8005 | *size = 4; | ||
8006 | return 0; | ||
8007 | } | ||
8008 | return -EINVAL; | ||
8009 | case AMDGPU_PP_SENSOR_GFX_MCLK: | ||
8010 | if (pl_index < ps->performance_level_count) { | ||
8011 | mclk = ps->performance_levels[pl_index].mclk; | ||
8012 | *((uint32_t *)value) = mclk; | ||
8013 | *size = 4; | ||
8014 | return 0; | ||
8015 | } | ||
8016 | return -EINVAL; | ||
8017 | case AMDGPU_PP_SENSOR_GPU_TEMP: | ||
8018 | *((uint32_t *)value) = si_dpm_get_temp(adev); | ||
8019 | *size = 4; | ||
8020 | return 0; | ||
8021 | default: | ||
8022 | return -EINVAL; | ||
8023 | } | ||
8024 | } | ||
7985 | 8025 | ||
7986 | const struct amd_ip_funcs si_dpm_ip_funcs = { | 8026 | const struct amd_ip_funcs si_dpm_ip_funcs = { |
7987 | .name = "si_dpm", | 8027 | .name = "si_dpm", |
@@ -8018,6 +8058,7 @@ static const struct amdgpu_dpm_funcs si_dpm_funcs = { | |||
8018 | .get_fan_speed_percent = &si_dpm_get_fan_speed_percent, | 8058 | .get_fan_speed_percent = &si_dpm_get_fan_speed_percent, |
8019 | .check_state_equal = &si_check_state_equal, | 8059 | .check_state_equal = &si_check_state_equal, |
8020 | .get_vce_clock_state = amdgpu_get_vce_clock_state, | 8060 | .get_vce_clock_state = amdgpu_get_vce_clock_state, |
8061 | .read_sensor = &si_dpm_read_sensor, | ||
8021 | }; | 8062 | }; |
8022 | 8063 | ||
8023 | static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev) | 8064 | static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev) |