diff options
author | Eric Huang <JinHuiEric.Huang@amd.com> | 2016-04-12 14:57:23 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-05-04 20:29:47 -0400 |
commit | 5632708f4452eb9afb985b245b98dac9a5feeac2 (patch) | |
tree | cd46c6074e2869548d735b77f17fe0d1be3953b6 | |
parent | 51224389543ebd7307e09f0f46e5c5cac417d940 (diff) |
drm/amd/powerplay: add dpm force multiple levels on cz/tonga/fiji/polaris (v2)
Allows you to force multiple levels rather than just one via the new
sysfs interrface.
v2: squash in:
drm/amd/powerplay: ensure clock level set by user is valid.
From Rex.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/tonga_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 |
8 files changed, 81 insertions, 34 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 6d44d4a64698..589b36e8c5cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
@@ -362,16 +362,23 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, | |||
362 | struct amdgpu_device *adev = ddev->dev_private; | 362 | struct amdgpu_device *adev = ddev->dev_private; |
363 | int ret; | 363 | int ret; |
364 | long level; | 364 | long level; |
365 | uint32_t i, mask = 0; | ||
366 | char sub_str[2]; | ||
365 | 367 | ||
366 | ret = kstrtol(buf, 0, &level); | 368 | for (i = 0; i < strlen(buf) - 1; i++) { |
369 | sub_str[0] = *(buf + i); | ||
370 | sub_str[1] = '\0'; | ||
371 | ret = kstrtol(sub_str, 0, &level); | ||
367 | 372 | ||
368 | if (ret) { | 373 | if (ret) { |
369 | count = -EINVAL; | 374 | count = -EINVAL; |
370 | goto fail; | 375 | goto fail; |
376 | } | ||
377 | mask |= 1 << level; | ||
371 | } | 378 | } |
372 | 379 | ||
373 | if (adev->pp_enabled) | 380 | if (adev->pp_enabled) |
374 | amdgpu_dpm_force_clock_level(adev, PP_SCLK, level); | 381 | amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); |
375 | fail: | 382 | fail: |
376 | return count; | 383 | return count; |
377 | } | 384 | } |
@@ -399,16 +406,23 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, | |||
399 | struct amdgpu_device *adev = ddev->dev_private; | 406 | struct amdgpu_device *adev = ddev->dev_private; |
400 | int ret; | 407 | int ret; |
401 | long level; | 408 | long level; |
409 | uint32_t i, mask = 0; | ||
410 | char sub_str[2]; | ||
402 | 411 | ||
403 | ret = kstrtol(buf, 0, &level); | 412 | for (i = 0; i < strlen(buf) - 1; i++) { |
413 | sub_str[0] = *(buf + i); | ||
414 | sub_str[1] = '\0'; | ||
415 | ret = kstrtol(sub_str, 0, &level); | ||
404 | 416 | ||
405 | if (ret) { | 417 | if (ret) { |
406 | count = -EINVAL; | 418 | count = -EINVAL; |
407 | goto fail; | 419 | goto fail; |
420 | } | ||
421 | mask |= 1 << level; | ||
408 | } | 422 | } |
409 | 423 | ||
410 | if (adev->pp_enabled) | 424 | if (adev->pp_enabled) |
411 | amdgpu_dpm_force_clock_level(adev, PP_MCLK, level); | 425 | amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); |
412 | fail: | 426 | fail: |
413 | return count; | 427 | return count; |
414 | } | 428 | } |
@@ -436,16 +450,23 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, | |||
436 | struct amdgpu_device *adev = ddev->dev_private; | 450 | struct amdgpu_device *adev = ddev->dev_private; |
437 | int ret; | 451 | int ret; |
438 | long level; | 452 | long level; |
453 | uint32_t i, mask = 0; | ||
454 | char sub_str[2]; | ||
439 | 455 | ||
440 | ret = kstrtol(buf, 0, &level); | 456 | for (i = 0; i < strlen(buf) - 1; i++) { |
457 | sub_str[0] = *(buf + i); | ||
458 | sub_str[1] = '\0'; | ||
459 | ret = kstrtol(sub_str, 0, &level); | ||
441 | 460 | ||
442 | if (ret) { | 461 | if (ret) { |
443 | count = -EINVAL; | 462 | count = -EINVAL; |
444 | goto fail; | 463 | goto fail; |
464 | } | ||
465 | mask |= 1 << level; | ||
445 | } | 466 | } |
446 | 467 | ||
447 | if (adev->pp_enabled) | 468 | if (adev->pp_enabled) |
448 | amdgpu_dpm_force_clock_level(adev, PP_PCIE, level); | 469 | amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); |
449 | fail: | 470 | fail: |
450 | return count; | 471 | return count; |
451 | } | 472 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index ce8d9bf8d68d..0527ae3d10f9 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
@@ -763,7 +763,7 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) | |||
763 | } | 763 | } |
764 | 764 | ||
765 | static int pp_dpm_force_clock_level(void *handle, | 765 | static int pp_dpm_force_clock_level(void *handle, |
766 | enum pp_clock_type type, int level) | 766 | enum pp_clock_type type, uint32_t mask) |
767 | { | 767 | { |
768 | struct pp_hwmgr *hwmgr; | 768 | struct pp_hwmgr *hwmgr; |
769 | 769 | ||
@@ -779,7 +779,7 @@ static int pp_dpm_force_clock_level(void *handle, | |||
779 | return 0; | 779 | return 0; |
780 | } | 780 | } |
781 | 781 | ||
782 | return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, level); | 782 | return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask); |
783 | } | 783 | } |
784 | 784 | ||
785 | static int pp_dpm_print_clock_levels(void *handle, | 785 | static int pp_dpm_print_clock_levels(void *handle, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 648394fff69a..1f14c477d15d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | |||
@@ -1729,7 +1729,7 @@ static int cz_get_dal_power_level(struct pp_hwmgr *hwmgr, | |||
1729 | } | 1729 | } |
1730 | 1730 | ||
1731 | static int cz_force_clock_level(struct pp_hwmgr *hwmgr, | 1731 | static int cz_force_clock_level(struct pp_hwmgr *hwmgr, |
1732 | enum pp_clock_type type, int level) | 1732 | enum pp_clock_type type, uint32_t mask) |
1733 | { | 1733 | { |
1734 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) | 1734 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) |
1735 | return -EINVAL; | 1735 | return -EINVAL; |
@@ -1738,10 +1738,10 @@ static int cz_force_clock_level(struct pp_hwmgr *hwmgr, | |||
1738 | case PP_SCLK: | 1738 | case PP_SCLK: |
1739 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 1739 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
1740 | PPSMC_MSG_SetSclkSoftMin, | 1740 | PPSMC_MSG_SetSclkSoftMin, |
1741 | (1 << level)); | 1741 | mask); |
1742 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 1742 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
1743 | PPSMC_MSG_SetSclkSoftMax, | 1743 | PPSMC_MSG_SetSclkSoftMax, |
1744 | (1 << level)); | 1744 | mask); |
1745 | break; | 1745 | break; |
1746 | default: | 1746 | default: |
1747 | break; | 1747 | break; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index dc836d3e92b5..f8d49f1b44f5 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | |||
@@ -5113,7 +5113,7 @@ static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t siz | |||
5113 | } | 5113 | } |
5114 | 5114 | ||
5115 | static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, | 5115 | static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, |
5116 | enum pp_clock_type type, int level) | 5116 | enum pp_clock_type type, uint32_t mask) |
5117 | { | 5117 | { |
5118 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | 5118 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); |
5119 | 5119 | ||
@@ -5125,20 +5125,30 @@ static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, | |||
5125 | if (!data->sclk_dpm_key_disabled) | 5125 | if (!data->sclk_dpm_key_disabled) |
5126 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 5126 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
5127 | PPSMC_MSG_SCLKDPM_SetEnabledMask, | 5127 | PPSMC_MSG_SCLKDPM_SetEnabledMask, |
5128 | (1 << level)); | 5128 | data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); |
5129 | break; | 5129 | break; |
5130 | |||
5130 | case PP_MCLK: | 5131 | case PP_MCLK: |
5131 | if (!data->mclk_dpm_key_disabled) | 5132 | if (!data->mclk_dpm_key_disabled) |
5132 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 5133 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
5133 | PPSMC_MSG_MCLKDPM_SetEnabledMask, | 5134 | PPSMC_MSG_MCLKDPM_SetEnabledMask, |
5134 | (1 << level)); | 5135 | data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); |
5135 | break; | 5136 | break; |
5137 | |||
5136 | case PP_PCIE: | 5138 | case PP_PCIE: |
5139 | { | ||
5140 | uint32_t tmp = mask & data->dpm_level_enable_mask.pcie_dpm_enable_mask; | ||
5141 | uint32_t level = 0; | ||
5142 | |||
5143 | while (tmp >>= 1) | ||
5144 | level++; | ||
5145 | |||
5137 | if (!data->pcie_dpm_key_disabled) | 5146 | if (!data->pcie_dpm_key_disabled) |
5138 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 5147 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
5139 | PPSMC_MSG_PCIeDPM_ForceLevel, | 5148 | PPSMC_MSG_PCIeDPM_ForceLevel, |
5140 | (1 << level)); | 5149 | level); |
5141 | break; | 5150 | break; |
5151 | } | ||
5142 | default: | 5152 | default: |
5143 | break; | 5153 | break; |
5144 | } | 5154 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index 2ab3bb25d175..79192c301d78 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c | |||
@@ -4767,7 +4767,7 @@ static int polaris10_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_ | |||
4767 | } | 4767 | } |
4768 | 4768 | ||
4769 | static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr, | 4769 | static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr, |
4770 | enum pp_clock_type type, int level) | 4770 | enum pp_clock_type type, uint32_t mask) |
4771 | { | 4771 | { |
4772 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 4772 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
4773 | 4773 | ||
@@ -4779,20 +4779,28 @@ static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr, | |||
4779 | if (!data->sclk_dpm_key_disabled) | 4779 | if (!data->sclk_dpm_key_disabled) |
4780 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 4780 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
4781 | PPSMC_MSG_SCLKDPM_SetEnabledMask, | 4781 | PPSMC_MSG_SCLKDPM_SetEnabledMask, |
4782 | (1 << level)); | 4782 | data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); |
4783 | break; | 4783 | break; |
4784 | case PP_MCLK: | 4784 | case PP_MCLK: |
4785 | if (!data->mclk_dpm_key_disabled) | 4785 | if (!data->mclk_dpm_key_disabled) |
4786 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 4786 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
4787 | PPSMC_MSG_MCLKDPM_SetEnabledMask, | 4787 | PPSMC_MSG_MCLKDPM_SetEnabledMask, |
4788 | (1 << level)); | 4788 | data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); |
4789 | break; | 4789 | break; |
4790 | case PP_PCIE: | 4790 | case PP_PCIE: |
4791 | { | ||
4792 | uint32_t tmp = mask & data->dpm_level_enable_mask.pcie_dpm_enable_mask; | ||
4793 | uint32_t level = 0; | ||
4794 | |||
4795 | while (tmp >>= 1) | ||
4796 | level++; | ||
4797 | |||
4791 | if (!data->pcie_dpm_key_disabled) | 4798 | if (!data->pcie_dpm_key_disabled) |
4792 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 4799 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
4793 | PPSMC_MSG_PCIeDPM_ForceLevel, | 4800 | PPSMC_MSG_PCIeDPM_ForceLevel, |
4794 | (1 << level)); | 4801 | level); |
4795 | break; | 4802 | break; |
4803 | } | ||
4796 | default: | 4804 | default: |
4797 | break; | 4805 | break; |
4798 | } | 4806 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 0242e348e755..9040225bec90 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | |||
@@ -6075,7 +6075,7 @@ static int tonga_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t si | |||
6075 | } | 6075 | } |
6076 | 6076 | ||
6077 | static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, | 6077 | static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, |
6078 | enum pp_clock_type type, int level) | 6078 | enum pp_clock_type type, uint32_t mask) |
6079 | { | 6079 | { |
6080 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | 6080 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); |
6081 | 6081 | ||
@@ -6087,20 +6087,28 @@ static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, | |||
6087 | if (!data->sclk_dpm_key_disabled) | 6087 | if (!data->sclk_dpm_key_disabled) |
6088 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 6088 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
6089 | PPSMC_MSG_SCLKDPM_SetEnabledMask, | 6089 | PPSMC_MSG_SCLKDPM_SetEnabledMask, |
6090 | (1 << level)); | 6090 | data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); |
6091 | break; | 6091 | break; |
6092 | case PP_MCLK: | 6092 | case PP_MCLK: |
6093 | if (!data->mclk_dpm_key_disabled) | 6093 | if (!data->mclk_dpm_key_disabled) |
6094 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 6094 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
6095 | PPSMC_MSG_MCLKDPM_SetEnabledMask, | 6095 | PPSMC_MSG_MCLKDPM_SetEnabledMask, |
6096 | (1 << level)); | 6096 | data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); |
6097 | break; | 6097 | break; |
6098 | case PP_PCIE: | 6098 | case PP_PCIE: |
6099 | { | ||
6100 | uint32_t tmp = mask & data->dpm_level_enable_mask.pcie_dpm_enable_mask; | ||
6101 | uint32_t level = 0; | ||
6102 | |||
6103 | while (tmp >>= 1) | ||
6104 | level++; | ||
6105 | |||
6099 | if (!data->pcie_dpm_key_disabled) | 6106 | if (!data->pcie_dpm_key_disabled) |
6100 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | 6107 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, |
6101 | PPSMC_MSG_PCIeDPM_ForceLevel, | 6108 | PPSMC_MSG_PCIeDPM_ForceLevel, |
6102 | (1 << level)); | 6109 | level); |
6103 | break; | 6110 | break; |
6111 | } | ||
6104 | default: | 6112 | default: |
6105 | break; | 6113 | break; |
6106 | } | 6114 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index e5f2ee749fa6..50b367d44307 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | |||
@@ -340,7 +340,7 @@ struct amd_powerplay_funcs { | |||
340 | int (*get_pp_num_states)(void *handle, struct pp_states_info *data); | 340 | int (*get_pp_num_states)(void *handle, struct pp_states_info *data); |
341 | int (*get_pp_table)(void *handle, char **table); | 341 | int (*get_pp_table)(void *handle, char **table); |
342 | int (*set_pp_table)(void *handle, const char *buf, size_t size); | 342 | int (*set_pp_table)(void *handle, const char *buf, size_t size); |
343 | int (*force_clock_level)(void *handle, enum pp_clock_type type, int level); | 343 | int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); |
344 | int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); | 344 | int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); |
345 | }; | 345 | }; |
346 | 346 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 12285a989eff..b1a9ae509ed8 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -335,7 +335,7 @@ struct pp_hwmgr_func { | |||
335 | int (*power_off_asic)(struct pp_hwmgr *hwmgr); | 335 | int (*power_off_asic)(struct pp_hwmgr *hwmgr); |
336 | int (*get_pp_table)(struct pp_hwmgr *hwmgr, char **table); | 336 | int (*get_pp_table)(struct pp_hwmgr *hwmgr, char **table); |
337 | int (*set_pp_table)(struct pp_hwmgr *hwmgr, const char *buf, size_t size); | 337 | int (*set_pp_table)(struct pp_hwmgr *hwmgr, const char *buf, size_t size); |
338 | int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, int level); | 338 | int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); |
339 | int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); | 339 | int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); |
340 | int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); | 340 | int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); |
341 | }; | 341 | }; |