Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Eric Huang and committed by
Alex Deucher
5632708f 51224389

+81 -34
+36 -15
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
··· 362 362 struct amdgpu_device *adev = ddev->dev_private; 363 363 int ret; 364 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) { 369 - count = -EINVAL; 370 - goto fail; 373 + if (ret) { 374 + count = -EINVAL; 375 + goto fail; 376 + } 377 + mask |= 1 << level; 371 378 } 372 379 373 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 382 fail: 376 383 return count; 377 384 } ··· 406 399 struct amdgpu_device *adev = ddev->dev_private; 407 400 int ret; 408 401 long level; 402 + uint32_t i, mask = 0; 403 + char sub_str[2]; 409 404 410 - ret = kstrtol(buf, 0, &level); 405 + for (i = 0; i < strlen(buf) - 1; i++) { 406 + sub_str[0] = *(buf + i); 407 + sub_str[1] = '\0'; 408 + ret = kstrtol(sub_str, 0, &level); 411 409 412 - if (ret) { 413 - count = -EINVAL; 414 - goto fail; 410 + if (ret) { 411 + count = -EINVAL; 412 + goto fail; 413 + } 414 + mask |= 1 << level; 415 415 } 416 416 417 417 if (adev->pp_enabled) 418 - amdgpu_dpm_force_clock_level(adev, PP_MCLK, level); 418 + amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); 419 419 fail: 420 420 return count; 421 421 } ··· 450 436 struct amdgpu_device *adev = ddev->dev_private; 451 437 int ret; 452 438 long level; 439 + uint32_t i, mask = 0; 440 + char sub_str[2]; 453 441 454 - ret = kstrtol(buf, 0, &level); 442 + for (i = 0; i < strlen(buf) - 1; i++) { 443 + sub_str[0] = *(buf + i); 444 + sub_str[1] = '\0'; 445 + ret = kstrtol(sub_str, 0, &level); 455 446 456 - if (ret) { 457 - count = -EINVAL; 458 - goto fail; 447 + if (ret) { 448 + count = -EINVAL; 449 + goto fail; 450 + } 451 + mask |= 1 << level; 459 452 } 460 453 461 454 if (adev->pp_enabled) 462 - amdgpu_dpm_force_clock_level(adev, PP_PCIE, level); 455 + amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); 463 456 fail: 464 457 return count; 465 458 }
+2 -2
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
··· 763 763 } 764 764 765 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 768 struct pp_hwmgr *hwmgr; 769 769 ··· 779 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 785 static int pp_dpm_print_clock_levels(void *handle,
+3 -3
drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
··· 1729 1729 } 1730 1730 1731 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 1734 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 1735 1735 return -EINVAL; ··· 1738 1738 case PP_SCLK: 1739 1739 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 1740 1740 PPSMC_MSG_SetSclkSoftMin, 1741 - (1 << level)); 1741 + mask); 1742 1742 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 1743 1743 PPSMC_MSG_SetSclkSoftMax, 1744 - (1 << level)); 1744 + mask); 1745 1745 break; 1746 1746 default: 1747 1747 break;
+14 -4
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
··· 5113 5113 } 5114 5114 5115 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 5118 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 5119 5119 ··· 5125 5125 if (!data->sclk_dpm_key_disabled) 5126 5126 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 5127 5127 PPSMC_MSG_SCLKDPM_SetEnabledMask, 5128 - (1 << level)); 5128 + data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); 5129 5129 break; 5130 + 5130 5131 case PP_MCLK: 5131 5132 if (!data->mclk_dpm_key_disabled) 5132 5133 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 5133 5134 PPSMC_MSG_MCLKDPM_SetEnabledMask, 5134 - (1 << level)); 5135 + data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); 5135 5136 break; 5137 + 5136 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 5146 if (!data->pcie_dpm_key_disabled) 5138 5147 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 5139 5148 PPSMC_MSG_PCIeDPM_ForceLevel, 5140 - (1 << level)); 5149 + level); 5141 5150 break; 5151 + } 5142 5152 default: 5143 5153 break; 5144 5154 }
+12 -4
drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c
··· 4767 4767 } 4768 4768 4769 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 4772 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); 4773 4773 ··· 4779 4779 if (!data->sclk_dpm_key_disabled) 4780 4780 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 4781 4781 PPSMC_MSG_SCLKDPM_SetEnabledMask, 4782 - (1 << level)); 4782 + data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); 4783 4783 break; 4784 4784 case PP_MCLK: 4785 4785 if (!data->mclk_dpm_key_disabled) 4786 4786 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 4787 4787 PPSMC_MSG_MCLKDPM_SetEnabledMask, 4788 - (1 << level)); 4788 + data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); 4789 4789 break; 4790 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 4798 if (!data->pcie_dpm_key_disabled) 4792 4799 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 4793 4800 PPSMC_MSG_PCIeDPM_ForceLevel, 4794 - (1 << level)); 4801 + level); 4795 4802 break; 4803 + } 4796 4804 default: 4797 4805 break; 4798 4806 }
+12 -4
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
··· 6075 6075 } 6076 6076 6077 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 6080 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 6081 6081 ··· 6087 6087 if (!data->sclk_dpm_key_disabled) 6088 6088 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 6089 6089 PPSMC_MSG_SCLKDPM_SetEnabledMask, 6090 - (1 << level)); 6090 + data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); 6091 6091 break; 6092 6092 case PP_MCLK: 6093 6093 if (!data->mclk_dpm_key_disabled) 6094 6094 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 6095 6095 PPSMC_MSG_MCLKDPM_SetEnabledMask, 6096 - (1 << level)); 6096 + data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); 6097 6097 break; 6098 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 6106 if (!data->pcie_dpm_key_disabled) 6100 6107 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 6101 6108 PPSMC_MSG_PCIeDPM_ForceLevel, 6102 - (1 << level)); 6109 + level); 6103 6110 break; 6111 + } 6104 6112 default: 6105 6113 break; 6106 6114 }
+1 -1
drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
··· 340 340 int (*get_pp_num_states)(void *handle, struct pp_states_info *data); 341 341 int (*get_pp_table)(void *handle, char **table); 342 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 344 int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); 345 345 }; 346 346
+1 -1
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 335 335 int (*power_off_asic)(struct pp_hwmgr *hwmgr); 336 336 int (*get_pp_table)(struct pp_hwmgr *hwmgr, char **table); 337 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 339 int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); 340 340 int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); 341 341 };