Bug Summary

File:dev/pci/drm/amd/pm/swsmu/smu12/renoir_ppt.c
Warning:line 899, column 44
The right operand of '<<' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name renoir_ppt.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12/renoir_ppt.c
1/*
2 * Copyright 2019 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#define SWSMU_CODE_LAYER_L2
25
26#include "amdgpu.h"
27#include "amdgpu_smu.h"
28#include "smu_v12_0_ppsmc.h"
29#include "smu12_driver_if.h"
30#include "smu_v12_0.h"
31#include "renoir_ppt.h"
32#include "smu_cmn.h"
33
34/*
35 * DO NOT use these for err/warn/info/debug messages.
36 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
37 * They are more MGPU friendly.
38 */
39#undef pr_err
40#undef pr_warn
41#undef pr_info
42#undef pr_debug
43
44static struct cmn2asic_msg_mapping renoir_message_map[SMU_MSG_MAX_COUNT] = {
45 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1)[SMU_MSG_TestMessage] = {1, (0x1), (1)},
46 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1)[SMU_MSG_GetSmuVersion] = {1, (0x2), (1)},
47 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1)[SMU_MSG_GetDriverIfVersion] = {1, (0x3), (1)},
48 MSG_MAP(PowerUpGfx, PPSMC_MSG_PowerUpGfx, 1)[SMU_MSG_PowerUpGfx] = {1, (0x6), (1)},
49 MSG_MAP(AllowGfxOff, PPSMC_MSG_EnableGfxOff, 1)[SMU_MSG_AllowGfxOff] = {1, (0x7), (1)},
50 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisableGfxOff, 1)[SMU_MSG_DisallowGfxOff] = {1, (0x8), (1)},
51 MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1)[SMU_MSG_PowerDownIspByTile] = {1, (0x9), (1)},
52 MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1)[SMU_MSG_PowerUpIspByTile] = {1, (0xA), (1)},
53 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1)[SMU_MSG_PowerDownVcn] = {1, (0xB), (1)},
54 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1)[SMU_MSG_PowerUpVcn] = {1, (0xC), (1)},
55 MSG_MAP(PowerDownSdma, PPSMC_MSG_PowerDownSdma, 1)[SMU_MSG_PowerDownSdma] = {1, (0xD), (1)},
56 MSG_MAP(PowerUpSdma, PPSMC_MSG_PowerUpSdma, 1)[SMU_MSG_PowerUpSdma] = {1, (0xE), (1)},
57 MSG_MAP(SetHardMinIspclkByFreq, PPSMC_MSG_SetHardMinIspclkByFreq, 1)[SMU_MSG_SetHardMinIspclkByFreq] = {1, (0xF), (1)},
58 MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1)[SMU_MSG_SetHardMinVcn] = {1, (0x10), (1)},
59 MSG_MAP(Spare1, PPSMC_MSG_spare1, 1)[SMU_MSG_Spare1] = {1, (0x11), (1)},
60 MSG_MAP(Spare2, PPSMC_MSG_spare2, 1)[SMU_MSG_Spare2] = {1, (0x12), (1)},
61 MSG_MAP(SetAllowFclkSwitch, PPSMC_MSG_SetAllowFclkSwitch, 1)[SMU_MSG_SetAllowFclkSwitch] = {1, (0x13), (1)},
62 MSG_MAP(SetMinVideoGfxclkFreq, PPSMC_MSG_SetMinVideoGfxclkFreq, 1)[SMU_MSG_SetMinVideoGfxclkFreq] = {1, (0x14), (1)},
63 MSG_MAP(ActiveProcessNotify, PPSMC_MSG_ActiveProcessNotify, 1)[SMU_MSG_ActiveProcessNotify] = {1, (0x15), (1)},
64 MSG_MAP(SetCustomPolicy, PPSMC_MSG_SetCustomPolicy, 1)[SMU_MSG_SetCustomPolicy] = {1, (0x16), (1)},
65 MSG_MAP(SetVideoFps, PPSMC_MSG_SetVideoFps, 1)[SMU_MSG_SetVideoFps] = {1, (0x17), (1)},
66 MSG_MAP(NumOfDisplays, PPSMC_MSG_SetDisplayCount, 1)[SMU_MSG_NumOfDisplays] = {1, (0x18), (1)},
67 MSG_MAP(QueryPowerLimit, PPSMC_MSG_QueryPowerLimit, 1)[SMU_MSG_QueryPowerLimit] = {1, (0x19), (1)},
68 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1)[SMU_MSG_SetDriverDramAddrHigh] = {1, (0x1A), (1)},
69 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1)[SMU_MSG_SetDriverDramAddrLow] = {1, (0x1B), (1)},
70 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1)[SMU_MSG_TransferTableSmu2Dram] = {1, (0x1C), (1)},
71 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1)[SMU_MSG_TransferTableDram2Smu] = {1, (0x1D), (1)},
72 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1)[SMU_MSG_GfxDeviceDriverReset] = {1, (0x1E), (1)},
73 MSG_MAP(SetGfxclkOverdriveByFreqVid, PPSMC_MSG_SetGfxclkOverdriveByFreqVid, 1)[SMU_MSG_SetGfxclkOverdriveByFreqVid] = {1, (0x1F), (1)},
74 MSG_MAP(SetHardMinDcfclkByFreq, PPSMC_MSG_SetHardMinDcfclkByFreq, 1)[SMU_MSG_SetHardMinDcfclkByFreq] = {1, (0x20), (1)},
75 MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1)[SMU_MSG_SetHardMinSocclkByFreq] = {1, (0x21), (1)},
76 MSG_MAP(ControlIgpuATS, PPSMC_MSG_ControlIgpuATS, 1)[SMU_MSG_ControlIgpuATS] = {1, (0x22), (1)},
77 MSG_MAP(SetMinVideoFclkFreq, PPSMC_MSG_SetMinVideoFclkFreq, 1)[SMU_MSG_SetMinVideoFclkFreq] = {1, (0x23), (1)},
78 MSG_MAP(SetMinDeepSleepDcfclk, PPSMC_MSG_SetMinDeepSleepDcfclk, 1)[SMU_MSG_SetMinDeepSleepDcfclk] = {1, (0x24), (1)},
79 MSG_MAP(ForcePowerDownGfx, PPSMC_MSG_ForcePowerDownGfx, 1)[SMU_MSG_ForcePowerDownGfx] = {1, (0x25), (1)},
80 MSG_MAP(SetPhyclkVoltageByFreq, PPSMC_MSG_SetPhyclkVoltageByFreq, 1)[SMU_MSG_SetPhyclkVoltageByFreq] = {1, (0x26), (1)},
81 MSG_MAP(SetDppclkVoltageByFreq, PPSMC_MSG_SetDppclkVoltageByFreq, 1)[SMU_MSG_SetDppclkVoltageByFreq] = {1, (0x27), (1)},
82 MSG_MAP(SetSoftMinVcn, PPSMC_MSG_SetSoftMinVcn, 1)[SMU_MSG_SetSoftMinVcn] = {1, (0x28), (1)},
83 MSG_MAP(EnablePostCode, PPSMC_MSG_EnablePostCode, 1)[SMU_MSG_EnablePostCode] = {1, (0x29), (1)},
84 MSG_MAP(GetGfxclkFrequency, PPSMC_MSG_GetGfxclkFrequency, 1)[SMU_MSG_GetGfxclkFrequency] = {1, (0x2A), (1)},
85 MSG_MAP(GetFclkFrequency, PPSMC_MSG_GetFclkFrequency, 1)[SMU_MSG_GetFclkFrequency] = {1, (0x2B), (1)},
86 MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxclkFrequency, 1)[SMU_MSG_GetMinGfxclkFrequency] = {1, (0x2C), (1)},
87 MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxclkFrequency, 1)[SMU_MSG_GetMaxGfxclkFrequency] = {1, (0x2D), (1)},
88 MSG_MAP(SoftReset, PPSMC_MSG_SoftReset, 1)[SMU_MSG_SoftReset] = {1, (0x2E), (1)},
89 MSG_MAP(SetGfxCGPG, PPSMC_MSG_SetGfxCGPG, 1)[SMU_MSG_SetGfxCGPG] = {1, (0x2F), (1)},
90 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1)[SMU_MSG_SetSoftMaxGfxClk] = {1, (0x30), (1)},
91 MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1)[SMU_MSG_SetHardMinGfxClk] = {1, (0x31), (1)},
92 MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1)[SMU_MSG_SetSoftMaxSocclkByFreq] = {1, (0x32), (1)},
93 MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1)[SMU_MSG_SetSoftMaxFclkByFreq] = {1, (0x33), (1)},
94 MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1)[SMU_MSG_SetSoftMaxVcn] = {1, (0x34), (1)},
95 MSG_MAP(PowerGateMmHub, PPSMC_MSG_PowerGateMmHub, 1)[SMU_MSG_PowerGateMmHub] = {1, (0x35), (1)},
96 MSG_MAP(UpdatePmeRestore, PPSMC_MSG_UpdatePmeRestore, 1)[SMU_MSG_UpdatePmeRestore] = {1, (0x36), (1)},
97 MSG_MAP(GpuChangeState, PPSMC_MSG_GpuChangeState, 1)[SMU_MSG_GpuChangeState] = {1, (0x37), (1)},
98 MSG_MAP(SetPowerLimitPercentage, PPSMC_MSG_SetPowerLimitPercentage, 1)[SMU_MSG_SetPowerLimitPercentage] = {1, (0x38), (1)},
99 MSG_MAP(ForceGfxContentSave, PPSMC_MSG_ForceGfxContentSave, 1)[SMU_MSG_ForceGfxContentSave] = {1, (0x39), (1)},
100 MSG_MAP(EnableTmdp48MHzRefclkPwrDown, PPSMC_MSG_EnableTmdp48MHzRefclkPwrDown, 1)[SMU_MSG_EnableTmdp48MHzRefclkPwrDown] = {1, (0x3A), (1)},
101 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 1)[SMU_MSG_PowerDownJpeg] = {1, (0x3B), (1)},
102 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 1)[SMU_MSG_PowerUpJpeg] = {1, (0x3C), (1)},
103 MSG_MAP(PowerGateAtHub, PPSMC_MSG_PowerGateAtHub, 1)[SMU_MSG_PowerGateAtHub] = {1, (0x3D), (1)},
104 MSG_MAP(SetSoftMinJpeg, PPSMC_MSG_SetSoftMinJpeg, 1)[SMU_MSG_SetSoftMinJpeg] = {1, (0x3E), (1)},
105 MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1)[SMU_MSG_SetHardMinFclkByFreq] = {1, (0x3F), (1)},
106};
107
108static struct cmn2asic_mapping renoir_clk_map[SMU_CLK_COUNT] = {
109 CLK_MAP(GFXCLK, CLOCK_GFXCLK)[SMU_GFXCLK] = {1, (CLOCK_GFXCLK)},
110 CLK_MAP(SCLK, CLOCK_GFXCLK)[SMU_SCLK] = {1, (CLOCK_GFXCLK)},
111 CLK_MAP(SOCCLK, CLOCK_SOCCLK)[SMU_SOCCLK] = {1, (CLOCK_SOCCLK)},
112 CLK_MAP(UCLK, CLOCK_FCLK)[SMU_UCLK] = {1, (CLOCK_FCLK)},
113 CLK_MAP(MCLK, CLOCK_FCLK)[SMU_MCLK] = {1, (CLOCK_FCLK)},
114};
115
116static struct cmn2asic_mapping renoir_table_map[SMU_TABLE_COUNT] = {
117 TAB_MAP_VALID(WATERMARKS)[SMU_TABLE_WATERMARKS] = {1, 1},
118 TAB_MAP_INVALID(CUSTOM_DPM)[SMU_TABLE_CUSTOM_DPM] = {0, 2},
119 TAB_MAP_VALID(DPMCLOCKS)[SMU_TABLE_DPMCLOCKS] = {1, 4},
120 TAB_MAP_VALID(SMU_METRICS)[SMU_TABLE_SMU_METRICS] = {1, 7},
121};
122
123static struct cmn2asic_mapping renoir_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
124 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT)[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = {1, (0)},
125 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT)[PP_SMC_POWER_PROFILE_VIDEO] = {1, (2)},
126 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT)[PP_SMC_POWER_PROFILE_VR] = {1, (3)},
127 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT)[PP_SMC_POWER_PROFILE_COMPUTE] = {1, (4)},
128 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT)[PP_SMC_POWER_PROFILE_CUSTOM] = {1, (5)},
129};
130
131static int renoir_init_smc_tables(struct smu_context *smu)
132{
133 struct smu_table_context *smu_table = &smu->smu_table;
134 struct smu_table *tables = smu_table->tables;
135
136 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),do { tables[SMU_TABLE_WATERMARKS].size = sizeof(Watermarks_t)
; tables[SMU_TABLE_WATERMARKS].align = (1 << 12); tables
[SMU_TABLE_WATERMARKS].domain = 0x4; } while (0)
137 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM)do { tables[SMU_TABLE_WATERMARKS].size = sizeof(Watermarks_t)
; tables[SMU_TABLE_WATERMARKS].align = (1 << 12); tables
[SMU_TABLE_WATERMARKS].domain = 0x4; } while (0)
;
138 SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),do { tables[SMU_TABLE_DPMCLOCKS].size = sizeof(DpmClocks_t); tables
[SMU_TABLE_DPMCLOCKS].align = (1 << 12); tables[SMU_TABLE_DPMCLOCKS
].domain = 0x4; } while (0)
139 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM)do { tables[SMU_TABLE_DPMCLOCKS].size = sizeof(DpmClocks_t); tables
[SMU_TABLE_DPMCLOCKS].align = (1 << 12); tables[SMU_TABLE_DPMCLOCKS
].domain = 0x4; } while (0)
;
140 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),do { tables[SMU_TABLE_SMU_METRICS].size = sizeof(SmuMetrics_t
); tables[SMU_TABLE_SMU_METRICS].align = (1 << 12); tables
[SMU_TABLE_SMU_METRICS].domain = 0x4; } while (0)
141 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM)do { tables[SMU_TABLE_SMU_METRICS].size = sizeof(SmuMetrics_t
); tables[SMU_TABLE_SMU_METRICS].align = (1 << 12); tables
[SMU_TABLE_SMU_METRICS].domain = 0x4; } while (0)
;
142
143 smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL(0x0001 | 0x0004));
144 if (!smu_table->clocks_table)
145 goto err0_out;
146
147 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL(0x0001 | 0x0004));
148 if (!smu_table->metrics_table)
149 goto err1_out;
150 smu_table->metrics_time = 0;
151
152 smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL(0x0001 | 0x0004));
153 if (!smu_table->watermarks_table)
154 goto err2_out;
155
156 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_0);
157 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL(0x0001 | 0x0004));
158 if (!smu_table->gpu_metrics_table)
159 goto err3_out;
160
161 return 0;
162
163err3_out:
164 kfree(smu_table->watermarks_table);
165err2_out:
166 kfree(smu_table->metrics_table);
167err1_out:
168 kfree(smu_table->clocks_table);
169err0_out:
170 return -ENOMEM12;
171}
172
173/**
174 * This interface just for getting uclk ultimate freq and should't introduce
175 * other likewise function result in overmuch callback.
176 */
177static int renoir_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type clk_type,
178 uint32_t dpm_level, uint32_t *freq)
179{
180 DpmClocks_t *clk_table = smu->smu_table.clocks_table;
181
182 if (!clk_table || clk_type >= SMU_CLK_COUNT)
183 return -EINVAL22;
184
185 switch (clk_type) {
186 case SMU_SOCCLK:
187 if (dpm_level >= NUM_SOCCLK_DPM_LEVELS8)
188 return -EINVAL22;
189 *freq = clk_table->SocClocks[dpm_level].Freq;
190 break;
191 case SMU_UCLK:
192 case SMU_MCLK:
193 if (dpm_level >= NUM_FCLK_DPM_LEVELS4)
194 return -EINVAL22;
195 *freq = clk_table->FClocks[dpm_level].Freq;
196 break;
197 case SMU_DCEFCLK:
198 if (dpm_level >= NUM_DCFCLK_DPM_LEVELS8)
199 return -EINVAL22;
200 *freq = clk_table->DcfClocks[dpm_level].Freq;
201 break;
202 case SMU_FCLK:
203 if (dpm_level >= NUM_FCLK_DPM_LEVELS4)
204 return -EINVAL22;
205 *freq = clk_table->FClocks[dpm_level].Freq;
206 break;
207 default:
208 return -EINVAL22;
209 }
210
211 return 0;
212}
213
214static int renoir_get_profiling_clk_mask(struct smu_context *smu,
215 enum amd_dpm_forced_level level,
216 uint32_t *sclk_mask,
217 uint32_t *mclk_mask,
218 uint32_t *soc_mask)
219{
220
221 if (level
3.1
'level' is not equal to AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK
== AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
4
Taking false branch
222 if (sclk_mask)
223 *sclk_mask = 0;
224 } else if (level
4.1
'level' is equal to AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK
== AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
5
Taking true branch
225 if (mclk_mask
5.1
'mclk_mask' is non-null
)
6
Taking true branch
226 /* mclk levels are in reverse order */
227 *mclk_mask = NUM_MEMCLK_DPM_LEVELS4 - 1;
228 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
229 if(sclk_mask)
230 /* The sclk as gfxclk and has three level about max/min/current */
231 *sclk_mask = 3 - 1;
232
233 if(mclk_mask)
234 /* mclk levels are in reverse order */
235 *mclk_mask = 0;
236
237 if(soc_mask)
238 *soc_mask = NUM_SOCCLK_DPM_LEVELS8 - 1;
239 }
240
241 return 0;
7
Returning without writing to '*sclk_mask'
8
Returning zero, which participates in a condition later
242}
243
244static int renoir_get_dpm_ultimate_freq(struct smu_context *smu,
245 enum smu_clk_type clk_type,
246 uint32_t *min,
247 uint32_t *max)
248{
249 int ret = 0;
250 uint32_t mclk_mask, soc_mask;
251 uint32_t clock_limit;
252
253 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) {
254 switch (clk_type) {
255 case SMU_MCLK:
256 case SMU_UCLK:
257 clock_limit = smu->smu_table.boot_values.uclk;
258 break;
259 case SMU_GFXCLK:
260 case SMU_SCLK:
261 clock_limit = smu->smu_table.boot_values.gfxclk;
262 break;
263 case SMU_SOCCLK:
264 clock_limit = smu->smu_table.boot_values.socclk;
265 break;
266 default:
267 clock_limit = 0;
268 break;
269 }
270
271 /* clock in Mhz unit */
272 if (min)
273 *min = clock_limit / 100;
274 if (max)
275 *max = clock_limit / 100;
276
277 return 0;
278 }
279
280 if (max) {
281 ret = renoir_get_profiling_clk_mask(smu,
282 AMD_DPM_FORCED_LEVEL_PROFILE_PEAK,
283 NULL((void *)0),
284 &mclk_mask,
285 &soc_mask);
286 if (ret)
287 goto failed;
288
289 switch (clk_type) {
290 case SMU_GFXCLK:
291 case SMU_SCLK:
292 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMaxGfxclkFrequency, max);
293 if (ret) {
294 dev_err(smu->adev->dev, "Attempt to get max GX frequency from SMC Failed !\n")printf("drm:pid%d:%s *ERROR* " "Attempt to get max GX frequency from SMC Failed !\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__)
;
295 goto failed;
296 }
297 break;
298 case SMU_UCLK:
299 case SMU_FCLK:
300 case SMU_MCLK:
301 ret = renoir_get_dpm_clk_limited(smu, clk_type, mclk_mask, max);
302 if (ret)
303 goto failed;
304 break;
305 case SMU_SOCCLK:
306 ret = renoir_get_dpm_clk_limited(smu, clk_type, soc_mask, max);
307 if (ret)
308 goto failed;
309 break;
310 default:
311 ret = -EINVAL22;
312 goto failed;
313 }
314 }
315
316 if (min) {
317 switch (clk_type) {
318 case SMU_GFXCLK:
319 case SMU_SCLK:
320 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMinGfxclkFrequency, min);
321 if (ret) {
322 dev_err(smu->adev->dev, "Attempt to get min GX frequency from SMC Failed !\n")printf("drm:pid%d:%s *ERROR* " "Attempt to get min GX frequency from SMC Failed !\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__)
;
323 goto failed;
324 }
325 break;
326 case SMU_UCLK:
327 case SMU_FCLK:
328 case SMU_MCLK:
329 ret = renoir_get_dpm_clk_limited(smu, clk_type, NUM_MEMCLK_DPM_LEVELS4 - 1, min);
330 if (ret)
331 goto failed;
332 break;
333 case SMU_SOCCLK:
334 ret = renoir_get_dpm_clk_limited(smu, clk_type, 0, min);
335 if (ret)
336 goto failed;
337 break;
338 default:
339 ret = -EINVAL22;
340 goto failed;
341 }
342 }
343failed:
344 return ret;
345}
346
347static int renoir_print_clk_levels(struct smu_context *smu,
348 enum smu_clk_type clk_type, char *buf)
349{
350 int i, size = 0, ret = 0;
351 uint32_t cur_value = 0, value = 0, count = 0, min = 0, max = 0;
352 SmuMetrics_t metrics;
353 bool_Bool cur_value_match_level = false0;
354
355 memset(&metrics, 0, sizeof(metrics))__builtin_memset((&metrics), (0), (sizeof(metrics)));
356
357 ret = smu_cmn_get_metrics_table(smu, &metrics, false0);
358 if (ret)
359 return ret;
360
361 switch (clk_type) {
362 case SMU_GFXCLK:
363 case SMU_SCLK:
364 /* retirve table returned paramters unit is MHz */
365 cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
366 ret = renoir_get_dpm_ultimate_freq(smu, SMU_GFXCLK, &min, &max);
367 if (!ret) {
368 /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
369 if (cur_value == max)
370 i = 2;
371 else if (cur_value == min)
372 i = 0;
373 else
374 i = 1;
375
376 size += snprintf(buf + size, PAGE_SIZE(1 << 12) - size, "0: %uMhz %s\n", min,
377 i == 0 ? "*" : "");
378 size += snprintf(buf + size, PAGE_SIZE(1 << 12) - size, "1: %uMhz %s\n",
379 i == 1 ? cur_value : RENOIR_UMD_PSTATE_GFXCLK700,
380 i == 1 ? "*" : "");
381 size += snprintf(buf + size, PAGE_SIZE(1 << 12) - size, "2: %uMhz %s\n", max,
382 i == 2 ? "*" : "");
383 }
384 return size;
385 case SMU_SOCCLK:
386 count = NUM_SOCCLK_DPM_LEVELS8;
387 cur_value = metrics.ClockFrequency[CLOCK_SOCCLK];
388 break;
389 case SMU_MCLK:
390 count = NUM_MEMCLK_DPM_LEVELS4;
391 cur_value = metrics.ClockFrequency[CLOCK_FCLK];
392 break;
393 case SMU_DCEFCLK:
394 count = NUM_DCFCLK_DPM_LEVELS8;
395 cur_value = metrics.ClockFrequency[CLOCK_DCFCLK];
396 break;
397 case SMU_FCLK:
398 count = NUM_FCLK_DPM_LEVELS4;
399 cur_value = metrics.ClockFrequency[CLOCK_FCLK];
400 break;
401 default:
402 return -EINVAL22;
403 }
404
405 for (i = 0; i < count; i++) {
406 ret = renoir_get_dpm_clk_limited(smu, clk_type, i, &value);
407 if (ret)
408 return ret;
409 if (!value)
410 continue;
411 size += snprintf(buf + size, PAGE_SIZE(1 << 12) - size, "%d: %uMhz %s\n", i, value,
412 cur_value == value ? "*" : "");
413 if (cur_value == value)
414 cur_value_match_level = true1;
415 }
416
417 if (!cur_value_match_level)
418 size += snprintf(buf + size, PAGE_SIZE(1 << 12) - size, " %uMhz *\n", cur_value);
419
420 return size;
421}
422
423static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context *smu)
424{
425 enum amd_pm_state_type pm_type;
426 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
427
428 if (!smu_dpm_ctx->dpm_context ||
429 !smu_dpm_ctx->dpm_current_power_state)
430 return -EINVAL22;
431
432 switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
433 case SMU_STATE_UI_LABEL_BATTERY:
434 pm_type = POWER_STATE_TYPE_BATTERY;
435 break;
436 case SMU_STATE_UI_LABEL_BALLANCED:
437 pm_type = POWER_STATE_TYPE_BALANCED;
438 break;
439 case SMU_STATE_UI_LABEL_PERFORMANCE:
440 pm_type = POWER_STATE_TYPE_PERFORMANCE;
441 break;
442 default:
443 if (smu_dpm_ctx->dpm_current_power_state->classification.flags & SMU_STATE_CLASSIFICATION_FLAG_BOOT)
444 pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
445 else
446 pm_type = POWER_STATE_TYPE_DEFAULT;
447 break;
448 }
449
450 return pm_type;
451}
452
453static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool_Bool enable)
454{
455 int ret = 0;
456
457 if (enable) {
458 /* vcn dpm on is a prerequisite for vcn power gate messages */
459 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
460 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL((void *)0));
461 if (ret)
462 return ret;
463 }
464 } else {
465 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
466 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL((void *)0));
467 if (ret)
468 return ret;
469 }
470 }
471
472 return ret;
473}
474
475static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool_Bool enable)
476{
477 int ret = 0;
478
479 if (enable) {
480 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
481 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL((void *)0));
482 if (ret)
483 return ret;
484 }
485 } else {
486 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
487 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL((void *)0));
488 if (ret)
489 return ret;
490 }
491 }
492
493 return ret;
494}
495
496static int renoir_get_current_clk_freq_by_table(struct smu_context *smu,
497 enum smu_clk_type clk_type,
498 uint32_t *value)
499{
500 int ret = 0, clk_id = 0;
501 SmuMetrics_t metrics;
502
503 ret = smu_cmn_get_metrics_table(smu, &metrics, false0);
504 if (ret)
505 return ret;
506
507 clk_id = smu_cmn_to_asic_specific_index(smu,
508 CMN2ASIC_MAPPING_CLK,
509 clk_type);
510 if (clk_id < 0)
511 return clk_id;
512
513 *value = metrics.ClockFrequency[clk_id];
514
515 return ret;
516}
517
518static int renoir_force_dpm_limit_value(struct smu_context *smu, bool_Bool highest)
519{
520 int ret = 0, i = 0;
521 uint32_t min_freq, max_freq, force_freq;
522 enum smu_clk_type clk_type;
523
524 enum smu_clk_type clks[] = {
525 SMU_GFXCLK,
526 SMU_MCLK,
527 SMU_SOCCLK,
528 };
529
530 for (i = 0; i < ARRAY_SIZE(clks)(sizeof((clks)) / sizeof((clks)[0])); i++) {
531 clk_type = clks[i];
532 ret = renoir_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
533 if (ret)
534 return ret;
535
536 force_freq = highest ? max_freq : min_freq;
537 ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
538 if (ret)
539 return ret;
540 }
541
542 return ret;
543}
544
545static int renoir_unforce_dpm_levels(struct smu_context *smu) {
546
547 int ret = 0, i = 0;
548 uint32_t min_freq, max_freq;
549 enum smu_clk_type clk_type;
550
551 struct clk_feature_map {
552 enum smu_clk_type clk_type;
553 uint32_t feature;
554 } clk_feature_map[] = {
555 {SMU_GFXCLK, SMU_FEATURE_DPM_GFXCLK_BIT},
556 {SMU_MCLK, SMU_FEATURE_DPM_UCLK_BIT},
557 {SMU_SOCCLK, SMU_FEATURE_DPM_SOCCLK_BIT},
558 };
559
560 for (i = 0; i < ARRAY_SIZE(clk_feature_map)(sizeof((clk_feature_map)) / sizeof((clk_feature_map)[0])); i++) {
561 if (!smu_cmn_feature_is_enabled(smu, clk_feature_map[i].feature))
562 continue;
563
564 clk_type = clk_feature_map[i].clk_type;
565
566 ret = renoir_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
567 if (ret)
568 return ret;
569
570 ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
571 if (ret)
572 return ret;
573 }
574
575 return ret;
576}
577
578static int renoir_get_gpu_temperature(struct smu_context *smu, uint32_t *value)
579{
580 int ret = 0;
581 SmuMetrics_t metrics;
582
583 if (!value)
584 return -EINVAL22;
585
586 ret = smu_cmn_get_metrics_table(smu, &metrics, false0);
587 if (ret)
588 return ret;
589
590 *value = (metrics.GfxTemperature / 100) *
591 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES1000;
592
593 return 0;
594}
595
596static int renoir_get_current_activity_percent(struct smu_context *smu,
597 enum amd_pp_sensors sensor,
598 uint32_t *value)
599{
600 int ret = 0;
601 SmuMetrics_t metrics;
602
603 if (!value)
604 return -EINVAL22;
605
606 ret = smu_cmn_get_metrics_table(smu, &metrics, false0);
607 if (ret)
608 return ret;
609
610 switch (sensor) {
611 case AMDGPU_PP_SENSOR_GPU_LOAD:
612 *value = metrics.AverageGfxActivity / 100;
613 break;
614 default:
615 dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n")printf("drm:pid%d:%s *ERROR* " "Invalid sensor for retrieving clock activity\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__)
;
616 return -EINVAL22;
617 }
618
619 return 0;
620}
621
622static int renoir_get_vddc(struct smu_context *smu, uint32_t *value,
623 unsigned int index)
624{
625 int ret = 0;
626 SmuMetrics_t metrics;
627
628 if (index >= 2)
629 return -EINVAL22;
630
631 if (!value)
632 return -EINVAL22;
633
634 ret = smu_cmn_get_metrics_table(smu, &metrics, false0);
635 if (ret)
636 return ret;
637
638 *value = metrics.Voltage[index];
639
640 return 0;
641}
642
643static int renoir_get_power(struct smu_context *smu, uint32_t *value)
644{
645 int ret = 0;
646 SmuMetrics_t metrics;
647
648 if (!value)
649 return -EINVAL22;
650
651 ret = smu_cmn_get_metrics_table(smu, &metrics, false0);
652 if (ret)
653 return ret;
654
655 *value = metrics.CurrentSocketPower << 8;
656
657 return 0;
658}
659
660/**
661 * This interface get dpm clock table for dc
662 */
663static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table)
664{
665 DpmClocks_t *table = smu->smu_table.clocks_table;
666 int i;
667
668 if (!clock_table || !table)
669 return -EINVAL22;
670
671 for (i = 0; i < NUM_DCFCLK_DPM_LEVELS8; i++) {
672 clock_table->DcfClocks[i].Freq = table->DcfClocks[i].Freq;
673 clock_table->DcfClocks[i].Vol = table->DcfClocks[i].Vol;
674 }
675
676 for (i = 0; i < NUM_SOCCLK_DPM_LEVELS8; i++) {
677 clock_table->SocClocks[i].Freq = table->SocClocks[i].Freq;
678 clock_table->SocClocks[i].Vol = table->SocClocks[i].Vol;
679 }
680
681 for (i = 0; i < NUM_FCLK_DPM_LEVELS4; i++) {
682 clock_table->FClocks[i].Freq = table->FClocks[i].Freq;
683 clock_table->FClocks[i].Vol = table->FClocks[i].Vol;
684 }
685
686 for (i = 0; i< NUM_MEMCLK_DPM_LEVELS4; i++) {
687 clock_table->MemClocks[i].Freq = table->MemClocks[i].Freq;
688 clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol;
689 }
690
691 return 0;
692}
693
694static int renoir_force_clk_levels(struct smu_context *smu,
695 enum smu_clk_type clk_type, uint32_t mask)
696{
697
698 int ret = 0 ;
699 uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
700
701 soft_min_level = mask ? (ffs(mask) - 1) : 0;
702 soft_max_level = mask ? (fls(mask) - 1) : 0;
703
704 switch (clk_type) {
705 case SMU_GFXCLK:
706 case SMU_SCLK:
707 if (soft_min_level > 2 || soft_max_level > 2) {
708 dev_info(smu->adev->dev, "Currently sclk only support 3 levels on APU\n")do { } while(0);
709 return -EINVAL22;
710 }
711
712 ret = renoir_get_dpm_ultimate_freq(smu, SMU_GFXCLK, &min_freq, &max_freq);
713 if (ret)
714 return ret;
715 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
716 soft_max_level == 0 ? min_freq :
717 soft_max_level == 1 ? RENOIR_UMD_PSTATE_GFXCLK700 : max_freq,
718 NULL((void *)0));
719 if (ret)
720 return ret;
721 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
722 soft_min_level == 2 ? max_freq :
723 soft_min_level == 1 ? RENOIR_UMD_PSTATE_GFXCLK700 : min_freq,
724 NULL((void *)0));
725 if (ret)
726 return ret;
727 break;
728 case SMU_SOCCLK:
729 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_min_level, &min_freq);
730 if (ret)
731 return ret;
732 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_max_level, &max_freq);
733 if (ret)
734 return ret;
735 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxSocclkByFreq, max_freq, NULL((void *)0));
736 if (ret)
737 return ret;
738 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinSocclkByFreq, min_freq, NULL((void *)0));
739 if (ret)
740 return ret;
741 break;
742 case SMU_MCLK:
743 case SMU_FCLK:
744 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_min_level, &min_freq);
745 if (ret)
746 return ret;
747 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_max_level, &max_freq);
748 if (ret)
749 return ret;
750 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxFclkByFreq, max_freq, NULL((void *)0));
751 if (ret)
752 return ret;
753 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min_freq, NULL((void *)0));
754 if (ret)
755 return ret;
756 break;
757 default:
758 break;
759 }
760
761 return ret;
762}
763
764static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
765{
766 int workload_type, ret;
767 uint32_t profile_mode = input[size];
768
769 if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
770 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode)printf("drm:pid%d:%s *ERROR* " "Invalid power profile mode %d\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , profile_mode
)
;
771 return -EINVAL22;
772 }
773
774 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
775 workload_type = smu_cmn_to_asic_specific_index(smu,
776 CMN2ASIC_MAPPING_WORKLOAD,
777 profile_mode);
778 if (workload_type < 0) {
779 /*
780 * TODO: If some case need switch to powersave/default power mode
781 * then can consider enter WORKLOAD_COMPUTE/WORKLOAD_CUSTOM for power saving.
782 */
783 dev_err_once(smu->adev->dev, "Unsupported power profile mode %d on RENOIR\n", profile_mode)printf("drm:pid%d:%s *ERROR* " "Unsupported power profile mode %d on RENOIR\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , profile_mode
)
;
784 return -EINVAL22;
785 }
786
787 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
788 1 << workload_type,
789 NULL((void *)0));
790 if (ret) {
791 dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type)printf("drm:pid%d:%s *ERROR* " "Fail to set workload type %d\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , workload_type
)
;
792 return ret;
793 }
794
795 smu->power_profile_mode = profile_mode;
796
797 return 0;
798}
799
800static int renoir_set_peak_clock_by_device(struct smu_context *smu)
801{
802 int ret = 0;
803 uint32_t sclk_freq = 0, uclk_freq = 0;
804
805 ret = renoir_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL((void *)0), &sclk_freq);
806 if (ret)
807 return ret;
808
809 ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq);
810 if (ret)
811 return ret;
812
813 ret = renoir_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL((void *)0), &uclk_freq);
814 if (ret)
815 return ret;
816
817 ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq);
818 if (ret)
819 return ret;
820
821 return ret;
822}
823
824static int renoir_set_performance_level(struct smu_context *smu,
825 enum amd_dpm_forced_level level)
826{
827 int ret = 0;
828 uint32_t sclk_mask, mclk_mask, soc_mask;
1
'sclk_mask' declared without an initial value
829
830 switch (level) {
2
Control jumps to 'case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:' at line 892
831 case AMD_DPM_FORCED_LEVEL_HIGH:
832 ret = renoir_force_dpm_limit_value(smu, true1);
833 break;
834 case AMD_DPM_FORCED_LEVEL_LOW:
835 ret = renoir_force_dpm_limit_value(smu, false0);
836 break;
837 case AMD_DPM_FORCED_LEVEL_AUTO:
838 ret = renoir_unforce_dpm_levels(smu);
839 break;
840 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
841 ret = smu_cmn_send_smc_msg_with_param(smu,
842 SMU_MSG_SetHardMinGfxClk,
843 RENOIR_UMD_PSTATE_GFXCLK700,
844 NULL((void *)0));
845 if (ret)
846 return ret;
847 ret = smu_cmn_send_smc_msg_with_param(smu,
848 SMU_MSG_SetHardMinFclkByFreq,
849 RENOIR_UMD_PSTATE_FCLK800,
850 NULL((void *)0));
851 if (ret)
852 return ret;
853 ret = smu_cmn_send_smc_msg_with_param(smu,
854 SMU_MSG_SetHardMinSocclkByFreq,
855 RENOIR_UMD_PSTATE_SOCCLK678,
856 NULL((void *)0));
857 if (ret)
858 return ret;
859 ret = smu_cmn_send_smc_msg_with_param(smu,
860 SMU_MSG_SetHardMinVcn,
861 RENOIR_UMD_PSTATE_VCNCLK0x022D01D8,
862 NULL((void *)0));
863 if (ret)
864 return ret;
865
866 ret = smu_cmn_send_smc_msg_with_param(smu,
867 SMU_MSG_SetSoftMaxGfxClk,
868 RENOIR_UMD_PSTATE_GFXCLK700,
869 NULL((void *)0));
870 if (ret)
871 return ret;
872 ret = smu_cmn_send_smc_msg_with_param(smu,
873 SMU_MSG_SetSoftMaxFclkByFreq,
874 RENOIR_UMD_PSTATE_FCLK800,
875 NULL((void *)0));
876 if (ret)
877 return ret;
878 ret = smu_cmn_send_smc_msg_with_param(smu,
879 SMU_MSG_SetSoftMaxSocclkByFreq,
880 RENOIR_UMD_PSTATE_SOCCLK678,
881 NULL((void *)0));
882 if (ret)
883 return ret;
884 ret = smu_cmn_send_smc_msg_with_param(smu,
885 SMU_MSG_SetSoftMaxVcn,
886 RENOIR_UMD_PSTATE_VCNCLK0x022D01D8,
887 NULL((void *)0));
888 if (ret)
889 return ret;
890 break;
891 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
892 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
893 ret = renoir_get_profiling_clk_mask(smu, level,
3
Calling 'renoir_get_profiling_clk_mask'
9
Returning from 'renoir_get_profiling_clk_mask'
894 &sclk_mask,
895 &mclk_mask,
896 &soc_mask);
897 if (ret
9.1
'ret' is 0
)
10
Taking false branch
898 return ret;
899 renoir_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask);
11
The right operand of '<<' is a garbage value
900 renoir_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
901 renoir_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
902 break;
903 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
904 ret = renoir_set_peak_clock_by_device(smu);
905 break;
906 case AMD_DPM_FORCED_LEVEL_MANUAL:
907 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
908 default:
909 break;
910 }
911 return ret;
912}
913
914/* save watermark settings into pplib smu structure,
915 * also pass data to smu controller
916 */
917static int renoir_set_watermarks_table(
918 struct smu_context *smu,
919 struct pp_smu_wm_range_sets *clock_ranges)
920{
921 Watermarks_t *table = smu->smu_table.watermarks_table;
922 int ret = 0;
923 int i;
924
925 if (clock_ranges) {
926 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES4 ||
927 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES4)
928 return -EINVAL22;
929
930 /* save into smu->smu_table.tables[SMU_TABLE_WATERMARKS]->cpu_addr*/
931 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
932 table->WatermarkRow[WM_DCFCLK][i].MinClock =
933 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
934 table->WatermarkRow[WM_DCFCLK][i].MaxClock =
935 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
936 table->WatermarkRow[WM_DCFCLK][i].MinMclk =
937 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
938 table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
939 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
940
941 table->WatermarkRow[WM_DCFCLK][i].WmSetting =
942 clock_ranges->reader_wm_sets[i].wm_inst;
943 table->WatermarkRow[WM_DCFCLK][i].WmType =
944 clock_ranges->reader_wm_sets[i].wm_type;
945 }
946
947 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
948 table->WatermarkRow[WM_SOCCLK][i].MinClock =
949 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
950 table->WatermarkRow[WM_SOCCLK][i].MaxClock =
951 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
952 table->WatermarkRow[WM_SOCCLK][i].MinMclk =
953 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
954 table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
955 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
956
957 table->WatermarkRow[WM_SOCCLK][i].WmSetting =
958 clock_ranges->writer_wm_sets[i].wm_inst;
959 table->WatermarkRow[WM_SOCCLK][i].WmType =
960 clock_ranges->writer_wm_sets[i].wm_type;
961 }
962
963 smu->watermarks_bitmap |= WATERMARKS_EXIST(1 << 0);
964 }
965
966 /* pass data to smu controller */
967 if ((smu->watermarks_bitmap & WATERMARKS_EXIST(1 << 0)) &&
968 !(smu->watermarks_bitmap & WATERMARKS_LOADED(1 << 1))) {
969 ret = smu_cmn_write_watermarks_table(smu);
970 if (ret) {
971 dev_err(smu->adev->dev, "Failed to update WMTABLE!")printf("drm:pid%d:%s *ERROR* " "Failed to update WMTABLE!", (
{struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__)
;
972 return ret;
973 }
974 smu->watermarks_bitmap |= WATERMARKS_LOADED(1 << 1);
975 }
976
977 return 0;
978}
979
980static int renoir_get_power_profile_mode(struct smu_context *smu,
981 char *buf)
982{
983 static const char *profile_name[] = {
984 "BOOTUP_DEFAULT",
985 "3D_FULL_SCREEN",
986 "POWER_SAVING",
987 "VIDEO",
988 "VR",
989 "COMPUTE",
990 "CUSTOM"};
991 uint32_t i, size = 0;
992 int16_t workload_type = 0;
993
994 if (!buf)
995 return -EINVAL22;
996
997 for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
998 /*
999 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1000 * Not all profile modes are supported on arcturus.
1001 */
1002 workload_type = smu_cmn_to_asic_specific_index(smu,
1003 CMN2ASIC_MAPPING_WORKLOAD,
1004 i);
1005 if (workload_type < 0)
1006 continue;
1007
1008 size += snprintf(buf + size, PAGE_SIZE(1 << 12) - size, "%2d %14s%s\n",
1009 i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1010 }
1011
1012 return size;
1013}
1014
1015static int renoir_read_sensor(struct smu_context *smu,
1016 enum amd_pp_sensors sensor,
1017 void *data, uint32_t *size)
1018{
1019 int ret = 0;
1020
1021 if (!data || !size)
1022 return -EINVAL22;
1023
1024 mutex_lock(&smu->sensor_lock)rw_enter_write(&smu->sensor_lock);
1025 switch (sensor) {
1026 case AMDGPU_PP_SENSOR_GPU_LOAD:
1027 ret = renoir_get_current_activity_percent(smu, sensor, (uint32_t *)data);
1028 *size = 4;
1029 break;
1030 case AMDGPU_PP_SENSOR_GPU_TEMP:
1031 ret = renoir_get_gpu_temperature(smu, (uint32_t *)data);
1032 *size = 4;
1033 break;
1034 case AMDGPU_PP_SENSOR_GFX_MCLK:
1035 ret = renoir_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
1036 *(uint32_t *)data *= 100;
1037 *size = 4;
1038 break;
1039 case AMDGPU_PP_SENSOR_GFX_SCLK:
1040 ret = renoir_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
1041 *(uint32_t *)data *= 100;
1042 *size = 4;
1043 break;
1044 case AMDGPU_PP_SENSOR_VDDGFX:
1045 ret = renoir_get_vddc(smu, (uint32_t *)data, 0);
1046 *size = 4;
1047 break;
1048 case AMDGPU_PP_SENSOR_VDDNB:
1049 ret = renoir_get_vddc(smu, (uint32_t *)data, 1);
1050 *size = 4;
1051 break;
1052 case AMDGPU_PP_SENSOR_GPU_POWER:
1053 ret = renoir_get_power(smu, (uint32_t *)data);
1054 *size = 4;
1055 break;
1056 default:
1057 ret = -EOPNOTSUPP45;
1058 break;
1059 }
1060 mutex_unlock(&smu->sensor_lock)rw_exit_write(&smu->sensor_lock);
1061
1062 return ret;
1063}
1064
1065static bool_Bool renoir_is_dpm_running(struct smu_context *smu)
1066{
1067 struct amdgpu_device *adev = smu->adev;
1068
1069 /*
1070 * Until now, the pmfw hasn't exported the interface of SMU
1071 * feature mask to APU SKU so just force on all the feature
1072 * at early initial stage.
1073 */
1074 if (adev->in_suspend)
1075 return false0;
1076 else
1077 return true1;
1078
1079}
1080
1081static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
1082 void **table)
1083{
1084 struct smu_table_context *smu_table = &smu->smu_table;
1085 struct gpu_metrics_v2_0 *gpu_metrics =
1086 (struct gpu_metrics_v2_0 *)smu_table->gpu_metrics_table;
1087 SmuMetrics_t metrics;
1088 int ret = 0;
1089
1090 ret = smu_cmn_get_metrics_table(smu, &metrics, true1);
1091 if (ret)
1092 return ret;
1093
1094 smu_v12_0_init_gpu_metrics_v2_0(gpu_metrics);
1095
1096 gpu_metrics->temperature_gfx = metrics.GfxTemperature;
1097 gpu_metrics->temperature_soc = metrics.SocTemperature;
1098 memcpy(&gpu_metrics->temperature_core[0],__builtin_memcpy((&gpu_metrics->temperature_core[0]), (
&metrics.CoreTemperature[0]), (sizeof(uint16_t) * 8))
1099 &metrics.CoreTemperature[0],__builtin_memcpy((&gpu_metrics->temperature_core[0]), (
&metrics.CoreTemperature[0]), (sizeof(uint16_t) * 8))
1100 sizeof(uint16_t) * 8)__builtin_memcpy((&gpu_metrics->temperature_core[0]), (
&metrics.CoreTemperature[0]), (sizeof(uint16_t) * 8))
;
1101 gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0];
1102 gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1];
1103
1104 gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
1105 gpu_metrics->average_mm_activity = metrics.AverageUvdActivity;
1106
1107 gpu_metrics->average_socket_power = metrics.CurrentSocketPower;
1108 gpu_metrics->average_cpu_power = metrics.Power[0];
1109 gpu_metrics->average_soc_power = metrics.Power[1];
1110 memcpy(&gpu_metrics->average_core_power[0],__builtin_memcpy((&gpu_metrics->average_core_power[0])
, (&metrics.CorePower[0]), (sizeof(uint16_t) * 8))
1111 &metrics.CorePower[0],__builtin_memcpy((&gpu_metrics->average_core_power[0])
, (&metrics.CorePower[0]), (sizeof(uint16_t) * 8))
1112 sizeof(uint16_t) * 8)__builtin_memcpy((&gpu_metrics->average_core_power[0])
, (&metrics.CorePower[0]), (sizeof(uint16_t) * 8))
;
1113
1114 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
1115 gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
1116 gpu_metrics->average_fclk_frequency = metrics.AverageFclkFrequency;
1117 gpu_metrics->average_vclk_frequency = metrics.AverageVclkFrequency;
1118
1119 gpu_metrics->current_gfxclk = metrics.ClockFrequency[CLOCK_GFXCLK];
1120 gpu_metrics->current_socclk = metrics.ClockFrequency[CLOCK_SOCCLK];
1121 gpu_metrics->current_uclk = metrics.ClockFrequency[CLOCK_UMCCLK];
1122 gpu_metrics->current_fclk = metrics.ClockFrequency[CLOCK_FCLK];
1123 gpu_metrics->current_vclk = metrics.ClockFrequency[CLOCK_VCLK];
1124 gpu_metrics->current_dclk = metrics.ClockFrequency[CLOCK_DCLK];
1125 memcpy(&gpu_metrics->current_coreclk[0],__builtin_memcpy((&gpu_metrics->current_coreclk[0]), (
&metrics.CoreFrequency[0]), (sizeof(uint16_t) * 8))
1126 &metrics.CoreFrequency[0],__builtin_memcpy((&gpu_metrics->current_coreclk[0]), (
&metrics.CoreFrequency[0]), (sizeof(uint16_t) * 8))
1127 sizeof(uint16_t) * 8)__builtin_memcpy((&gpu_metrics->current_coreclk[0]), (
&metrics.CoreFrequency[0]), (sizeof(uint16_t) * 8))
;
1128 gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0];
1129 gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1];
1130
1131 gpu_metrics->throttle_status = metrics.ThrottlerStatus;
1132
1133 gpu_metrics->fan_pwm = metrics.FanPwm;
1134
1135 *table = (void *)gpu_metrics;
1136
1137 return sizeof(struct gpu_metrics_v2_0);
1138}
1139
1140static const struct pptable_funcs renoir_ppt_funcs = {
1141 .set_power_state = NULL((void *)0),
1142 .print_clk_levels = renoir_print_clk_levels,
1143 .get_current_power_state = renoir_get_current_power_state,
1144 .dpm_set_vcn_enable = renoir_dpm_set_vcn_enable,
1145 .dpm_set_jpeg_enable = renoir_dpm_set_jpeg_enable,
1146 .force_clk_levels = renoir_force_clk_levels,
1147 .set_power_profile_mode = renoir_set_power_profile_mode,
1148 .set_performance_level = renoir_set_performance_level,
1149 .get_dpm_clock_table = renoir_get_dpm_clock_table,
1150 .set_watermarks_table = renoir_set_watermarks_table,
1151 .get_power_profile_mode = renoir_get_power_profile_mode,
1152 .read_sensor = renoir_read_sensor,
1153 .check_fw_status = smu_v12_0_check_fw_status,
1154 .check_fw_version = smu_v12_0_check_fw_version,
1155 .powergate_sdma = smu_v12_0_powergate_sdma,
1156 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
1157 .send_smc_msg = smu_cmn_send_smc_msg,
1158 .set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
1159 .gfx_off_control = smu_v12_0_gfx_off_control,
1160 .get_gfx_off_status = smu_v12_0_get_gfxoff_status,
1161 .init_smc_tables = renoir_init_smc_tables,
1162 .fini_smc_tables = smu_v12_0_fini_smc_tables,
1163 .set_default_dpm_table = smu_v12_0_set_default_dpm_tables,
1164 .get_enabled_mask = smu_cmn_get_enabled_mask,
1165 .feature_is_enabled = smu_cmn_feature_is_enabled,
1166 .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
1167 .get_dpm_ultimate_freq = renoir_get_dpm_ultimate_freq,
1168 .mode2_reset = smu_v12_0_mode2_reset,
1169 .set_soft_freq_limited_range = smu_v12_0_set_soft_freq_limited_range,
1170 .set_driver_table_location = smu_v12_0_set_driver_table_location,
1171 .is_dpm_running = renoir_is_dpm_running,
1172 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
1173 .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
1174 .get_gpu_metrics = renoir_get_gpu_metrics,
1175};
1176
1177void renoir_set_ppt_funcs(struct smu_context *smu)
1178{
1179 smu->ppt_funcs = &renoir_ppt_funcs;
1180 smu->message_map = renoir_message_map;
1181 smu->clock_map = renoir_clk_map;
1182 smu->table_map = renoir_table_map;
1183 smu->workload_map = renoir_workload_map;
1184 smu->smc_driver_if_version = SMU12_DRIVER_IF_VERSION14;
1185 smu->is_apu = true1;
1186}