aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ci_dpm.c43
-rw-r--r--drivers/gpu/drm/amd/amdgpu/kv_dpm.c34
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si_dpm.c41
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
6939static 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
6939const struct amd_ip_funcs ci_dpm_ip_funcs = { 6981const 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
6987static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) 7030static 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
3263static 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
3263const struct amd_ip_funcs kv_dpm_ip_funcs = { 3296const 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
3297static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev) 3331static 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
7985static 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
7986const struct amd_ip_funcs si_dpm_ip_funcs = { 8026const 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
8023static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev) 8064static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)