aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Huang <JinHuiEric.Huang@amd.com>2016-04-12 14:57:23 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-05-04 20:29:47 -0400
commit5632708f4452eb9afb985b245b98dac9a5feeac2 (patch)
treecd46c6074e2869548d735b77f17fe0d1be3953b6
parent51224389543ebd7307e09f0f46e5c5cac417d940 (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.c51
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c18
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c16
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c16
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h2
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);
375fail: 382fail:
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);
412fail: 426fail:
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);
449fail: 470fail:
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
765static int pp_dpm_force_clock_level(void *handle, 765static 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
785static int pp_dpm_print_clock_levels(void *handle, 785static 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
1731static int cz_force_clock_level(struct pp_hwmgr *hwmgr, 1731static 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
5115static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, 5115static 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
4769static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr, 4769static 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
6077static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, 6077static 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};