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

drm/amd/powerplay: update swSMU VCN/JPEG PG logics

Add lock protections and avoid unnecessary actions
if the PG state is already the same as required.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Tested-by: Matt Coffin <mcoffin13@gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Evan Quan and committed by
Alex Deucher
2c34c960 f2e2573c

+60 -34
+56 -1
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
··· 133 133 return ret; 134 134 } 135 135 136 + static int smu_dpm_set_vcn_enable(struct smu_context *smu, 137 + bool enable) 138 + { 139 + struct smu_power_context *smu_power = &smu->smu_power; 140 + struct smu_power_gate *power_gate = &smu_power->power_gate; 141 + int ret = 0; 142 + 143 + if (!smu->ppt_funcs->dpm_set_vcn_enable) 144 + return 0; 145 + 146 + mutex_lock(&power_gate->vcn_gate_lock); 147 + 148 + if (atomic_read(&power_gate->vcn_gated) ^ enable) 149 + goto out; 150 + 151 + ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); 152 + if (!ret) 153 + atomic_set(&power_gate->vcn_gated, !enable); 154 + 155 + out: 156 + mutex_unlock(&power_gate->vcn_gate_lock); 157 + 158 + return ret; 159 + } 160 + 161 + static int smu_dpm_set_jpeg_enable(struct smu_context *smu, 162 + bool enable) 163 + { 164 + struct smu_power_context *smu_power = &smu->smu_power; 165 + struct smu_power_gate *power_gate = &smu_power->power_gate; 166 + int ret = 0; 167 + 168 + if (!smu->ppt_funcs->dpm_set_jpeg_enable) 169 + return 0; 170 + 171 + mutex_lock(&power_gate->jpeg_gate_lock); 172 + 173 + if (atomic_read(&power_gate->jpeg_gated) ^ enable) 174 + goto out; 175 + 176 + ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable); 177 + if (!ret) 178 + atomic_set(&power_gate->jpeg_gated, !enable); 179 + 180 + out: 181 + mutex_unlock(&power_gate->jpeg_gate_lock); 182 + 183 + return ret; 184 + } 185 + 136 186 /** 137 187 * smu_dpm_set_power_gate - power gate/ungate the specific IP block 138 188 * ··· 698 648 smu->watermarks_bitmap = 0; 699 649 smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; 700 650 smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; 651 + 652 + atomic_set(&smu->smu_power.power_gate.vcn_gated, 1); 653 + atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1); 654 + mutex_init(&smu->smu_power.power_gate.vcn_gate_lock); 655 + mutex_init(&smu->smu_power.power_gate.jpeg_gate_lock); 701 656 702 657 smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; 703 658 smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; ··· 2028 1973 *size = 4; 2029 1974 break; 2030 1975 case AMDGPU_PP_SENSOR_VCN_POWER_STATE: 2031 - *(uint32_t *)data = smu->smu_power.power_gate.vcn_gated ? 0 : 1; 1976 + *(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0: 1; 2032 1977 *size = 4; 2033 1978 break; 2034 1979 case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
-4
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
··· 1849 1849 1850 1850 static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 1851 1851 { 1852 - struct smu_power_context *smu_power = &smu->smu_power; 1853 - struct smu_power_gate *power_gate = &smu_power->power_gate; 1854 1852 int ret = 0; 1855 1853 1856 1854 if (enable) { ··· 1859 1861 return ret; 1860 1862 } 1861 1863 } 1862 - power_gate->vcn_gated = false; 1863 1864 } else { 1864 1865 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 1865 1866 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0); ··· 1867 1870 return ret; 1868 1871 } 1869 1872 } 1870 - power_gate->vcn_gated = true; 1871 1873 } 1872 1874 1873 1875 return ret;
+4 -2
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
··· 292 292 struct smu_power_gate { 293 293 bool uvd_gated; 294 294 bool vce_gated; 295 - bool vcn_gated; 296 - bool jpeg_gated; 295 + atomic_t vcn_gated; 296 + atomic_t jpeg_gated; 297 + struct mutex vcn_gate_lock; 298 + struct mutex jpeg_gate_lock; 297 299 }; 298 300 299 301 struct smu_power_context {
-8
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
··· 785 785 786 786 static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 787 787 { 788 - struct smu_power_context *smu_power = &smu->smu_power; 789 - struct smu_power_gate *power_gate = &smu_power->power_gate; 790 788 int ret = 0; 791 789 792 790 if (enable) { ··· 794 796 if (ret) 795 797 return ret; 796 798 } 797 - power_gate->vcn_gated = false; 798 799 } else { 799 800 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 800 801 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL); 801 802 if (ret) 802 803 return ret; 803 804 } 804 - power_gate->vcn_gated = true; 805 805 } 806 806 807 807 return ret; ··· 807 811 808 812 static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) 809 813 { 810 - struct smu_power_context *smu_power = &smu->smu_power; 811 - struct smu_power_gate *power_gate = &smu_power->power_gate; 812 814 int ret = 0; 813 815 814 816 if (enable) { ··· 815 821 if (ret) 816 822 return ret; 817 823 } 818 - power_gate->jpeg_gated = false; 819 824 } else { 820 825 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { 821 826 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL); 822 827 if (ret) 823 828 return ret; 824 829 } 825 - power_gate->jpeg_gated = true; 826 830 } 827 831 828 832 return ret;
-8
drivers/gpu/drm/amd/powerplay/renoir_ppt.c
··· 459 459 460 460 static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 461 461 { 462 - struct smu_power_context *smu_power = &smu->smu_power; 463 - struct smu_power_gate *power_gate = &smu_power->power_gate; 464 462 int ret = 0; 465 463 466 464 if (enable) { ··· 468 470 if (ret) 469 471 return ret; 470 472 } 471 - power_gate->vcn_gated = false; 472 473 } else { 473 474 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 474 475 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL); 475 476 if (ret) 476 477 return ret; 477 478 } 478 - power_gate->vcn_gated = true; 479 479 } 480 480 481 481 return ret; ··· 481 485 482 486 static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) 483 487 { 484 - struct smu_power_context *smu_power = &smu->smu_power; 485 - struct smu_power_gate *power_gate = &smu_power->power_gate; 486 488 int ret = 0; 487 489 488 490 if (enable) { ··· 489 495 if (ret) 490 496 return ret; 491 497 } 492 - power_gate->jpeg_gated = false; 493 498 } else { 494 499 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { 495 500 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL); 496 501 if (ret) 497 502 return ret; 498 503 } 499 - power_gate->jpeg_gated = true; 500 504 } 501 505 502 506 return ret;
-9
drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c
··· 766 766 767 767 static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 768 768 { 769 - struct smu_power_context *smu_power = &smu->smu_power; 770 - struct smu_power_gate *power_gate = &smu_power->power_gate; 771 769 struct amdgpu_device *adev = smu->adev; 772 - 773 770 int ret = 0; 774 771 775 772 if (enable) { ··· 782 785 return ret; 783 786 } 784 787 } 785 - power_gate->vcn_gated = false; 786 788 } else { 787 789 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { 788 790 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL); ··· 794 798 return ret; 795 799 } 796 800 } 797 - power_gate->vcn_gated = true; 798 801 } 799 802 800 803 return ret; ··· 801 806 802 807 static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) 803 808 { 804 - struct smu_power_context *smu_power = &smu->smu_power; 805 - struct smu_power_gate *power_gate = &smu_power->power_gate; 806 809 int ret = 0; 807 810 808 811 if (enable) { ··· 809 816 if (ret) 810 817 return ret; 811 818 } 812 - power_gate->jpeg_gated = false; 813 819 } else { 814 820 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { 815 821 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL); 816 822 if (ret) 817 823 return ret; 818 824 } 819 - power_gate->jpeg_gated = true; 820 825 } 821 826 822 827 return ret;
-2
drivers/gpu/drm/amd/powerplay/smu_internal.h
··· 77 77 #define smu_get_dal_power_level(smu, clocks) smu_ppt_funcs(get_dal_power_level, 0, smu, clocks) 78 78 #define smu_get_perf_level(smu, designation, level) smu_ppt_funcs(get_perf_level, 0, smu, designation, level) 79 79 #define smu_get_current_shallow_sleep_clocks(smu, clocks) smu_ppt_funcs(get_current_shallow_sleep_clocks, 0, smu, clocks) 80 - #define smu_dpm_set_vcn_enable(smu, enable) smu_ppt_funcs(dpm_set_vcn_enable, 0, smu, enable) 81 - #define smu_dpm_set_jpeg_enable(smu, enable) smu_ppt_funcs(dpm_set_jpeg_enable, 0, smu, enable) 82 80 #define smu_set_watermarks_table(smu, clock_ranges) smu_ppt_funcs(set_watermarks_table, 0, smu, clock_ranges) 83 81 #define smu_thermal_temperature_range_update(smu, range, rw) smu_ppt_funcs(thermal_temperature_range_update, 0, smu, range, rw) 84 82 #define smu_register_irq_handler(smu) smu_ppt_funcs(register_irq_handler, 0, smu)