Bug Summary

File:dev/pci/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c
Warning:line 1831, column 11
Value stored to 'hi_sidd' during its initialization is never read

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 vegam_smumgr.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/powerplay/smumgr/vegam_smumgr.c
1/*
2 * Copyright 2017 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#include "pp_debug.h"
24#include "smumgr.h"
25#include "smu_ucode_xfer_vi.h"
26#include "vegam_smumgr.h"
27#include "smu/smu_7_1_3_d.h"
28#include "smu/smu_7_1_3_sh_mask.h"
29#include "gmc/gmc_8_1_d.h"
30#include "gmc/gmc_8_1_sh_mask.h"
31#include "oss/oss_3_0_d.h"
32#include "gca/gfx_8_0_d.h"
33#include "bif/bif_5_0_d.h"
34#include "bif/bif_5_0_sh_mask.h"
35#include "ppatomctrl.h"
36#include "cgs_common.h"
37#include "smu7_ppsmc.h"
38
39#include "smu7_dyn_defaults.h"
40
41#include "smu7_hwmgr.h"
42#include "hardwaremanager.h"
43#include "atombios.h"
44#include "pppcielanes.h"
45
46#include "dce/dce_11_2_d.h"
47#include "dce/dce_11_2_sh_mask.h"
48
49#define PPVEGAM_TARGETACTIVITY_DFLT50 50
50
51#define VOLTAGE_VID_OFFSET_SCALE1625 625
52#define VOLTAGE_VID_OFFSET_SCALE2100 100
53#define POWERTUNE_DEFAULT_SET_MAX1 1
54#define VDDC_VDDCI_DELTA200 200
55#define MC_CG_ARB_FREQ_F10x0b 0x0b
56
57#define STRAP_ASIC_RO_LSB2168 2168
58#define STRAP_ASIC_RO_MSB2175 2175
59
60#define PPSMC_MSG_ApplyAvfsCksOffVoltage((uint16_t) 0x415) ((uint16_t) 0x415)
61#define PPSMC_MSG_EnableModeSwitchRLCNotification((uint16_t) 0x305) ((uint16_t) 0x305)
62
63static const struct vegam_pt_defaults
64vegam_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX1] = {
65 /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt,
66 * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */
67 { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
68 { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61},
69 { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } },
70};
71
72static const sclkFcwRange_t Range_Table[NUM_SCLK_RANGE8] = {
73 {VCO_2_43, POSTDIV_DIV_BY_164, 75, 160, 112},
74 {VCO_3_61, POSTDIV_DIV_BY_164, 112, 224, 160},
75 {VCO_2_43, POSTDIV_DIV_BY_83, 75, 160, 112},
76 {VCO_3_61, POSTDIV_DIV_BY_83, 112, 224, 160},
77 {VCO_2_43, POSTDIV_DIV_BY_42, 75, 160, 112},
78 {VCO_3_61, POSTDIV_DIV_BY_42, 112, 216, 160},
79 {VCO_2_43, POSTDIV_DIV_BY_21, 75, 160, 108},
80 {VCO_3_61, POSTDIV_DIV_BY_21, 112, 216, 160} };
81
82static int vegam_smu_init(struct pp_hwmgr *hwmgr)
83{
84 struct vegam_smumgr *smu_data;
85
86 smu_data = kzalloc(sizeof(struct vegam_smumgr), GFP_KERNEL(0x0001 | 0x0004));
87 if (smu_data == NULL((void *)0))
88 return -ENOMEM12;
89
90 hwmgr->smu_backend = smu_data;
91
92 if (smu7_init(hwmgr)) {
93 kfree(smu_data);
94 return -EINVAL22;
95 }
96
97 return 0;
98}
99
100static int vegam_start_smu_in_protection_mode(struct pp_hwmgr *hwmgr)
101{
102 int result = 0;
103
104 /* Wait for smc boot up */
105 /* PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0) */
106
107 /* Assert reset */
108 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
109 SMC_SYSCON_RESET_CNTL, rst_reg, 1)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
;
110
111 result = smu7_upload_smu_firmware_image(hwmgr);
112 if (result != 0)
113 return result;
114
115 /* Clear status */
116 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMU_STATUS, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe0003088,0))
;
117
118 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000004,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000004))) & ~0x1) | (0x1 &
((0) << 0x0)))))
119 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000004,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000004))) & ~0x1) | (0x1 &
((0) << 0x0)))))
;
120
121 /* De-assert reset */
122 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((0) << 0x0)))))
123 SMC_SYSCON_RESET_CNTL, rst_reg, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((0) << 0x0)))))
;
124
125
126 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1)phm_wait_on_indirect_register(hwmgr, 0x1AC, 0xc0000004, (1) <<
0x10, 0x10000)
;
127
128
129 /* Call Test SMU message with 0x20000 offset to trigger SMU start */
130 smu7_send_msg_to_smc_offset(hwmgr);
131
132 /* Wait done bit to be set */
133 /* Check pass/failed indicator */
134
135 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, SMU_STATUS, SMU_DONE, 0)phm_wait_for_indirect_register_unequal(hwmgr, 0x1AC, 0xe0003088
, (0) << 0x0, 0x1)
;
136
137 if (1 != PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe0003088))) & 0x2) >>
0x1)
138 SMU_STATUS, SMU_PASS)((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe0003088))) & 0x2) >>
0x1)
)
139 PP_ASSERT_WITH_CODE(false, "SMU Firmware start failed!", return -1)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "SMU Firmware start failed!"
); return -1; } } while (0)
;
140
141 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixFIRMWARE_FLAGS, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x3f000,0))
;
142
143 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
144 SMC_SYSCON_RESET_CNTL, rst_reg, 1)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
;
145
146 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((0) << 0x0)))))
147 SMC_SYSCON_RESET_CNTL, rst_reg, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((0) << 0x0)))))
;
148
149 /* Wait for firmware to initialize */
150 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1)phm_wait_on_indirect_register(hwmgr, 0x1AC, 0x3f000, (1) <<
0x0, 0x1)
;
151
152 return result;
153}
154
155static int vegam_start_smu_in_non_protection_mode(struct pp_hwmgr *hwmgr)
156{
157 int result = 0;
158
159 /* wait for smc boot up */
160 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0)phm_wait_for_indirect_register_unequal(hwmgr, 0x1AC, 0xc0000004
, (0) << 0x7, 0x80)
;
161
162 /* Clear firmware interrupt enable flag */
163 /* PHM_WRITE_VFPF_INDIRECT_FIELD(pSmuMgr, SMC_IND, SMC_SYSCON_MISC_CNTL, pre_fetcher_en, 1); */
164 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x3f000,0))
165 ixFIRMWARE_FLAGS, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x3f000,0))
;
166
167 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
168 SMC_SYSCON_RESET_CNTL,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
169 rst_reg, 1)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((1) << 0x0)))))
;
170
171 result = smu7_upload_smu_firmware_image(hwmgr);
172 if (result != 0)
173 return result;
174
175 /* Set smc instruct start point at 0x0 */
176 smu7_program_jump_on_start(hwmgr);
177
178 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000004,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000004))) & ~0x1) | (0x1 &
((0) << 0x0)))))
179 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000004,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000004))) & ~0x1) | (0x1 &
((0) << 0x0)))))
;
180
181 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((0) << 0x0)))))
182 SMC_SYSCON_RESET_CNTL, rst_reg, 0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x80000000,((((((struct cgs_device
*)hwmgr->device)->ops->read_ind_register(hwmgr->
device,CGS_IND_REG__SMC,0x80000000))) & ~0x1) | (0x1 &
((0) << 0x0)))))
;
183
184 /* Wait for firmware to initialize */
185
186 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,phm_wait_on_indirect_register(hwmgr, 0x1AC, 0x3f000, (1) <<
0x0, 0x1)
187 FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1)phm_wait_on_indirect_register(hwmgr, 0x1AC, 0x3f000, (1) <<
0x0, 0x1)
;
188
189 return result;
190}
191
192static int vegam_start_smu(struct pp_hwmgr *hwmgr)
193{
194 int result = 0;
195 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
196
197 /* Only start SMC if SMC RAM is not running */
198 if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) {
199 smu_data->protected_mode = (uint8_t)(PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe00030a4))) & 0x10000
) >> 0x10)
200 CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE)((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe00030a4))) & 0x10000
) >> 0x10)
);
201 smu_data->smu7_data.security_hard_key = (uint8_t)(PHM_READ_VFPF_INDIRECT_FIELD(((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe00030a4))) & 0x20000
) >> 0x11)
202 hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL)((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xe00030a4))) & 0x20000
) >> 0x11)
);
203
204 /* Check if SMU is running in protected mode */
205 if (smu_data->protected_mode == 0)
206 result = vegam_start_smu_in_non_protection_mode(hwmgr);
207 else
208 result = vegam_start_smu_in_protection_mode(hwmgr);
209
210 if (result != 0)
211 PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Failed to load SMU ucode."
); return result; } } while (0)
;
212 }
213
214 /* Setup SoftRegsStart here for register lookup in case DummyBackEnd is used and ProcessFirmwareHeader is not executed */
215 smu7_read_smc_sram_dword(hwmgr,
216 SMU7_FIRMWARE_HEADER_LOCATION0x20000 + offsetof(SMU75_Firmware_Header, SoftRegisters)__builtin_offsetof(SMU75_Firmware_Header, SoftRegisters),
217 &(smu_data->smu7_data.soft_regs_start),
218 0x40000);
219
220 result = smu7_request_smu_load_fw(hwmgr);
221
222 return result;
223}
224
225static int vegam_process_firmware_header(struct pp_hwmgr *hwmgr)
226{
227 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
228 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
229 uint32_t tmp;
230 int result;
231 bool_Bool error = false0;
232
233 result = smu7_read_smc_sram_dword(hwmgr,
234 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
235 offsetof(SMU75_Firmware_Header, DpmTable)__builtin_offsetof(SMU75_Firmware_Header, DpmTable),
236 &tmp, SMC_RAM_END0x40000);
237
238 if (0 == result)
239 smu_data->smu7_data.dpm_table_start = tmp;
240
241 error |= (0 != result);
242
243 result = smu7_read_smc_sram_dword(hwmgr,
244 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
245 offsetof(SMU75_Firmware_Header, SoftRegisters)__builtin_offsetof(SMU75_Firmware_Header, SoftRegisters),
246 &tmp, SMC_RAM_END0x40000);
247
248 if (!result) {
249 data->soft_regs_start = tmp;
250 smu_data->smu7_data.soft_regs_start = tmp;
251 }
252
253 error |= (0 != result);
254
255 result = smu7_read_smc_sram_dword(hwmgr,
256 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
257 offsetof(SMU75_Firmware_Header, mcRegisterTable)__builtin_offsetof(SMU75_Firmware_Header, mcRegisterTable),
258 &tmp, SMC_RAM_END0x40000);
259
260 if (!result)
261 smu_data->smu7_data.mc_reg_table_start = tmp;
262
263 result = smu7_read_smc_sram_dword(hwmgr,
264 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
265 offsetof(SMU75_Firmware_Header, FanTable)__builtin_offsetof(SMU75_Firmware_Header, FanTable),
266 &tmp, SMC_RAM_END0x40000);
267
268 if (!result)
269 smu_data->smu7_data.fan_table_start = tmp;
270
271 error |= (0 != result);
272
273 result = smu7_read_smc_sram_dword(hwmgr,
274 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
275 offsetof(SMU75_Firmware_Header, mcArbDramTimingTable)__builtin_offsetof(SMU75_Firmware_Header, mcArbDramTimingTable
)
,
276 &tmp, SMC_RAM_END0x40000);
277
278 if (!result)
279 smu_data->smu7_data.arb_table_start = tmp;
280
281 error |= (0 != result);
282
283 result = smu7_read_smc_sram_dword(hwmgr,
284 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
285 offsetof(SMU75_Firmware_Header, Version)__builtin_offsetof(SMU75_Firmware_Header, Version),
286 &tmp, SMC_RAM_END0x40000);
287
288 if (!result)
289 hwmgr->microcode_version_info.SMC = tmp;
290
291 error |= (0 != result);
292
293 return error ? -1 : 0;
294}
295
296static bool_Bool vegam_is_dpm_running(struct pp_hwmgr *hwmgr)
297{
298 return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device,((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x3f010))) & 0x2000) >>
0xd)
299 CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0x3f010))) & 0x2000) >>
0xd)
)
300 ? true1 : false0;
301}
302
303static uint32_t vegam_get_mac_definition(uint32_t value)
304{
305 switch (value) {
306 case SMU_MAX_LEVELS_GRAPHICS:
307 return SMU75_MAX_LEVELS_GRAPHICS8;
308 case SMU_MAX_LEVELS_MEMORY:
309 return SMU75_MAX_LEVELS_MEMORY4;
310 case SMU_MAX_LEVELS_LINK:
311 return SMU75_MAX_LEVELS_LINK8;
312 case SMU_MAX_ENTRIES_SMIO:
313 return SMU75_MAX_ENTRIES_SMIO32;
314 case SMU_MAX_LEVELS_VDDC:
315 return SMU75_MAX_LEVELS_VDDC16;
316 case SMU_MAX_LEVELS_VDDGFX:
317 return SMU75_MAX_LEVELS_VDDGFX16;
318 case SMU_MAX_LEVELS_VDDCI:
319 return SMU75_MAX_LEVELS_VDDCI8;
320 case SMU_MAX_LEVELS_MVDD:
321 return SMU75_MAX_LEVELS_MVDD4;
322 case SMU_UVD_MCLK_HANDSHAKE_DISABLE:
323 return SMU7_UVD_MCLK_HANDSHAKE_DISABLE0x00000100 |
324 SMU7_VCE_MCLK_HANDSHAKE_DISABLE0x00010000;
325 }
326
327 pr_warn("can't get the mac of %x\n", value)printk("\0014" "amdgpu: " "can't get the mac of %x\n", value);
328 return 0;
329}
330
331static int vegam_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
332{
333 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
334 uint32_t mm_boot_level_offset, mm_boot_level_value;
335 struct phm_ppt_v1_information *table_info =
336 (struct phm_ppt_v1_information *)(hwmgr->pptable);
337
338 smu_data->smc_state_table.UvdBootLevel = 0;
339 if (table_info->mm_dep_table->count > 0)
340 smu_data->smc_state_table.UvdBootLevel =
341 (uint8_t) (table_info->mm_dep_table->count - 1);
342 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU75_Discrete_DpmTable,__builtin_offsetof(SMU75_Discrete_DpmTable, UvdBootLevel)
343 UvdBootLevel)__builtin_offsetof(SMU75_Discrete_DpmTable, UvdBootLevel);
344 mm_boot_level_offset /= 4;
345 mm_boot_level_offset *= 4;
346 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset))
347 CGS_IND_REG__SMC, mm_boot_level_offset)(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset))
;
348 mm_boot_level_value &= 0x00FFFFFF;
349 mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24;
350 cgs_write_ind_register(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset,mm_boot_level_value
))
351 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset,mm_boot_level_value
))
;
352
353 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
354 PHM_PlatformCaps_UVDDPM) ||
355 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
356 PHM_PlatformCaps_StablePState))
357 smum_send_msg_to_smc_with_parameter(hwmgr,
358 PPSMC_MSG_UVDDPM_SetEnabledMask((uint16_t) 0x12D),
359 (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel),
360 NULL((void *)0));
361 return 0;
362}
363
364static int vegam_update_vce_smc_table(struct pp_hwmgr *hwmgr)
365{
366 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
367 uint32_t mm_boot_level_offset, mm_boot_level_value;
368 struct phm_ppt_v1_information *table_info =
369 (struct phm_ppt_v1_information *)(hwmgr->pptable);
370
371 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
372 PHM_PlatformCaps_StablePState))
373 smu_data->smc_state_table.VceBootLevel =
374 (uint8_t) (table_info->mm_dep_table->count - 1);
375 else
376 smu_data->smc_state_table.VceBootLevel = 0;
377
378 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start +
379 offsetof(SMU75_Discrete_DpmTable, VceBootLevel)__builtin_offsetof(SMU75_Discrete_DpmTable, VceBootLevel);
380 mm_boot_level_offset /= 4;
381 mm_boot_level_offset *= 4;
382 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset))
383 CGS_IND_REG__SMC, mm_boot_level_offset)(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset))
;
384 mm_boot_level_value &= 0xFF00FFFF;
385 mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16;
386 cgs_write_ind_register(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset,mm_boot_level_value
))
387 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,mm_boot_level_offset,mm_boot_level_value
))
;
388
389 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
390 smum_send_msg_to_smc_with_parameter(hwmgr,
391 PPSMC_MSG_VCEDPM_SetEnabledMask((uint16_t) 0x12E),
392 (uint32_t)1 << smu_data->smc_state_table.VceBootLevel,
393 NULL((void *)0));
394 return 0;
395}
396
397static int vegam_update_bif_smc_table(struct pp_hwmgr *hwmgr)
398{
399 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
400 struct phm_ppt_v1_information *table_info =
401 (struct phm_ppt_v1_information *)(hwmgr->pptable);
402 struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
403 int max_entry, i;
404
405 max_entry = (SMU75_MAX_LEVELS_LINK8 < pcie_table->count) ?
406 SMU75_MAX_LEVELS_LINK8 :
407 pcie_table->count;
408 /* Setup BIF_SCLK levels */
409 for (i = 0; i < max_entry; i++)
410 smu_data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk;
411 return 0;
412}
413
414static int vegam_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
415{
416 switch (type) {
417 case SMU_UVD_TABLE:
418 vegam_update_uvd_smc_table(hwmgr);
419 break;
420 case SMU_VCE_TABLE:
421 vegam_update_vce_smc_table(hwmgr);
422 break;
423 case SMU_BIF_TABLE:
424 vegam_update_bif_smc_table(hwmgr);
425 break;
426 default:
427 break;
428 }
429 return 0;
430}
431
432static void vegam_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
433{
434 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
435 struct phm_ppt_v1_information *table_info =
436 (struct phm_ppt_v1_information *)(hwmgr->pptable);
437
438 if (table_info &&
439 table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX1 &&
440 table_info->cac_dtp_table->usPowerTuneDataSetID)
441 smu_data->power_tune_defaults =
442 &vegam_power_tune_data_set_array
443 [table_info->cac_dtp_table->usPowerTuneDataSetID - 1];
444 else
445 smu_data->power_tune_defaults = &vegam_power_tune_data_set_array[0];
446
447}
448
449static int vegam_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
450 SMU75_Discrete_DpmTable *table)
451{
452 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
453 uint32_t count, level;
454
455 if (SMU7_VOLTAGE_CONTROL_BY_GPIO0x1 == data->mvdd_control) {
456 count = data->mvdd_voltage_table.count;
457 if (count > SMU_MAX_SMIO_LEVELS4)
458 count = SMU_MAX_SMIO_LEVELS4;
459 for (level = 0; level < count; level++) {
460 table->SmioTable2.Pattern[level].Voltage = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(data->mvdd_voltage_table
.entries[level].value * 4) ? (__uint16_t)(((__uint16_t)(data->
mvdd_voltage_table.entries[level].value * 4) & 0xffU) <<
8 | ((__uint16_t)(data->mvdd_voltage_table.entries[level]
.value * 4) & 0xff00U) >> 8) : __swap16md(data->
mvdd_voltage_table.entries[level].value * 4))
461 data->mvdd_voltage_table.entries[level].value * VOLTAGE_SCALE)(__uint16_t)(__builtin_constant_p(data->mvdd_voltage_table
.entries[level].value * 4) ? (__uint16_t)(((__uint16_t)(data->
mvdd_voltage_table.entries[level].value * 4) & 0xffU) <<
8 | ((__uint16_t)(data->mvdd_voltage_table.entries[level]
.value * 4) & 0xff00U) >> 8) : __swap16md(data->
mvdd_voltage_table.entries[level].value * 4))
;
462 /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/
463 table->SmioTable2.Pattern[level].Smio =
464 (uint8_t) level;
465 table->Smio[level] |=
466 data->mvdd_voltage_table.entries[level].smio_low;
467 }
468 table->SmioMask2 = data->mvdd_voltage_table.mask_low;
469
470 table->MvddLevelCount = (uint32_t) PP_HOST_TO_SMC_UL(count)(__uint32_t)(__builtin_constant_p(count) ? (__uint32_t)(((__uint32_t
)(count) & 0xff) << 24 | ((__uint32_t)(count) &
0xff00) << 8 | ((__uint32_t)(count) & 0xff0000) >>
8 | ((__uint32_t)(count) & 0xff000000) >> 24) : __swap32md
(count))
;
471 }
472
473 return 0;
474}
475
476static int vegam_populate_smc_vddci_table(struct pp_hwmgr *hwmgr,
477 struct SMU75_Discrete_DpmTable *table)
478{
479 uint32_t count, level;
480 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
481
482 count = data->vddci_voltage_table.count;
483
484 if (SMU7_VOLTAGE_CONTROL_BY_GPIO0x1 == data->vddci_control) {
485 if (count > SMU_MAX_SMIO_LEVELS4)
486 count = SMU_MAX_SMIO_LEVELS4;
487 for (level = 0; level < count; ++level) {
488 table->SmioTable1.Pattern[level].Voltage = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(data->vddci_voltage_table
.entries[level].value * 4) ? (__uint16_t)(((__uint16_t)(data->
vddci_voltage_table.entries[level].value * 4) & 0xffU) <<
8 | ((__uint16_t)(data->vddci_voltage_table.entries[level
].value * 4) & 0xff00U) >> 8) : __swap16md(data->
vddci_voltage_table.entries[level].value * 4))
489 data->vddci_voltage_table.entries[level].value * VOLTAGE_SCALE)(__uint16_t)(__builtin_constant_p(data->vddci_voltage_table
.entries[level].value * 4) ? (__uint16_t)(((__uint16_t)(data->
vddci_voltage_table.entries[level].value * 4) & 0xffU) <<
8 | ((__uint16_t)(data->vddci_voltage_table.entries[level
].value * 4) & 0xff00U) >> 8) : __swap16md(data->
vddci_voltage_table.entries[level].value * 4))
;
490 table->SmioTable1.Pattern[level].Smio = (uint8_t) level;
491
492 table->Smio[level] |= data->vddci_voltage_table.entries[level].smio_low;
493 }
494 }
495
496 table->SmioMask1 = data->vddci_voltage_table.mask_low;
497
498 return 0;
499}
500
501static int vegam_populate_cac_table(struct pp_hwmgr *hwmgr,
502 struct SMU75_Discrete_DpmTable *table)
503{
504 uint32_t count;
505 uint8_t index;
506 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
507 struct phm_ppt_v1_information *table_info =
508 (struct phm_ppt_v1_information *)(hwmgr->pptable);
509 struct phm_ppt_v1_voltage_lookup_table *lookup_table =
510 table_info->vddc_lookup_table;
511 /* tables is already swapped, so in order to use the value from it,
512 * we need to swap it back.
513 * We are populating vddc CAC data to BapmVddc table
514 * in split and merged mode
515 */
516 for (count = 0; count < lookup_table->count; count++) {
517 index = phm_get_voltage_index(lookup_table,
518 data->vddc_voltage_table.entries[count].value);
519 table->BapmVddcVidLoSidd[count] =
520 convert_to_vid(lookup_table->entries[index].us_cac_low);
521 table->BapmVddcVidHiSidd[count] =
522 convert_to_vid(lookup_table->entries[index].us_cac_mid);
523 table->BapmVddcVidHiSidd2[count] =
524 convert_to_vid(lookup_table->entries[index].us_cac_high);
525 }
526
527 return 0;
528}
529
530static int vegam_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr,
531 struct SMU75_Discrete_DpmTable *table)
532{
533 vegam_populate_smc_vddci_table(hwmgr, table);
534 vegam_populate_smc_mvdd_table(hwmgr, table);
535 vegam_populate_cac_table(hwmgr, table);
536
537 return 0;
538}
539
540static int vegam_populate_ulv_level(struct pp_hwmgr *hwmgr,
541 struct SMU75_Discrete_Ulv *state)
542{
543 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
544 struct phm_ppt_v1_information *table_info =
545 (struct phm_ppt_v1_information *)(hwmgr->pptable);
546
547 state->CcPwrDynRm = 0;
548 state->CcPwrDynRm1 = 0;
549
550 state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset;
551 state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset *
552 VOLTAGE_VID_OFFSET_SCALE2100 / VOLTAGE_VID_OFFSET_SCALE1625);
553
554 state->VddcPhase = data->vddc_phase_shed_control ^ 0x3;
555
556 CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm)((state->CcPwrDynRm) = (__uint32_t)(__builtin_constant_p(state
->CcPwrDynRm) ? (__uint32_t)(((__uint32_t)(state->CcPwrDynRm
) & 0xff) << 24 | ((__uint32_t)(state->CcPwrDynRm
) & 0xff00) << 8 | ((__uint32_t)(state->CcPwrDynRm
) & 0xff0000) >> 8 | ((__uint32_t)(state->CcPwrDynRm
) & 0xff000000) >> 24) : __swap32md(state->CcPwrDynRm
)))
;
557 CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1)((state->CcPwrDynRm1) = (__uint32_t)(__builtin_constant_p(
state->CcPwrDynRm1) ? (__uint32_t)(((__uint32_t)(state->
CcPwrDynRm1) & 0xff) << 24 | ((__uint32_t)(state->
CcPwrDynRm1) & 0xff00) << 8 | ((__uint32_t)(state->
CcPwrDynRm1) & 0xff0000) >> 8 | ((__uint32_t)(state
->CcPwrDynRm1) & 0xff000000) >> 24) : __swap32md
(state->CcPwrDynRm1)))
;
558 CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset)((state->VddcOffset) = (__uint16_t)(__builtin_constant_p(state
->VddcOffset) ? (__uint16_t)(((__uint16_t)(state->VddcOffset
) & 0xffU) << 8 | ((__uint16_t)(state->VddcOffset
) & 0xff00U) >> 8) : __swap16md(state->VddcOffset
)))
;
559
560 return 0;
561}
562
563static int vegam_populate_ulv_state(struct pp_hwmgr *hwmgr,
564 struct SMU75_Discrete_DpmTable *table)
565{
566 return vegam_populate_ulv_level(hwmgr, &table->Ulv);
567}
568
569static int vegam_populate_smc_link_level(struct pp_hwmgr *hwmgr,
570 struct SMU75_Discrete_DpmTable *table)
571{
572 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
573 struct vegam_smumgr *smu_data =
574 (struct vegam_smumgr *)(hwmgr->smu_backend);
575 struct smu7_dpm_table *dpm_table = &data->dpm_table;
576 int i;
577
578 /* Index (dpm_table->pcie_speed_table.count)
579 * is reserved for PCIE boot level. */
580 for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) {
581 table->LinkLevel[i].PcieGenSpeed =
582 (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value;
583 table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width(
584 dpm_table->pcie_speed_table.dpm_levels[i].param1);
585 table->LinkLevel[i].EnabledForActivity = 1;
586 table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff);
587 table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5)(__uint32_t)(__builtin_constant_p(5) ? (__uint32_t)(((__uint32_t
)(5) & 0xff) << 24 | ((__uint32_t)(5) & 0xff00)
<< 8 | ((__uint32_t)(5) & 0xff0000) >> 8 | (
(__uint32_t)(5) & 0xff000000) >> 24) : __swap32md(5
))
;
588 table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30)(__uint32_t)(__builtin_constant_p(30) ? (__uint32_t)(((__uint32_t
)(30) & 0xff) << 24 | ((__uint32_t)(30) & 0xff00
) << 8 | ((__uint32_t)(30) & 0xff0000) >> 8 |
((__uint32_t)(30) & 0xff000000) >> 24) : __swap32md
(30))
;
589 }
590
591 smu_data->smc_state_table.LinkLevelCount =
592 (uint8_t)dpm_table->pcie_speed_table.count;
593
594/* To Do move to hwmgr */
595 data->dpm_level_enable_mask.pcie_dpm_enable_mask =
596 phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table);
597
598 return 0;
599}
600
601static int vegam_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr,
602 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table,
603 uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd)
604{
605 uint32_t i;
606 uint16_t vddci;
607 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
608
609 *voltage = *mvdd = 0;
610
611 /* clock - voltage dependency table is empty table */
612 if (dep_table->count == 0)
613 return -EINVAL22;
614
615 for (i = 0; i < dep_table->count; i++) {
616 /* find first sclk bigger than request */
617 if (dep_table->entries[i].clk >= clock) {
618 *voltage |= (dep_table->entries[i].vddc *
619 VOLTAGE_SCALE4) << VDDC_SHIFT0;
620 if (SMU7_VOLTAGE_CONTROL_NONE0x0 == data->vddci_control)
621 *voltage |= (data->vbios_boot_state.vddci_bootup_value *
622 VOLTAGE_SCALE4) << VDDCI_SHIFT15;
623 else if (dep_table->entries[i].vddci)
624 *voltage |= (dep_table->entries[i].vddci *
625 VOLTAGE_SCALE4) << VDDCI_SHIFT15;
626 else {
627 vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
628 (dep_table->entries[i].vddc -
629 (uint16_t)VDDC_VDDCI_DELTA200));
630 *voltage |= (vddci * VOLTAGE_SCALE4) << VDDCI_SHIFT15;
631 }
632
633 if (SMU7_VOLTAGE_CONTROL_NONE0x0 == data->mvdd_control)
634 *mvdd = data->vbios_boot_state.mvdd_bootup_value *
635 VOLTAGE_SCALE4;
636 else if (dep_table->entries[i].mvdd)
637 *mvdd = (uint32_t) dep_table->entries[i].mvdd *
638 VOLTAGE_SCALE4;
639
640 *voltage |= 1 << PHASES_SHIFT30;
641 return 0;
642 }
643 }
644
645 /* sclk is bigger than max sclk in the dependence table */
646 *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE4) << VDDC_SHIFT0;
647
648 if (SMU7_VOLTAGE_CONTROL_NONE0x0 == data->vddci_control)
649 *voltage |= (data->vbios_boot_state.vddci_bootup_value *
650 VOLTAGE_SCALE4) << VDDCI_SHIFT15;
651 else if (dep_table->entries[i - 1].vddci)
652 *voltage |= (dep_table->entries[i - 1].vddci *
653 VOLTAGE_SCALE4) << VDDC_SHIFT0;
654 else {
655 vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
656 (dep_table->entries[i - 1].vddc -
657 (uint16_t)VDDC_VDDCI_DELTA200));
658
659 *voltage |= (vddci * VOLTAGE_SCALE4) << VDDCI_SHIFT15;
660 }
661
662 if (SMU7_VOLTAGE_CONTROL_NONE0x0 == data->mvdd_control)
663 *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE4;
664 else if (dep_table->entries[i].mvdd)
665 *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE4;
666
667 return 0;
668}
669
670static void vegam_get_sclk_range_table(struct pp_hwmgr *hwmgr,
671 SMU75_Discrete_DpmTable *table)
672{
673 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
674 uint32_t i, ref_clk;
675
676 struct pp_atom_ctrl_sclk_range_table range_table_from_vbios = { { {0} } };
677
678 ref_clk = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev)((struct amdgpu_device *)hwmgr->adev)->asic_funcs->get_xclk
(((struct amdgpu_device *)hwmgr->adev))
;
679
680 if (0 == atomctrl_get_smc_sclk_range_table(hwmgr, &range_table_from_vbios)) {
681 for (i = 0; i < NUM_SCLK_RANGE8; i++) {
682 table->SclkFcwRangeTable[i].vco_setting =
683 range_table_from_vbios.entry[i].ucVco_setting;
684 table->SclkFcwRangeTable[i].postdiv =
685 range_table_from_vbios.entry[i].ucPostdiv;
686 table->SclkFcwRangeTable[i].fcw_pcc =
687 range_table_from_vbios.entry[i].usFcw_pcc;
688
689 table->SclkFcwRangeTable[i].fcw_trans_upper =
690 range_table_from_vbios.entry[i].usFcw_trans_upper;
691 table->SclkFcwRangeTable[i].fcw_trans_lower =
692 range_table_from_vbios.entry[i].usRcw_trans_lower;
693
694 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc)((table->SclkFcwRangeTable[i].fcw_pcc) = (__uint16_t)(__builtin_constant_p
(table->SclkFcwRangeTable[i].fcw_pcc) ? (__uint16_t)(((__uint16_t
)(table->SclkFcwRangeTable[i].fcw_pcc) & 0xffU) <<
8 | ((__uint16_t)(table->SclkFcwRangeTable[i].fcw_pcc) &
0xff00U) >> 8) : __swap16md(table->SclkFcwRangeTable
[i].fcw_pcc)))
;
695 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper)((table->SclkFcwRangeTable[i].fcw_trans_upper) = (__uint16_t
)(__builtin_constant_p(table->SclkFcwRangeTable[i].fcw_trans_upper
) ? (__uint16_t)(((__uint16_t)(table->SclkFcwRangeTable[i]
.fcw_trans_upper) & 0xffU) << 8 | ((__uint16_t)(table
->SclkFcwRangeTable[i].fcw_trans_upper) & 0xff00U) >>
8) : __swap16md(table->SclkFcwRangeTable[i].fcw_trans_upper
)))
;
696 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower)((table->SclkFcwRangeTable[i].fcw_trans_lower) = (__uint16_t
)(__builtin_constant_p(table->SclkFcwRangeTable[i].fcw_trans_lower
) ? (__uint16_t)(((__uint16_t)(table->SclkFcwRangeTable[i]
.fcw_trans_lower) & 0xffU) << 8 | ((__uint16_t)(table
->SclkFcwRangeTable[i].fcw_trans_lower) & 0xff00U) >>
8) : __swap16md(table->SclkFcwRangeTable[i].fcw_trans_lower
)))
;
697 }
698 return;
699 }
700
701 for (i = 0; i < NUM_SCLK_RANGE8; i++) {
702 smu_data->range_table[i].trans_lower_frequency =
703 (ref_clk * Range_Table[i].fcw_trans_lower) >> Range_Table[i].postdiv;
704 smu_data->range_table[i].trans_upper_frequency =
705 (ref_clk * Range_Table[i].fcw_trans_upper) >> Range_Table[i].postdiv;
706
707 table->SclkFcwRangeTable[i].vco_setting = Range_Table[i].vco_setting;
708 table->SclkFcwRangeTable[i].postdiv = Range_Table[i].postdiv;
709 table->SclkFcwRangeTable[i].fcw_pcc = Range_Table[i].fcw_pcc;
710
711 table->SclkFcwRangeTable[i].fcw_trans_upper = Range_Table[i].fcw_trans_upper;
712 table->SclkFcwRangeTable[i].fcw_trans_lower = Range_Table[i].fcw_trans_lower;
713
714 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc)((table->SclkFcwRangeTable[i].fcw_pcc) = (__uint16_t)(__builtin_constant_p
(table->SclkFcwRangeTable[i].fcw_pcc) ? (__uint16_t)(((__uint16_t
)(table->SclkFcwRangeTable[i].fcw_pcc) & 0xffU) <<
8 | ((__uint16_t)(table->SclkFcwRangeTable[i].fcw_pcc) &
0xff00U) >> 8) : __swap16md(table->SclkFcwRangeTable
[i].fcw_pcc)))
;
715 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper)((table->SclkFcwRangeTable[i].fcw_trans_upper) = (__uint16_t
)(__builtin_constant_p(table->SclkFcwRangeTable[i].fcw_trans_upper
) ? (__uint16_t)(((__uint16_t)(table->SclkFcwRangeTable[i]
.fcw_trans_upper) & 0xffU) << 8 | ((__uint16_t)(table
->SclkFcwRangeTable[i].fcw_trans_upper) & 0xff00U) >>
8) : __swap16md(table->SclkFcwRangeTable[i].fcw_trans_upper
)))
;
716 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower)((table->SclkFcwRangeTable[i].fcw_trans_lower) = (__uint16_t
)(__builtin_constant_p(table->SclkFcwRangeTable[i].fcw_trans_lower
) ? (__uint16_t)(((__uint16_t)(table->SclkFcwRangeTable[i]
.fcw_trans_lower) & 0xffU) << 8 | ((__uint16_t)(table
->SclkFcwRangeTable[i].fcw_trans_lower) & 0xff00U) >>
8) : __swap16md(table->SclkFcwRangeTable[i].fcw_trans_lower
)))
;
717 }
718}
719
720static int vegam_calculate_sclk_params(struct pp_hwmgr *hwmgr,
721 uint32_t clock, SMU_SclkSetting *sclk_setting)
722{
723 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
724 const SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
725 struct pp_atomctrl_clock_dividers_ai dividers;
726 uint32_t ref_clock;
727 uint32_t pcc_target_percent, pcc_target_freq, ss_target_percent, ss_target_freq;
728 uint8_t i;
729 int result;
730 uint64_t temp;
731
732 sclk_setting->SclkFrequency = clock;
733 /* get the engine clock dividers for this clock value */
734 result = atomctrl_get_engine_pll_dividers_ai(hwmgr, clock, &dividers);
735 if (result == 0) {
736 sclk_setting->Fcw_int = dividers.usSclk_fcw_int;
737 sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac;
738 sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int;
739 sclk_setting->PllRange = dividers.ucSclkPllRange;
740 sclk_setting->Sclk_slew_rate = 0x400;
741 sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac;
742 sclk_setting->Pcc_down_slew_rate = 0xffff;
743 sclk_setting->SSc_En = dividers.ucSscEnable;
744 sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int;
745 sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac;
746 sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac;
747 return result;
748 }
749
750 ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev)((struct amdgpu_device *)hwmgr->adev)->asic_funcs->get_xclk
(((struct amdgpu_device *)hwmgr->adev))
;
751
752 for (i = 0; i < NUM_SCLK_RANGE8; i++) {
753 if (clock > smu_data->range_table[i].trans_lower_frequency
754 && clock <= smu_data->range_table[i].trans_upper_frequency) {
755 sclk_setting->PllRange = i;
756 break;
757 }
758 }
759
760 sclk_setting->Fcw_int = (uint16_t)
761 ((clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) /
762 ref_clock);
763 temp = clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv;
764 temp <<= 0x10;
765 do_div(temp, ref_clock)({ uint32_t __base = (ref_clock); uint32_t __rem = ((uint64_t
)(temp)) % __base; (temp) = ((uint64_t)(temp)) / __base; __rem
; })
;
766 sclk_setting->Fcw_frac = temp & 0xffff;
767
768 pcc_target_percent = 10; /* Hardcode 10% for now. */
769 pcc_target_freq = clock - (clock * pcc_target_percent / 100);
770 sclk_setting->Pcc_fcw_int = (uint16_t)
771 ((pcc_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) /
772 ref_clock);
773
774 ss_target_percent = 2; /* Hardcode 2% for now. */
775 sclk_setting->SSc_En = 0;
776 if (ss_target_percent) {
777 sclk_setting->SSc_En = 1;
778 ss_target_freq = clock - (clock * ss_target_percent / 100);
779 sclk_setting->Fcw1_int = (uint16_t)
780 ((ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) /
781 ref_clock);
782 temp = ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv;
783 temp <<= 0x10;
784 do_div(temp, ref_clock)({ uint32_t __base = (ref_clock); uint32_t __rem = ((uint64_t
)(temp)) % __base; (temp) = ((uint64_t)(temp)) / __base; __rem
; })
;
785 sclk_setting->Fcw1_frac = temp & 0xffff;
786 }
787
788 return 0;
789}
790
791static uint8_t vegam_get_sleep_divider_id_from_clock(uint32_t clock,
792 uint32_t clock_insr)
793{
794 uint8_t i;
795 uint32_t temp;
796 uint32_t min = max(clock_insr, (uint32_t)SMU7_MINIMUM_ENGINE_CLOCK)(((clock_insr)>((uint32_t)2500))?(clock_insr):((uint32_t)2500
))
;
797
798 PP_ASSERT_WITH_CODE((clock >= min),do { if (!((clock >= min))) { printk("\0014" "amdgpu: " "%s\n"
, "Engine clock can't satisfy stutter requirement!"); return 0
; } } while (0)
799 "Engine clock can't satisfy stutter requirement!",do { if (!((clock >= min))) { printk("\0014" "amdgpu: " "%s\n"
, "Engine clock can't satisfy stutter requirement!"); return 0
; } } while (0)
800 return 0)do { if (!((clock >= min))) { printk("\0014" "amdgpu: " "%s\n"
, "Engine clock can't satisfy stutter requirement!"); return 0
; } } while (0)
;
801 for (i = 31; ; i--) {
802 temp = clock / (i + 1);
803
804 if (temp >= min || i == 0)
805 break;
806 }
807 return i;
808}
809
810static int vegam_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
811 uint32_t clock, struct SMU75_Discrete_GraphicsLevel *level)
812{
813 int result;
814 /* PP_Clocks minClocks; */
815 uint32_t mvdd;
816 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
817 struct phm_ppt_v1_information *table_info =
818 (struct phm_ppt_v1_information *)(hwmgr->pptable);
819 SMU_SclkSetting curr_sclk_setting = { 0 };
820
821 result = vegam_calculate_sclk_params(hwmgr, clock, &curr_sclk_setting);
822
823 /* populate graphics levels */
824 result = vegam_get_dependency_volt_by_clk(hwmgr,
825 table_info->vdd_dep_on_sclk, clock,
826 &level->MinVoltage, &mvdd);
827
828 PP_ASSERT_WITH_CODE((0 == result),do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find VDDC voltage value for " "VDDC engine clock dependency table"
); return result; } } while (0)
829 "can not find VDDC voltage value for "do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find VDDC voltage value for " "VDDC engine clock dependency table"
); return result; } } while (0)
830 "VDDC engine clock dependency table",do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find VDDC voltage value for " "VDDC engine clock dependency table"
); return result; } } while (0)
831 return result)do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find VDDC voltage value for " "VDDC engine clock dependency table"
); return result; } } while (0)
;
832 level->ActivityLevel = (uint16_t)(SclkDPMTuning_VEGAM0x002d000a >> DPMTuning_Activity_Shift16);
833
834 level->CcPwrDynRm = 0;
835 level->CcPwrDynRm1 = 0;
836 level->EnabledForActivity = 0;
837 level->EnabledForThrottle = 1;
838 level->VoltageDownHyst = 0;
839 level->PowerThrottle = 0;
840 data->display_timing.min_clock_in_sr = hwmgr->display_config->min_core_set_clock_in_sr;
841
842 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
843 level->DeepSleepDivId = vegam_get_sleep_divider_id_from_clock(clock,
844 hwmgr->display_config->min_core_set_clock_in_sr);
845
846 level->SclkSetting = curr_sclk_setting;
847
848 CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage)((level->MinVoltage) = (__uint32_t)(__builtin_constant_p(level
->MinVoltage) ? (__uint32_t)(((__uint32_t)(level->MinVoltage
) & 0xff) << 24 | ((__uint32_t)(level->MinVoltage
) & 0xff00) << 8 | ((__uint32_t)(level->MinVoltage
) & 0xff0000) >> 8 | ((__uint32_t)(level->MinVoltage
) & 0xff000000) >> 24) : __swap32md(level->MinVoltage
)))
;
849 CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm)((level->CcPwrDynRm) = (__uint32_t)(__builtin_constant_p(level
->CcPwrDynRm) ? (__uint32_t)(((__uint32_t)(level->CcPwrDynRm
) & 0xff) << 24 | ((__uint32_t)(level->CcPwrDynRm
) & 0xff00) << 8 | ((__uint32_t)(level->CcPwrDynRm
) & 0xff0000) >> 8 | ((__uint32_t)(level->CcPwrDynRm
) & 0xff000000) >> 24) : __swap32md(level->CcPwrDynRm
)))
;
850 CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1)((level->CcPwrDynRm1) = (__uint32_t)(__builtin_constant_p(
level->CcPwrDynRm1) ? (__uint32_t)(((__uint32_t)(level->
CcPwrDynRm1) & 0xff) << 24 | ((__uint32_t)(level->
CcPwrDynRm1) & 0xff00) << 8 | ((__uint32_t)(level->
CcPwrDynRm1) & 0xff0000) >> 8 | ((__uint32_t)(level
->CcPwrDynRm1) & 0xff000000) >> 24) : __swap32md
(level->CcPwrDynRm1)))
;
851 CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel)((level->ActivityLevel) = (__uint16_t)(__builtin_constant_p
(level->ActivityLevel) ? (__uint16_t)(((__uint16_t)(level->
ActivityLevel) & 0xffU) << 8 | ((__uint16_t)(level->
ActivityLevel) & 0xff00U) >> 8) : __swap16md(level->
ActivityLevel)))
;
852 CONVERT_FROM_HOST_TO_SMC_UL(level->SclkSetting.SclkFrequency)((level->SclkSetting.SclkFrequency) = (__uint32_t)(__builtin_constant_p
(level->SclkSetting.SclkFrequency) ? (__uint32_t)(((__uint32_t
)(level->SclkSetting.SclkFrequency) & 0xff) << 24
| ((__uint32_t)(level->SclkSetting.SclkFrequency) & 0xff00
) << 8 | ((__uint32_t)(level->SclkSetting.SclkFrequency
) & 0xff0000) >> 8 | ((__uint32_t)(level->SclkSetting
.SclkFrequency) & 0xff000000) >> 24) : __swap32md(level
->SclkSetting.SclkFrequency)))
;
853 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int)((level->SclkSetting.Fcw_int) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Fcw_int) ? (__uint16_t)(((__uint16_t)(
level->SclkSetting.Fcw_int) & 0xffU) << 8 | ((__uint16_t
)(level->SclkSetting.Fcw_int) & 0xff00U) >> 8) :
__swap16md(level->SclkSetting.Fcw_int)))
;
854 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac)((level->SclkSetting.Fcw_frac) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Fcw_frac) ? (__uint16_t)(((__uint16_t)
(level->SclkSetting.Fcw_frac) & 0xffU) << 8 | ((
__uint16_t)(level->SclkSetting.Fcw_frac) & 0xff00U) >>
8) : __swap16md(level->SclkSetting.Fcw_frac)))
;
855 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int)((level->SclkSetting.Pcc_fcw_int) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Pcc_fcw_int) ? (__uint16_t)(((__uint16_t
)(level->SclkSetting.Pcc_fcw_int) & 0xffU) << 8 |
((__uint16_t)(level->SclkSetting.Pcc_fcw_int) & 0xff00U
) >> 8) : __swap16md(level->SclkSetting.Pcc_fcw_int)
))
;
856 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate)((level->SclkSetting.Sclk_slew_rate) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Sclk_slew_rate) ? (__uint16_t)(((__uint16_t
)(level->SclkSetting.Sclk_slew_rate) & 0xffU) <<
8 | ((__uint16_t)(level->SclkSetting.Sclk_slew_rate) &
0xff00U) >> 8) : __swap16md(level->SclkSetting.Sclk_slew_rate
)))
;
857 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate)((level->SclkSetting.Pcc_up_slew_rate) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Pcc_up_slew_rate) ? (__uint16_t)(((__uint16_t
)(level->SclkSetting.Pcc_up_slew_rate) & 0xffU) <<
8 | ((__uint16_t)(level->SclkSetting.Pcc_up_slew_rate) &
0xff00U) >> 8) : __swap16md(level->SclkSetting.Pcc_up_slew_rate
)))
;
858 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate)((level->SclkSetting.Pcc_down_slew_rate) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Pcc_down_slew_rate) ? (__uint16_t)(((__uint16_t
)(level->SclkSetting.Pcc_down_slew_rate) & 0xffU) <<
8 | ((__uint16_t)(level->SclkSetting.Pcc_down_slew_rate) &
0xff00U) >> 8) : __swap16md(level->SclkSetting.Pcc_down_slew_rate
)))
;
859 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int)((level->SclkSetting.Fcw1_int) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Fcw1_int) ? (__uint16_t)(((__uint16_t)
(level->SclkSetting.Fcw1_int) & 0xffU) << 8 | ((
__uint16_t)(level->SclkSetting.Fcw1_int) & 0xff00U) >>
8) : __swap16md(level->SclkSetting.Fcw1_int)))
;
860 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac)((level->SclkSetting.Fcw1_frac) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Fcw1_frac) ? (__uint16_t)(((__uint16_t
)(level->SclkSetting.Fcw1_frac) & 0xffU) << 8 | (
(__uint16_t)(level->SclkSetting.Fcw1_frac) & 0xff00U) >>
8) : __swap16md(level->SclkSetting.Fcw1_frac)))
;
861 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate)((level->SclkSetting.Sclk_ss_slew_rate) = (__uint16_t)(__builtin_constant_p
(level->SclkSetting.Sclk_ss_slew_rate) ? (__uint16_t)(((__uint16_t
)(level->SclkSetting.Sclk_ss_slew_rate) & 0xffU) <<
8 | ((__uint16_t)(level->SclkSetting.Sclk_ss_slew_rate) &
0xff00U) >> 8) : __swap16md(level->SclkSetting.Sclk_ss_slew_rate
)))
;
862 return 0;
863}
864
865static int vegam_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
866{
867 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
868 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
869 struct smu7_dpm_table *dpm_table = &hw_data->dpm_table;
870 struct phm_ppt_v1_information *table_info =
871 (struct phm_ppt_v1_information *)(hwmgr->pptable);
872 struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
873 uint8_t pcie_entry_cnt = (uint8_t) hw_data->dpm_table.pcie_speed_table.count;
874 int result = 0;
875 uint32_t array = smu_data->smu7_data.dpm_table_start +
876 offsetof(SMU75_Discrete_DpmTable, GraphicsLevel)__builtin_offsetof(SMU75_Discrete_DpmTable, GraphicsLevel);
877 uint32_t array_size = sizeof(struct SMU75_Discrete_GraphicsLevel) *
878 SMU75_MAX_LEVELS_GRAPHICS8;
879 struct SMU75_Discrete_GraphicsLevel *levels =
880 smu_data->smc_state_table.GraphicsLevel;
881 uint32_t i, max_entry;
882 uint8_t hightest_pcie_level_enabled = 0,
883 lowest_pcie_level_enabled = 0,
884 mid_pcie_level_enabled = 0,
885 count = 0;
886
887 vegam_get_sclk_range_table(hwmgr, &(smu_data->smc_state_table));
888
889 for (i = 0; i < dpm_table->sclk_table.count; i++) {
890
891 result = vegam_populate_single_graphic_level(hwmgr,
892 dpm_table->sclk_table.dpm_levels[i].value,
893 &(smu_data->smc_state_table.GraphicsLevel[i]));
894 if (result)
895 return result;
896
897 levels[i].UpHyst = (uint8_t)
898 (SclkDPMTuning_VEGAM0x002d000a >> DPMTuning_Uphyst_Shift0);
899 levels[i].DownHyst = (uint8_t)
900 (SclkDPMTuning_VEGAM0x002d000a >> DPMTuning_Downhyst_Shift8);
901 /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
902 if (i > 1)
903 levels[i].DeepSleepDivId = 0;
904 }
905 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
906 PHM_PlatformCaps_SPLLShutdownSupport))
907 smu_data->smc_state_table.GraphicsLevel[0].SclkSetting.SSc_En = 0;
908
909 smu_data->smc_state_table.GraphicsDpmLevelCount =
910 (uint8_t)dpm_table->sclk_table.count;
911 hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask =
912 phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
913
914 for (i = 0; i < dpm_table->sclk_table.count; i++)
915 levels[i].EnabledForActivity =
916 (hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask >> i) & 0x1;
917
918 if (pcie_table != NULL((void *)0)) {
919 PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt),do { if (!((1 <= pcie_entry_cnt))) { printk("\0014" "amdgpu: "
"%s\n", "There must be 1 or more PCIE levels defined in PPTable."
); return -22; } } while (0)
920 "There must be 1 or more PCIE levels defined in PPTable.",do { if (!((1 <= pcie_entry_cnt))) { printk("\0014" "amdgpu: "
"%s\n", "There must be 1 or more PCIE levels defined in PPTable."
); return -22; } } while (0)
921 return -EINVAL)do { if (!((1 <= pcie_entry_cnt))) { printk("\0014" "amdgpu: "
"%s\n", "There must be 1 or more PCIE levels defined in PPTable."
); return -22; } } while (0)
;
922 max_entry = pcie_entry_cnt - 1;
923 for (i = 0; i < dpm_table->sclk_table.count; i++)
924 levels[i].pcieDpmLevel =
925 (uint8_t) ((i < max_entry) ? i : max_entry);
926 } else {
927 while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
928 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
929 (1 << (hightest_pcie_level_enabled + 1))) != 0))
930 hightest_pcie_level_enabled++;
931
932 while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
933 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
934 (1 << lowest_pcie_level_enabled)) == 0))
935 lowest_pcie_level_enabled++;
936
937 while ((count < hightest_pcie_level_enabled) &&
938 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
939 (1 << (lowest_pcie_level_enabled + 1 + count))) == 0))
940 count++;
941
942 mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) <
943 hightest_pcie_level_enabled ?
944 (lowest_pcie_level_enabled + 1 + count) :
945 hightest_pcie_level_enabled;
946
947 /* set pcieDpmLevel to hightest_pcie_level_enabled */
948 for (i = 2; i < dpm_table->sclk_table.count; i++)
949 levels[i].pcieDpmLevel = hightest_pcie_level_enabled;
950
951 /* set pcieDpmLevel to lowest_pcie_level_enabled */
952 levels[0].pcieDpmLevel = lowest_pcie_level_enabled;
953
954 /* set pcieDpmLevel to mid_pcie_level_enabled */
955 levels[1].pcieDpmLevel = mid_pcie_level_enabled;
956 }
957 /* level count will send to smc once at init smc table and never change */
958 result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels,
959 (uint32_t)array_size, SMC_RAM_END0x40000);
960
961 return result;
962}
963
964static int vegam_calculate_mclk_params(struct pp_hwmgr *hwmgr,
965 uint32_t clock, struct SMU75_Discrete_MemoryLevel *mem_level)
966{
967 struct pp_atomctrl_memory_clock_param_ai mpll_param;
968
969 PP_ASSERT_WITH_CODE(!atomctrl_get_memory_pll_dividers_ai(hwmgr,do { if (!(!atomctrl_get_memory_pll_dividers_ai(hwmgr, clock,
&mpll_param))) { printk("\0014" "amdgpu: " "%s\n", "Failed to retrieve memory pll parameter."
); return -22; } } while (0)
970 clock, &mpll_param),do { if (!(!atomctrl_get_memory_pll_dividers_ai(hwmgr, clock,
&mpll_param))) { printk("\0014" "amdgpu: " "%s\n", "Failed to retrieve memory pll parameter."
); return -22; } } while (0)
971 "Failed to retrieve memory pll parameter.",do { if (!(!atomctrl_get_memory_pll_dividers_ai(hwmgr, clock,
&mpll_param))) { printk("\0014" "amdgpu: " "%s\n", "Failed to retrieve memory pll parameter."
); return -22; } } while (0)
972 return -EINVAL)do { if (!(!atomctrl_get_memory_pll_dividers_ai(hwmgr, clock,
&mpll_param))) { printk("\0014" "amdgpu: " "%s\n", "Failed to retrieve memory pll parameter."
); return -22; } } while (0)
;
973
974 mem_level->MclkFrequency = (uint32_t)mpll_param.ulClock;
975 mem_level->Fcw_int = (uint16_t)mpll_param.ulMclk_fcw_int;
976 mem_level->Fcw_frac = (uint16_t)mpll_param.ulMclk_fcw_frac;
977 mem_level->Postdiv = (uint8_t)mpll_param.ulPostDiv;
978
979 return 0;
980}
981
982static int vegam_populate_single_memory_level(struct pp_hwmgr *hwmgr,
983 uint32_t clock, struct SMU75_Discrete_MemoryLevel *mem_level)
984{
985 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
986 struct phm_ppt_v1_information *table_info =
987 (struct phm_ppt_v1_information *)(hwmgr->pptable);
988 int result = 0;
989 uint32_t mclk_stutter_mode_threshold = 60000;
990
991
992 if (table_info->vdd_dep_on_mclk) {
993 result = vegam_get_dependency_volt_by_clk(hwmgr,
994 table_info->vdd_dep_on_mclk, clock,
995 &mem_level->MinVoltage, &mem_level->MinMvdd);
996 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "can not find MinVddc voltage value from memory "
"VDDC voltage dependency table"); return result; } } while (
0)
997 "can not find MinVddc voltage value from memory "do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "can not find MinVddc voltage value from memory "
"VDDC voltage dependency table"); return result; } } while (
0)
998 "VDDC voltage dependency table", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "can not find MinVddc voltage value from memory "
"VDDC voltage dependency table"); return result; } } while (
0)
;
999 }
1000
1001 result = vegam_calculate_mclk_params(hwmgr, clock, mem_level);
1002 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to calculate mclk params."
); return -22; } } while (0)
1003 "Failed to calculate mclk params.",do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to calculate mclk params."
); return -22; } } while (0)
1004 return -EINVAL)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to calculate mclk params."
); return -22; } } while (0)
;
1005
1006 mem_level->EnabledForThrottle = 1;
1007 mem_level->EnabledForActivity = 0;
1008 mem_level->VoltageDownHyst = 0;
1009 mem_level->ActivityLevel = (uint16_t)
1010 (MemoryDPMTuning_VEGAM0x000f3c0a >> DPMTuning_Activity_Shift16);
1011 mem_level->StutterEnable = false0;
1012 mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW0;
1013
1014 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1015 data->display_timing.vrefresh = hwmgr->display_config->vrefresh;
1016
1017 if (mclk_stutter_mode_threshold &&
1018 (clock <= mclk_stutter_mode_threshold) &&
1019 (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL,((((((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x1b35))) & 0x1) >> 0x0)
1020 STUTTER_ENABLE)((((((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x1b35))) & 0x1) >> 0x0)
& 0x1))
1021 mem_level->StutterEnable = true1;
1022
1023 if (!result) {
1024 CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd)((mem_level->MinMvdd) = (__uint32_t)(__builtin_constant_p(
mem_level->MinMvdd) ? (__uint32_t)(((__uint32_t)(mem_level
->MinMvdd) & 0xff) << 24 | ((__uint32_t)(mem_level
->MinMvdd) & 0xff00) << 8 | ((__uint32_t)(mem_level
->MinMvdd) & 0xff0000) >> 8 | ((__uint32_t)(mem_level
->MinMvdd) & 0xff000000) >> 24) : __swap32md(mem_level
->MinMvdd)))
;
1025 CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency)((mem_level->MclkFrequency) = (__uint32_t)(__builtin_constant_p
(mem_level->MclkFrequency) ? (__uint32_t)(((__uint32_t)(mem_level
->MclkFrequency) & 0xff) << 24 | ((__uint32_t)(mem_level
->MclkFrequency) & 0xff00) << 8 | ((__uint32_t)(
mem_level->MclkFrequency) & 0xff0000) >> 8 | ((__uint32_t
)(mem_level->MclkFrequency) & 0xff000000) >> 24)
: __swap32md(mem_level->MclkFrequency)))
;
1026 CONVERT_FROM_HOST_TO_SMC_US(mem_level->Fcw_int)((mem_level->Fcw_int) = (__uint16_t)(__builtin_constant_p(
mem_level->Fcw_int) ? (__uint16_t)(((__uint16_t)(mem_level
->Fcw_int) & 0xffU) << 8 | ((__uint16_t)(mem_level
->Fcw_int) & 0xff00U) >> 8) : __swap16md(mem_level
->Fcw_int)))
;
1027 CONVERT_FROM_HOST_TO_SMC_US(mem_level->Fcw_frac)((mem_level->Fcw_frac) = (__uint16_t)(__builtin_constant_p
(mem_level->Fcw_frac) ? (__uint16_t)(((__uint16_t)(mem_level
->Fcw_frac) & 0xffU) << 8 | ((__uint16_t)(mem_level
->Fcw_frac) & 0xff00U) >> 8) : __swap16md(mem_level
->Fcw_frac)))
;
1028 CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel)((mem_level->ActivityLevel) = (__uint16_t)(__builtin_constant_p
(mem_level->ActivityLevel) ? (__uint16_t)(((__uint16_t)(mem_level
->ActivityLevel) & 0xffU) << 8 | ((__uint16_t)(mem_level
->ActivityLevel) & 0xff00U) >> 8) : __swap16md(mem_level
->ActivityLevel)))
;
1029 CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage)((mem_level->MinVoltage) = (__uint32_t)(__builtin_constant_p
(mem_level->MinVoltage) ? (__uint32_t)(((__uint32_t)(mem_level
->MinVoltage) & 0xff) << 24 | ((__uint32_t)(mem_level
->MinVoltage) & 0xff00) << 8 | ((__uint32_t)(mem_level
->MinVoltage) & 0xff0000) >> 8 | ((__uint32_t)(mem_level
->MinVoltage) & 0xff000000) >> 24) : __swap32md(
mem_level->MinVoltage)))
;
1030 }
1031
1032 return result;
1033}
1034
1035static int vegam_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
1036{
1037 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1038 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1039 struct smu7_dpm_table *dpm_table = &hw_data->dpm_table;
1040 int result;
1041 /* populate MCLK dpm table to SMU7 */
1042 uint32_t array = smu_data->smu7_data.dpm_table_start +
1043 offsetof(SMU75_Discrete_DpmTable, MemoryLevel)__builtin_offsetof(SMU75_Discrete_DpmTable, MemoryLevel);
1044 uint32_t array_size = sizeof(SMU75_Discrete_MemoryLevel) *
1045 SMU75_MAX_LEVELS_MEMORY4;
1046 struct SMU75_Discrete_MemoryLevel *levels =
1047 smu_data->smc_state_table.MemoryLevel;
1048 uint32_t i;
1049
1050 for (i = 0; i < dpm_table->mclk_table.count; i++) {
1051 PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value),do { if (!((0 != dpm_table->mclk_table.dpm_levels[i].value
))) { printk("\0014" "amdgpu: " "%s\n", "can not populate memory level as memory clock is zero"
); return -22; } } while (0)
1052 "can not populate memory level as memory clock is zero",do { if (!((0 != dpm_table->mclk_table.dpm_levels[i].value
))) { printk("\0014" "amdgpu: " "%s\n", "can not populate memory level as memory clock is zero"
); return -22; } } while (0)
1053 return -EINVAL)do { if (!((0 != dpm_table->mclk_table.dpm_levels[i].value
))) { printk("\0014" "amdgpu: " "%s\n", "can not populate memory level as memory clock is zero"
); return -22; } } while (0)
;
1054 result = vegam_populate_single_memory_level(hwmgr,
1055 dpm_table->mclk_table.dpm_levels[i].value,
1056 &levels[i]);
1057
1058 if (result)
1059 return result;
1060
1061 levels[i].UpHyst = (uint8_t)
1062 (MemoryDPMTuning_VEGAM0x000f3c0a >> DPMTuning_Uphyst_Shift0);
1063 levels[i].DownHyst = (uint8_t)
1064 (MemoryDPMTuning_VEGAM0x000f3c0a >> DPMTuning_Downhyst_Shift8);
1065 }
1066
1067 smu_data->smc_state_table.MemoryDpmLevelCount =
1068 (uint8_t)dpm_table->mclk_table.count;
1069 hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask =
1070 phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
1071
1072 for (i = 0; i < dpm_table->mclk_table.count; i++)
1073 levels[i].EnabledForActivity =
1074 (hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask >> i) & 0x1;
1075
1076 levels[dpm_table->mclk_table.count - 1].DisplayWatermark =
1077 PPSMC_DISPLAY_WATERMARK_HIGH1;
1078
1079 /* level count will send to smc once at init smc table and never change */
1080 result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels,
1081 (uint32_t)array_size, SMC_RAM_END0x40000);
1082
1083 return result;
1084}
1085
1086static int vegam_populate_mvdd_value(struct pp_hwmgr *hwmgr,
1087 uint32_t mclk, SMIO_Pattern *smio_pat)
1088{
1089 const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1090 struct phm_ppt_v1_information *table_info =
1091 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1092 uint32_t i = 0;
1093
1094 if (SMU7_VOLTAGE_CONTROL_NONE0x0 != data->mvdd_control) {
1095 /* find mvdd value which clock is more than request */
1096 for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) {
1097 if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) {
1098 smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value;
1099 break;
1100 }
1101 }
1102 PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count,do { if (!(i < table_info->vdd_dep_on_mclk->count)) {
printk("\0014" "amdgpu: " "%s\n", "MVDD Voltage is outside the supported range."
); return -22; } } while (0)
1103 "MVDD Voltage is outside the supported range.",do { if (!(i < table_info->vdd_dep_on_mclk->count)) {
printk("\0014" "amdgpu: " "%s\n", "MVDD Voltage is outside the supported range."
); return -22; } } while (0)
1104 return -EINVAL)do { if (!(i < table_info->vdd_dep_on_mclk->count)) {
printk("\0014" "amdgpu: " "%s\n", "MVDD Voltage is outside the supported range."
); return -22; } } while (0)
;
1105 } else
1106 return -EINVAL22;
1107
1108 return 0;
1109}
1110
1111static int vegam_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
1112 SMU75_Discrete_DpmTable *table)
1113{
1114 int result = 0;
1115 uint32_t sclk_frequency;
1116 const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1117 struct phm_ppt_v1_information *table_info =
1118 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1119 SMIO_Pattern vol_level;
1120 uint32_t mvdd;
1121
1122 table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC0x01;
1123
1124 /* Get MinVoltage and Frequency from DPM0,
1125 * already converted to SMC_UL */
1126 sclk_frequency = data->vbios_boot_state.sclk_bootup_value;
1127 result = vegam_get_dependency_volt_by_clk(hwmgr,
1128 table_info->vdd_dep_on_sclk,
1129 sclk_frequency,
1130 &table->ACPILevel.MinVoltage, &mvdd);
1131 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Cannot find ACPI VDDC voltage value "
"in Clock Dependency Table"); ; } } while (0)
1132 "Cannot find ACPI VDDC voltage value "do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Cannot find ACPI VDDC voltage value "
"in Clock Dependency Table"); ; } } while (0)
1133 "in Clock Dependency Table",do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Cannot find ACPI VDDC voltage value "
"in Clock Dependency Table"); ; } } while (0)
1134 )do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Cannot find ACPI VDDC voltage value "
"in Clock Dependency Table"); ; } } while (0)
;
1135
1136 result = vegam_calculate_sclk_params(hwmgr, sclk_frequency,
1137 &(table->ACPILevel.SclkSetting));
1138 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Error retrieving Engine Clock dividers from VBIOS."
); return result; } } while (0)
1139 "Error retrieving Engine Clock dividers from VBIOS.",do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Error retrieving Engine Clock dividers from VBIOS."
); return result; } } while (0)
1140 return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Error retrieving Engine Clock dividers from VBIOS."
); return result; } } while (0)
;
1141
1142 table->ACPILevel.DeepSleepDivId = 0;
1143 table->ACPILevel.CcPwrDynRm = 0;
1144 table->ACPILevel.CcPwrDynRm1 = 0;
1145
1146 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags)((table->ACPILevel.Flags) = (__uint32_t)(__builtin_constant_p
(table->ACPILevel.Flags) ? (__uint32_t)(((__uint32_t)(table
->ACPILevel.Flags) & 0xff) << 24 | ((__uint32_t)
(table->ACPILevel.Flags) & 0xff00) << 8 | ((__uint32_t
)(table->ACPILevel.Flags) & 0xff0000) >> 8 | ((__uint32_t
)(table->ACPILevel.Flags) & 0xff000000) >> 24) :
__swap32md(table->ACPILevel.Flags)))
;
1147 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage)((table->ACPILevel.MinVoltage) = (__uint32_t)(__builtin_constant_p
(table->ACPILevel.MinVoltage) ? (__uint32_t)(((__uint32_t)
(table->ACPILevel.MinVoltage) & 0xff) << 24 | ((
__uint32_t)(table->ACPILevel.MinVoltage) & 0xff00) <<
8 | ((__uint32_t)(table->ACPILevel.MinVoltage) & 0xff0000
) >> 8 | ((__uint32_t)(table->ACPILevel.MinVoltage) &
0xff000000) >> 24) : __swap32md(table->ACPILevel.MinVoltage
)))
;
1148 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm)((table->ACPILevel.CcPwrDynRm) = (__uint32_t)(__builtin_constant_p
(table->ACPILevel.CcPwrDynRm) ? (__uint32_t)(((__uint32_t)
(table->ACPILevel.CcPwrDynRm) & 0xff) << 24 | ((
__uint32_t)(table->ACPILevel.CcPwrDynRm) & 0xff00) <<
8 | ((__uint32_t)(table->ACPILevel.CcPwrDynRm) & 0xff0000
) >> 8 | ((__uint32_t)(table->ACPILevel.CcPwrDynRm) &
0xff000000) >> 24) : __swap32md(table->ACPILevel.CcPwrDynRm
)))
;
1149 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1)((table->ACPILevel.CcPwrDynRm1) = (__uint32_t)(__builtin_constant_p
(table->ACPILevel.CcPwrDynRm1) ? (__uint32_t)(((__uint32_t
)(table->ACPILevel.CcPwrDynRm1) & 0xff) << 24 | (
(__uint32_t)(table->ACPILevel.CcPwrDynRm1) & 0xff00) <<
8 | ((__uint32_t)(table->ACPILevel.CcPwrDynRm1) & 0xff0000
) >> 8 | ((__uint32_t)(table->ACPILevel.CcPwrDynRm1)
& 0xff000000) >> 24) : __swap32md(table->ACPILevel
.CcPwrDynRm1)))
;
1150
1151 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkSetting.SclkFrequency)((table->ACPILevel.SclkSetting.SclkFrequency) = (__uint32_t
)(__builtin_constant_p(table->ACPILevel.SclkSetting.SclkFrequency
) ? (__uint32_t)(((__uint32_t)(table->ACPILevel.SclkSetting
.SclkFrequency) & 0xff) << 24 | ((__uint32_t)(table
->ACPILevel.SclkSetting.SclkFrequency) & 0xff00) <<
8 | ((__uint32_t)(table->ACPILevel.SclkSetting.SclkFrequency
) & 0xff0000) >> 8 | ((__uint32_t)(table->ACPILevel
.SclkSetting.SclkFrequency) & 0xff000000) >> 24) : __swap32md
(table->ACPILevel.SclkSetting.SclkFrequency)))
;
1152 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_int)((table->ACPILevel.SclkSetting.Fcw_int) = (__uint16_t)(__builtin_constant_p
(table->ACPILevel.SclkSetting.Fcw_int) ? (__uint16_t)(((__uint16_t
)(table->ACPILevel.SclkSetting.Fcw_int) & 0xffU) <<
8 | ((__uint16_t)(table->ACPILevel.SclkSetting.Fcw_int) &
0xff00U) >> 8) : __swap16md(table->ACPILevel.SclkSetting
.Fcw_int)))
;
1153 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_frac)((table->ACPILevel.SclkSetting.Fcw_frac) = (__uint16_t)(__builtin_constant_p
(table->ACPILevel.SclkSetting.Fcw_frac) ? (__uint16_t)(((__uint16_t
)(table->ACPILevel.SclkSetting.Fcw_frac) & 0xffU) <<
8 | ((__uint16_t)(table->ACPILevel.SclkSetting.Fcw_frac) &
0xff00U) >> 8) : __swap16md(table->ACPILevel.SclkSetting
.Fcw_frac)))
;
1154 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_fcw_int)((table->ACPILevel.SclkSetting.Pcc_fcw_int) = (__uint16_t)
(__builtin_constant_p(table->ACPILevel.SclkSetting.Pcc_fcw_int
) ? (__uint16_t)(((__uint16_t)(table->ACPILevel.SclkSetting
.Pcc_fcw_int) & 0xffU) << 8 | ((__uint16_t)(table->
ACPILevel.SclkSetting.Pcc_fcw_int) & 0xff00U) >> 8)
: __swap16md(table->ACPILevel.SclkSetting.Pcc_fcw_int)))
;
1155 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_slew_rate)((table->ACPILevel.SclkSetting.Sclk_slew_rate) = (__uint16_t
)(__builtin_constant_p(table->ACPILevel.SclkSetting.Sclk_slew_rate
) ? (__uint16_t)(((__uint16_t)(table->ACPILevel.SclkSetting
.Sclk_slew_rate) & 0xffU) << 8 | ((__uint16_t)(table
->ACPILevel.SclkSetting.Sclk_slew_rate) & 0xff00U) >>
8) : __swap16md(table->ACPILevel.SclkSetting.Sclk_slew_rate
)))
;
1156 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_up_slew_rate)((table->ACPILevel.SclkSetting.Pcc_up_slew_rate) = (__uint16_t
)(__builtin_constant_p(table->ACPILevel.SclkSetting.Pcc_up_slew_rate
) ? (__uint16_t)(((__uint16_t)(table->ACPILevel.SclkSetting
.Pcc_up_slew_rate) & 0xffU) << 8 | ((__uint16_t)(table
->ACPILevel.SclkSetting.Pcc_up_slew_rate) & 0xff00U) >>
8) : __swap16md(table->ACPILevel.SclkSetting.Pcc_up_slew_rate
)))
;
1157 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_down_slew_rate)((table->ACPILevel.SclkSetting.Pcc_down_slew_rate) = (__uint16_t
)(__builtin_constant_p(table->ACPILevel.SclkSetting.Pcc_down_slew_rate
) ? (__uint16_t)(((__uint16_t)(table->ACPILevel.SclkSetting
.Pcc_down_slew_rate) & 0xffU) << 8 | ((__uint16_t)(
table->ACPILevel.SclkSetting.Pcc_down_slew_rate) & 0xff00U
) >> 8) : __swap16md(table->ACPILevel.SclkSetting.Pcc_down_slew_rate
)))
;
1158 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_int)((table->ACPILevel.SclkSetting.Fcw1_int) = (__uint16_t)(__builtin_constant_p
(table->ACPILevel.SclkSetting.Fcw1_int) ? (__uint16_t)(((__uint16_t
)(table->ACPILevel.SclkSetting.Fcw1_int) & 0xffU) <<
8 | ((__uint16_t)(table->ACPILevel.SclkSetting.Fcw1_int) &
0xff00U) >> 8) : __swap16md(table->ACPILevel.SclkSetting
.Fcw1_int)))
;
1159 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac)((table->ACPILevel.SclkSetting.Fcw1_frac) = (__uint16_t)(__builtin_constant_p
(table->ACPILevel.SclkSetting.Fcw1_frac) ? (__uint16_t)(((
__uint16_t)(table->ACPILevel.SclkSetting.Fcw1_frac) & 0xffU
) << 8 | ((__uint16_t)(table->ACPILevel.SclkSetting.
Fcw1_frac) & 0xff00U) >> 8) : __swap16md(table->
ACPILevel.SclkSetting.Fcw1_frac)))
;
1160 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate)((table->ACPILevel.SclkSetting.Sclk_ss_slew_rate) = (__uint16_t
)(__builtin_constant_p(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate
) ? (__uint16_t)(((__uint16_t)(table->ACPILevel.SclkSetting
.Sclk_ss_slew_rate) & 0xffU) << 8 | ((__uint16_t)(table
->ACPILevel.SclkSetting.Sclk_ss_slew_rate) & 0xff00U) >>
8) : __swap16md(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate
)))
;
1161
1162
1163 /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
1164 table->MemoryACPILevel.MclkFrequency = data->vbios_boot_state.mclk_bootup_value;
1165 result = vegam_get_dependency_volt_by_clk(hwmgr,
1166 table_info->vdd_dep_on_mclk,
1167 table->MemoryACPILevel.MclkFrequency,
1168 &table->MemoryACPILevel.MinVoltage, &mvdd);
1169 PP_ASSERT_WITH_CODE((0 == result),do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "Cannot find ACPI VDDCI voltage value " "in Clock Dependency Table"
); ; } } while (0)
1170 "Cannot find ACPI VDDCI voltage value "do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "Cannot find ACPI VDDCI voltage value " "in Clock Dependency Table"
); ; } } while (0)
1171 "in Clock Dependency Table",do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "Cannot find ACPI VDDCI voltage value " "in Clock Dependency Table"
); ; } } while (0)
1172 )do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "Cannot find ACPI VDDCI voltage value " "in Clock Dependency Table"
); ; } } while (0)
;
1173
1174 if (!vegam_populate_mvdd_value(hwmgr, 0, &vol_level))
1175 table->MemoryACPILevel.MinMvdd = PP_HOST_TO_SMC_UL(vol_level.Voltage)(__uint32_t)(__builtin_constant_p(vol_level.Voltage) ? (__uint32_t
)(((__uint32_t)(vol_level.Voltage) & 0xff) << 24 | (
(__uint32_t)(vol_level.Voltage) & 0xff00) << 8 | ((
__uint32_t)(vol_level.Voltage) & 0xff0000) >> 8 | (
(__uint32_t)(vol_level.Voltage) & 0xff000000) >> 24
) : __swap32md(vol_level.Voltage))
;
1176 else
1177 table->MemoryACPILevel.MinMvdd = 0;
1178
1179 table->MemoryACPILevel.StutterEnable = false0;
1180
1181 table->MemoryACPILevel.EnabledForThrottle = 0;
1182 table->MemoryACPILevel.EnabledForActivity = 0;
1183 table->MemoryACPILevel.UpHyst = 0;
1184 table->MemoryACPILevel.DownHyst = 100;
1185 table->MemoryACPILevel.VoltageDownHyst = 0;
1186 table->MemoryACPILevel.ActivityLevel =
1187 PP_HOST_TO_SMC_US(data->current_profile_setting.mclk_activity)(__uint16_t)(__builtin_constant_p(data->current_profile_setting
.mclk_activity) ? (__uint16_t)(((__uint16_t)(data->current_profile_setting
.mclk_activity) & 0xffU) << 8 | ((__uint16_t)(data->
current_profile_setting.mclk_activity) & 0xff00U) >>
8) : __swap16md(data->current_profile_setting.mclk_activity
))
;
1188
1189 CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency)((table->MemoryACPILevel.MclkFrequency) = (__uint32_t)(__builtin_constant_p
(table->MemoryACPILevel.MclkFrequency) ? (__uint32_t)(((__uint32_t
)(table->MemoryACPILevel.MclkFrequency) & 0xff) <<
24 | ((__uint32_t)(table->MemoryACPILevel.MclkFrequency) &
0xff00) << 8 | ((__uint32_t)(table->MemoryACPILevel
.MclkFrequency) & 0xff0000) >> 8 | ((__uint32_t)(table
->MemoryACPILevel.MclkFrequency) & 0xff000000) >>
24) : __swap32md(table->MemoryACPILevel.MclkFrequency)))
;
1190 CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage)((table->MemoryACPILevel.MinVoltage) = (__uint32_t)(__builtin_constant_p
(table->MemoryACPILevel.MinVoltage) ? (__uint32_t)(((__uint32_t
)(table->MemoryACPILevel.MinVoltage) & 0xff) << 24
| ((__uint32_t)(table->MemoryACPILevel.MinVoltage) & 0xff00
) << 8 | ((__uint32_t)(table->MemoryACPILevel.MinVoltage
) & 0xff0000) >> 8 | ((__uint32_t)(table->MemoryACPILevel
.MinVoltage) & 0xff000000) >> 24) : __swap32md(table
->MemoryACPILevel.MinVoltage)))
;
1191
1192 return result;
1193}
1194
1195static int vegam_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
1196 SMU75_Discrete_DpmTable *table)
1197{
1198 int result = -EINVAL22;
1199 uint8_t count;
1200 struct pp_atomctrl_clock_dividers_vi dividers;
1201 struct phm_ppt_v1_information *table_info =
1202 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1203 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
1204 table_info->mm_dep_table;
1205 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1206 uint32_t vddci;
1207
1208 table->VceLevelCount = (uint8_t)(mm_table->count);
1209 table->VceBootLevel = 0;
1210
1211 for (count = 0; count < table->VceLevelCount; count++) {
1212 table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
1213 table->VceLevel[count].MinVoltage = 0;
1214 table->VceLevel[count].MinVoltage |=
1215 (mm_table->entries[count].vddc * VOLTAGE_SCALE4) << VDDC_SHIFT0;
1216
1217 if (SMU7_VOLTAGE_CONTROL_BY_GPIO0x1 == data->vddci_control)
1218 vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
1219 mm_table->entries[count].vddc - VDDC_VDDCI_DELTA200);
1220 else if (SMU7_VOLTAGE_CONTROL_BY_SVID20x2 == data->vddci_control)
1221 vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA200;
1222 else
1223 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE4) << VDDCI_SHIFT15;
1224
1225
1226 table->VceLevel[count].MinVoltage |=
1227 (vddci * VOLTAGE_SCALE4) << VDDCI_SHIFT15;
1228 table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT30;
1229
1230 /*retrieve divider value for VBIOS */
1231 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1232 table->VceLevel[count].Frequency, &dividers);
1233 PP_ASSERT_WITH_CODE((0 == result),do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for VCE engine clock"); return result
; } } while (0)
1234 "can not find divide id for VCE engine clock",do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for VCE engine clock"); return result
; } } while (0)
1235 return result)do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for VCE engine clock"); return result
; } } while (0)
;
1236
1237 table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
1238
1239 CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency)((table->VceLevel[count].Frequency) = (__uint32_t)(__builtin_constant_p
(table->VceLevel[count].Frequency) ? (__uint32_t)(((__uint32_t
)(table->VceLevel[count].Frequency) & 0xff) << 24
| ((__uint32_t)(table->VceLevel[count].Frequency) & 0xff00
) << 8 | ((__uint32_t)(table->VceLevel[count].Frequency
) & 0xff0000) >> 8 | ((__uint32_t)(table->VceLevel
[count].Frequency) & 0xff000000) >> 24) : __swap32md
(table->VceLevel[count].Frequency)))
;
1240 CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage)((table->VceLevel[count].MinVoltage) = (__uint32_t)(__builtin_constant_p
(table->VceLevel[count].MinVoltage) ? (__uint32_t)(((__uint32_t
)(table->VceLevel[count].MinVoltage) & 0xff) << 24
| ((__uint32_t)(table->VceLevel[count].MinVoltage) & 0xff00
) << 8 | ((__uint32_t)(table->VceLevel[count].MinVoltage
) & 0xff0000) >> 8 | ((__uint32_t)(table->VceLevel
[count].MinVoltage) & 0xff000000) >> 24) : __swap32md
(table->VceLevel[count].MinVoltage)))
;
1241 }
1242 return result;
1243}
1244
1245static int vegam_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr,
1246 int32_t eng_clock, int32_t mem_clock,
1247 SMU75_Discrete_MCArbDramTimingTableEntry *arb_regs)
1248{
1249 uint32_t dram_timing;
1250 uint32_t dram_timing2;
1251 uint32_t burst_time;
1252 uint32_t rfsh_rate;
1253 uint32_t misc3;
1254
1255 int result;
1256
1257 result = atomctrl_set_engine_dram_timings_rv770(hwmgr,
1258 eng_clock, mem_clock);
1259 PP_ASSERT_WITH_CODE(result == 0,do { if (!(result == 0)) { printk("\0014" "amdgpu: " "%s\n", "Error calling VBIOS to set DRAM_TIMING."
); return result; } } while (0)
1260 "Error calling VBIOS to set DRAM_TIMING.",do { if (!(result == 0)) { printk("\0014" "amdgpu: " "%s\n", "Error calling VBIOS to set DRAM_TIMING."
); return result; } } while (0)
1261 return result)do { if (!(result == 0)) { printk("\0014" "amdgpu: " "%s\n", "Error calling VBIOS to set DRAM_TIMING."
); return result; } } while (0)
;
1262
1263 dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING)(((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x9dd))
;
1264 dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2)(((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x9de))
;
1265 burst_time = cgs_read_register(hwmgr->device, mmMC_ARB_BURST_TIME)(((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0xa02))
;
1266 rfsh_rate = cgs_read_register(hwmgr->device, mmMC_ARB_RFSH_RATE)(((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x9ec))
;
1267 misc3 = cgs_read_register(hwmgr->device, mmMC_ARB_MISC3)(((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x9cd))
;
1268
1269 arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dram_timing)(__uint32_t)(__builtin_constant_p(dram_timing) ? (__uint32_t)
(((__uint32_t)(dram_timing) & 0xff) << 24 | ((__uint32_t
)(dram_timing) & 0xff00) << 8 | ((__uint32_t)(dram_timing
) & 0xff0000) >> 8 | ((__uint32_t)(dram_timing) &
0xff000000) >> 24) : __swap32md(dram_timing))
;
1270 arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2)(__uint32_t)(__builtin_constant_p(dram_timing2) ? (__uint32_t
)(((__uint32_t)(dram_timing2) & 0xff) << 24 | ((__uint32_t
)(dram_timing2) & 0xff00) << 8 | ((__uint32_t)(dram_timing2
) & 0xff0000) >> 8 | ((__uint32_t)(dram_timing2) &
0xff000000) >> 24) : __swap32md(dram_timing2))
;
1271 arb_regs->McArbBurstTime = PP_HOST_TO_SMC_UL(burst_time)(__uint32_t)(__builtin_constant_p(burst_time) ? (__uint32_t)(
((__uint32_t)(burst_time) & 0xff) << 24 | ((__uint32_t
)(burst_time) & 0xff00) << 8 | ((__uint32_t)(burst_time
) & 0xff0000) >> 8 | ((__uint32_t)(burst_time) &
0xff000000) >> 24) : __swap32md(burst_time))
;
1272 arb_regs->McArbRfshRate = PP_HOST_TO_SMC_UL(rfsh_rate)(__uint32_t)(__builtin_constant_p(rfsh_rate) ? (__uint32_t)((
(__uint32_t)(rfsh_rate) & 0xff) << 24 | ((__uint32_t
)(rfsh_rate) & 0xff00) << 8 | ((__uint32_t)(rfsh_rate
) & 0xff0000) >> 8 | ((__uint32_t)(rfsh_rate) &
0xff000000) >> 24) : __swap32md(rfsh_rate))
;
1273 arb_regs->McArbMisc3 = PP_HOST_TO_SMC_UL(misc3)(__uint32_t)(__builtin_constant_p(misc3) ? (__uint32_t)(((__uint32_t
)(misc3) & 0xff) << 24 | ((__uint32_t)(misc3) &
0xff00) << 8 | ((__uint32_t)(misc3) & 0xff0000) >>
8 | ((__uint32_t)(misc3) & 0xff000000) >> 24) : __swap32md
(misc3))
;
1274
1275 return 0;
1276}
1277
1278static int vegam_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
1279{
1280 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1281 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1282 struct SMU75_Discrete_MCArbDramTimingTable arb_regs;
1283 uint32_t i, j;
1284 int result = 0;
1285
1286 memset(&arb_regs, 0, sizeof(SMU75_Discrete_MCArbDramTimingTable))__builtin_memset((&arb_regs), (0), (sizeof(SMU75_Discrete_MCArbDramTimingTable
)))
;
1287
1288 for (i = 0; i < hw_data->dpm_table.sclk_table.count; i++) {
1289 for (j = 0; j < hw_data->dpm_table.mclk_table.count; j++) {
1290 result = vegam_populate_memory_timing_parameters(hwmgr,
1291 hw_data->dpm_table.sclk_table.dpm_levels[i].value,
1292 hw_data->dpm_table.mclk_table.dpm_levels[j].value,
1293 &arb_regs.entries[i][j]);
1294 if (result)
1295 return result;
1296 }
1297 }
1298
1299 result = smu7_copy_bytes_to_smc(
1300 hwmgr,
1301 smu_data->smu7_data.arb_table_start,
1302 (uint8_t *)&arb_regs,
1303 sizeof(SMU75_Discrete_MCArbDramTimingTable),
1304 SMC_RAM_END0x40000);
1305 return result;
1306}
1307
1308static int vegam_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
1309 struct SMU75_Discrete_DpmTable *table)
1310{
1311 int result = -EINVAL22;
1312 uint8_t count;
1313 struct pp_atomctrl_clock_dividers_vi dividers;
1314 struct phm_ppt_v1_information *table_info =
1315 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1316 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
1317 table_info->mm_dep_table;
1318 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1319 uint32_t vddci;
1320
1321 table->UvdLevelCount = (uint8_t)(mm_table->count);
1322 table->UvdBootLevel = 0;
1323
1324 for (count = 0; count < table->UvdLevelCount; count++) {
1325 table->UvdLevel[count].MinVoltage = 0;
1326 table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
1327 table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
1328 table->UvdLevel[count].MinVoltage |=
1329 (mm_table->entries[count].vddc * VOLTAGE_SCALE4) << VDDC_SHIFT0;
1330
1331 if (SMU7_VOLTAGE_CONTROL_BY_GPIO0x1 == data->vddci_control)
1332 vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
1333 mm_table->entries[count].vddc - VDDC_VDDCI_DELTA200);
1334 else if (SMU7_VOLTAGE_CONTROL_BY_SVID20x2 == data->vddci_control)
1335 vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA200;
1336 else
1337 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE4) << VDDCI_SHIFT15;
1338
1339 table->UvdLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE4) << VDDCI_SHIFT15;
1340 table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT30;
1341
1342 /* retrieve divider value for VBIOS */
1343 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1344 table->UvdLevel[count].VclkFrequency, &dividers);
1345 PP_ASSERT_WITH_CODE((0 == result),do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for Vclk clock"); return result; } }
while (0)
1346 "can not find divide id for Vclk clock", return result)do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for Vclk clock"); return result; } }
while (0)
;
1347
1348 table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider;
1349
1350 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1351 table->UvdLevel[count].DclkFrequency, &dividers);
1352 PP_ASSERT_WITH_CODE((0 == result),do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for Dclk clock"); return result; } }
while (0)
1353 "can not find divide id for Dclk clock", return result)do { if (!((0 == result))) { printk("\0014" "amdgpu: " "%s\n"
, "can not find divide id for Dclk clock"); return result; } }
while (0)
;
1354
1355 table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider;
1356
1357 CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency)((table->UvdLevel[count].VclkFrequency) = (__uint32_t)(__builtin_constant_p
(table->UvdLevel[count].VclkFrequency) ? (__uint32_t)(((__uint32_t
)(table->UvdLevel[count].VclkFrequency) & 0xff) <<
24 | ((__uint32_t)(table->UvdLevel[count].VclkFrequency) &
0xff00) << 8 | ((__uint32_t)(table->UvdLevel[count]
.VclkFrequency) & 0xff0000) >> 8 | ((__uint32_t)(table
->UvdLevel[count].VclkFrequency) & 0xff000000) >>
24) : __swap32md(table->UvdLevel[count].VclkFrequency)))
;
1358 CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency)((table->UvdLevel[count].DclkFrequency) = (__uint32_t)(__builtin_constant_p
(table->UvdLevel[count].DclkFrequency) ? (__uint32_t)(((__uint32_t
)(table->UvdLevel[count].DclkFrequency) & 0xff) <<
24 | ((__uint32_t)(table->UvdLevel[count].DclkFrequency) &
0xff00) << 8 | ((__uint32_t)(table->UvdLevel[count]
.DclkFrequency) & 0xff0000) >> 8 | ((__uint32_t)(table
->UvdLevel[count].DclkFrequency) & 0xff000000) >>
24) : __swap32md(table->UvdLevel[count].DclkFrequency)))
;
1359 CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage)((table->UvdLevel[count].MinVoltage) = (__uint32_t)(__builtin_constant_p
(table->UvdLevel[count].MinVoltage) ? (__uint32_t)(((__uint32_t
)(table->UvdLevel[count].MinVoltage) & 0xff) << 24
| ((__uint32_t)(table->UvdLevel[count].MinVoltage) & 0xff00
) << 8 | ((__uint32_t)(table->UvdLevel[count].MinVoltage
) & 0xff0000) >> 8 | ((__uint32_t)(table->UvdLevel
[count].MinVoltage) & 0xff000000) >> 24) : __swap32md
(table->UvdLevel[count].MinVoltage)))
;
1360 }
1361
1362 return result;
1363}
1364
1365static int vegam_populate_smc_boot_level(struct pp_hwmgr *hwmgr,
1366 struct SMU75_Discrete_DpmTable *table)
1367{
1368 int result = 0;
1369 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1370
1371 table->GraphicsBootLevel = 0;
1372 table->MemoryBootLevel = 0;
1373
1374 /* find boot level from dpm table */
1375 result = phm_find_boot_level(&(data->dpm_table.sclk_table),
1376 data->vbios_boot_state.sclk_bootup_value,
1377 (uint32_t *)&(table->GraphicsBootLevel));
1378 if (result)
1379 return result;
1380
1381 result = phm_find_boot_level(&(data->dpm_table.mclk_table),
1382 data->vbios_boot_state.mclk_bootup_value,
1383 (uint32_t *)&(table->MemoryBootLevel));
1384
1385 if (result)
1386 return result;
1387
1388 table->BootVddc = data->vbios_boot_state.vddc_bootup_value *
1389 VOLTAGE_SCALE4;
1390 table->BootVddci = data->vbios_boot_state.vddci_bootup_value *
1391 VOLTAGE_SCALE4;
1392 table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value *
1393 VOLTAGE_SCALE4;
1394
1395 CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc)((table->BootVddc) = (__uint16_t)(__builtin_constant_p(table
->BootVddc) ? (__uint16_t)(((__uint16_t)(table->BootVddc
) & 0xffU) << 8 | ((__uint16_t)(table->BootVddc)
& 0xff00U) >> 8) : __swap16md(table->BootVddc))
)
;
1396 CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci)((table->BootVddci) = (__uint16_t)(__builtin_constant_p(table
->BootVddci) ? (__uint16_t)(((__uint16_t)(table->BootVddci
) & 0xffU) << 8 | ((__uint16_t)(table->BootVddci
) & 0xff00U) >> 8) : __swap16md(table->BootVddci
)))
;
1397 CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd)((table->BootMVdd) = (__uint16_t)(__builtin_constant_p(table
->BootMVdd) ? (__uint16_t)(((__uint16_t)(table->BootMVdd
) & 0xffU) << 8 | ((__uint16_t)(table->BootMVdd)
& 0xff00U) >> 8) : __swap16md(table->BootMVdd))
)
;
1398
1399 return 0;
1400}
1401
1402static int vegam_populate_smc_initial_state(struct pp_hwmgr *hwmgr)
1403{
1404 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1405 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1406 struct phm_ppt_v1_information *table_info =
1407 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1408 uint8_t count, level;
1409
1410 count = (uint8_t)(table_info->vdd_dep_on_sclk->count);
1411
1412 for (level = 0; level < count; level++) {
1413 if (table_info->vdd_dep_on_sclk->entries[level].clk >=
1414 hw_data->vbios_boot_state.sclk_bootup_value) {
1415 smu_data->smc_state_table.GraphicsBootLevel = level;
1416 break;
1417 }
1418 }
1419
1420 count = (uint8_t)(table_info->vdd_dep_on_mclk->count);
1421 for (level = 0; level < count; level++) {
1422 if (table_info->vdd_dep_on_mclk->entries[level].clk >=
1423 hw_data->vbios_boot_state.mclk_bootup_value) {
1424 smu_data->smc_state_table.MemoryBootLevel = level;
1425 break;
1426 }
1427 }
1428
1429 return 0;
1430}
1431
1432static uint16_t scale_fan_gain_settings(uint16_t raw_setting)
1433{
1434 uint32_t tmp;
1435 tmp = raw_setting * 4096 / 100;
1436 return (uint16_t)tmp;
1437}
1438
1439static int vegam_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr)
1440{
1441 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1442
1443 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1444 SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1445 struct phm_ppt_v1_information *table_info =
1446 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1447 struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table;
1448 struct pp_advance_fan_control_parameters *fan_table =
1449 &hwmgr->thermal_controller.advanceFanControlParameters;
1450 int i, j, k;
1451 const uint16_t *pdef1;
1452 const uint16_t *pdef2;
1453
1454 table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128))(__uint16_t)(__builtin_constant_p((uint16_t)(cac_dtp_table->
usTDP * 128)) ? (__uint16_t)(((__uint16_t)((uint16_t)(cac_dtp_table
->usTDP * 128)) & 0xffU) << 8 | ((__uint16_t)((uint16_t
)(cac_dtp_table->usTDP * 128)) & 0xff00U) >> 8) :
__swap16md((uint16_t)(cac_dtp_table->usTDP * 128)))
;
1455 table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128))(__uint16_t)(__builtin_constant_p((uint16_t)(cac_dtp_table->
usTDP * 128)) ? (__uint16_t)(((__uint16_t)((uint16_t)(cac_dtp_table
->usTDP * 128)) & 0xffU) << 8 | ((__uint16_t)((uint16_t
)(cac_dtp_table->usTDP * 128)) & 0xff00U) >> 8) :
__swap16md((uint16_t)(cac_dtp_table->usTDP * 128)))
;
1456
1457 PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255,do { if (!(cac_dtp_table->usTargetOperatingTemp <= 255)
) { printk("\0014" "amdgpu: " "%s\n", "Target Operating Temp is out of Range!"
); ; } } while (0)
1458 "Target Operating Temp is out of Range!",do { if (!(cac_dtp_table->usTargetOperatingTemp <= 255)
) { printk("\0014" "amdgpu: " "%s\n", "Target Operating Temp is out of Range!"
); ; } } while (0)
1459 )do { if (!(cac_dtp_table->usTargetOperatingTemp <= 255)
) { printk("\0014" "amdgpu: " "%s\n", "Target Operating Temp is out of Range!"
); ; } } while (0)
;
1460
1461 table->TemperatureLimitEdge = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(cac_dtp_table->usTargetOperatingTemp
* 256) ? (__uint16_t)(((__uint16_t)(cac_dtp_table->usTargetOperatingTemp
* 256) & 0xffU) << 8 | ((__uint16_t)(cac_dtp_table
->usTargetOperatingTemp * 256) & 0xff00U) >> 8) :
__swap16md(cac_dtp_table->usTargetOperatingTemp * 256))
1462 cac_dtp_table->usTargetOperatingTemp * 256)(__uint16_t)(__builtin_constant_p(cac_dtp_table->usTargetOperatingTemp
* 256) ? (__uint16_t)(((__uint16_t)(cac_dtp_table->usTargetOperatingTemp
* 256) & 0xffU) << 8 | ((__uint16_t)(cac_dtp_table
->usTargetOperatingTemp * 256) & 0xff00U) >> 8) :
__swap16md(cac_dtp_table->usTargetOperatingTemp * 256))
;
1463 table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(cac_dtp_table->usTemperatureLimitHotspot
* 256) ? (__uint16_t)(((__uint16_t)(cac_dtp_table->usTemperatureLimitHotspot
* 256) & 0xffU) << 8 | ((__uint16_t)(cac_dtp_table
->usTemperatureLimitHotspot * 256) & 0xff00U) >>
8) : __swap16md(cac_dtp_table->usTemperatureLimitHotspot *
256))
1464 cac_dtp_table->usTemperatureLimitHotspot * 256)(__uint16_t)(__builtin_constant_p(cac_dtp_table->usTemperatureLimitHotspot
* 256) ? (__uint16_t)(((__uint16_t)(cac_dtp_table->usTemperatureLimitHotspot
* 256) & 0xffU) << 8 | ((__uint16_t)(cac_dtp_table
->usTemperatureLimitHotspot * 256) & 0xff00U) >>
8) : __swap16md(cac_dtp_table->usTemperatureLimitHotspot *
256))
;
1465 table->FanGainEdge = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(scale_fan_gain_settings(fan_table
->usFanGainEdge)) ? (__uint16_t)(((__uint16_t)(scale_fan_gain_settings
(fan_table->usFanGainEdge)) & 0xffU) << 8 | ((__uint16_t
)(scale_fan_gain_settings(fan_table->usFanGainEdge)) &
0xff00U) >> 8) : __swap16md(scale_fan_gain_settings(fan_table
->usFanGainEdge)))
1466 scale_fan_gain_settings(fan_table->usFanGainEdge))(__uint16_t)(__builtin_constant_p(scale_fan_gain_settings(fan_table
->usFanGainEdge)) ? (__uint16_t)(((__uint16_t)(scale_fan_gain_settings
(fan_table->usFanGainEdge)) & 0xffU) << 8 | ((__uint16_t
)(scale_fan_gain_settings(fan_table->usFanGainEdge)) &
0xff00U) >> 8) : __swap16md(scale_fan_gain_settings(fan_table
->usFanGainEdge)))
;
1467 table->FanGainHotspot = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(scale_fan_gain_settings(fan_table
->usFanGainHotspot)) ? (__uint16_t)(((__uint16_t)(scale_fan_gain_settings
(fan_table->usFanGainHotspot)) & 0xffU) << 8 | (
(__uint16_t)(scale_fan_gain_settings(fan_table->usFanGainHotspot
)) & 0xff00U) >> 8) : __swap16md(scale_fan_gain_settings
(fan_table->usFanGainHotspot)))
1468 scale_fan_gain_settings(fan_table->usFanGainHotspot))(__uint16_t)(__builtin_constant_p(scale_fan_gain_settings(fan_table
->usFanGainHotspot)) ? (__uint16_t)(((__uint16_t)(scale_fan_gain_settings
(fan_table->usFanGainHotspot)) & 0xffU) << 8 | (
(__uint16_t)(scale_fan_gain_settings(fan_table->usFanGainHotspot
)) & 0xff00U) >> 8) : __swap16md(scale_fan_gain_settings
(fan_table->usFanGainHotspot)))
;
1469
1470 pdef1 = defaults->BAPMTI_R;
1471 pdef2 = defaults->BAPMTI_RC;
1472
1473 for (i = 0; i < SMU75_DTE_ITERATIONS5; i++) {
1474 for (j = 0; j < SMU75_DTE_SOURCES3; j++) {
1475 for (k = 0; k < SMU75_DTE_SINKS1; k++) {
1476 table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1)(__uint16_t)(__builtin_constant_p(*pdef1) ? (__uint16_t)(((__uint16_t
)(*pdef1) & 0xffU) << 8 | ((__uint16_t)(*pdef1) &
0xff00U) >> 8) : __swap16md(*pdef1))
;
1477 table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2)(__uint16_t)(__builtin_constant_p(*pdef2) ? (__uint16_t)(((__uint16_t
)(*pdef2) & 0xffU) << 8 | ((__uint16_t)(*pdef2) &
0xff00U) >> 8) : __swap16md(*pdef2))
;
1478 pdef1++;
1479 pdef2++;
1480 }
1481 }
1482 }
1483
1484 return 0;
1485}
1486
1487static int vegam_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
1488{
1489 uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min;
1490 struct vegam_smumgr *smu_data =
1491 (struct vegam_smumgr *)(hwmgr->smu_backend);
1492
1493 uint8_t i, stretch_amount, volt_offset = 0;
1494 struct phm_ppt_v1_information *table_info =
1495 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1496 struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
1497 table_info->vdd_dep_on_sclk;
1498 uint32_t mask = (1 << ((STRAP_ASIC_RO_MSB2175 - STRAP_ASIC_RO_LSB2168) + 1)) - 1;
1499
1500 stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount;
1501
1502 atomctrl_read_efuse(hwmgr, STRAP_ASIC_RO_LSB2168, STRAP_ASIC_RO_MSB2175,
1503 mask, &efuse);
1504
1505 min = 1200;
1506 max = 2500;
1507
1508 ro = efuse * (max - min) / 255 + min;
1509
1510 /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
1511 for (i = 0; i < sclk_table->count; i++) {
1512 smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |=
1513 sclk_table->entries[i].cks_enable << i;
1514 volt_without_cks = (uint32_t)((2753594000U + (sclk_table->entries[i].clk/100) *
1515 136418 - (ro - 70) * 1000000) /
1516 (2424180 - (sclk_table->entries[i].clk/100) * 1132925/1000));
1517 volt_with_cks = (uint32_t)((2797202000U + sclk_table->entries[i].clk/100 *
1518 3232 - (ro - 65) * 1000000) /
1519 (2522480 - sclk_table->entries[i].clk/100 * 115764/100));
1520
1521 if (volt_without_cks >= volt_with_cks)
1522 volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks +
1523 sclk_table->entries[i].cks_voffset) * 100 + 624) / 625);
1524
1525 smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
1526 }
1527
1528 smu_data->smc_state_table.LdoRefSel =
1529 (table_info->cac_dtp_table->ucCKS_LDO_REFSEL != 0) ?
1530 table_info->cac_dtp_table->ucCKS_LDO_REFSEL : 5;
1531 /* Populate CKS Lookup Table */
1532 if (!(stretch_amount == 1 || stretch_amount == 2 ||
1533 stretch_amount == 5 || stretch_amount == 3 ||
1534 stretch_amount == 4)) {
1535 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
1536 PHM_PlatformCaps_ClockStretcher);
1537 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Stretch Amount in PPTable not supported\n"
); return -22; } } while (0)
1538 "Stretch Amount in PPTable not supported\n",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Stretch Amount in PPTable not supported\n"
); return -22; } } while (0)
1539 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Stretch Amount in PPTable not supported\n"
); return -22; } } while (0)
;
1540 }
1541
1542 value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL)(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xc0200350))
;
1543 value &= 0xFFFFFFFE;
1544 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xc0200350,value))
;
1545
1546 return 0;
1547}
1548
1549static bool_Bool vegam_is_hw_avfs_present(struct pp_hwmgr *hwmgr)
1550{
1551 uint32_t efuse;
1552
1553 efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xc0100000 + (49 * 4)))
1554 ixSMU_EFUSE_0 + (49 * 4))(((struct cgs_device *)hwmgr->device)->ops->read_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xc0100000 + (49 * 4)))
;
1555 efuse &= 0x00000001;
1556
1557 if (efuse)
1558 return true1;
1559
1560 return false0;
1561}
1562
1563static int vegam_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
1564{
1565 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1566 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1567
1568 SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1569 int result = 0;
1570 struct pp_atom_ctrl__avfs_parameters avfs_params = {0};
1571 AVFS_meanNsigma_t AVFS_meanNsigma = { {0} };
1572 AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} };
1573 uint32_t tmp, i;
1574
1575 struct phm_ppt_v1_information *table_info =
1576 (struct phm_ppt_v1_information *)hwmgr->pptable;
1577 struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
1578 table_info->vdd_dep_on_sclk;
1579
1580 if (!hwmgr->avfs_supported)
1581 return 0;
1582
1583 result = atomctrl_get_avfs_information(hwmgr, &avfs_params);
1584
1585 if (0 == result) {
1586 table->BTCGB_VDROOP_TABLE[0].a0 =
1587 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0)(__uint32_t)(__builtin_constant_p(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0
))
;
1588 table->BTCGB_VDROOP_TABLE[0].a1 =
1589 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1)(__uint32_t)(__builtin_constant_p(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1
))
;
1590 table->BTCGB_VDROOP_TABLE[0].a2 =
1591 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2)(__uint32_t)(__builtin_constant_p(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2
))
;
1592 table->BTCGB_VDROOP_TABLE[1].a0 =
1593 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0)(__uint32_t)(__builtin_constant_p(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0
))
;
1594 table->BTCGB_VDROOP_TABLE[1].a1 =
1595 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1)(__uint32_t)(__builtin_constant_p(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1
))
;
1596 table->BTCGB_VDROOP_TABLE[1].a2 =
1597 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2)(__uint32_t)(__builtin_constant_p(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2
))
;
1598 table->AVFSGB_FUSE_TABLE[0].m1 =
1599 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1
))
;
1600 table->AVFSGB_FUSE_TABLE[0].m2 =
1601 PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2)(__uint16_t)(__builtin_constant_p(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2
) ? (__uint16_t)(((__uint16_t)(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2
) & 0xff00U) >> 8) : __swap16md(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2
))
;
1602 table->AVFSGB_FUSE_TABLE[0].b =
1603 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b
))
;
1604 table->AVFSGB_FUSE_TABLE[0].m1_shift = 24;
1605 table->AVFSGB_FUSE_TABLE[0].m2_shift = 12;
1606 table->AVFSGB_FUSE_TABLE[1].m1 =
1607 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
))
;
1608 table->AVFSGB_FUSE_TABLE[1].m2 =
1609 PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2)(__uint16_t)(__builtin_constant_p(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2
) ? (__uint16_t)(((__uint16_t)(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2
) & 0xff00U) >> 8) : __swap16md(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2
))
;
1610 table->AVFSGB_FUSE_TABLE[1].b =
1611 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b
))
;
1612 table->AVFSGB_FUSE_TABLE[1].m1_shift = 24;
1613 table->AVFSGB_FUSE_TABLE[1].m2_shift = 12;
1614 table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv)(__uint16_t)(__builtin_constant_p(avfs_params.usMaxVoltage_0_25mv
) ? (__uint16_t)(((__uint16_t)(avfs_params.usMaxVoltage_0_25mv
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usMaxVoltage_0_25mv
) & 0xff00U) >> 8) : __swap16md(avfs_params.usMaxVoltage_0_25mv
))
;
1615 AVFS_meanNsigma.Aconstant[0] =
1616 PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFS_meanNsigma_Acontant0
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant0
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant0
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant0
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant0
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFS_meanNsigma_Acontant0
))
;
1617 AVFS_meanNsigma.Aconstant[1] =
1618 PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFS_meanNsigma_Acontant1
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant1
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant1
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant1
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant1
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFS_meanNsigma_Acontant1
))
;
1619 AVFS_meanNsigma.Aconstant[2] =
1620 PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2)(__uint32_t)(__builtin_constant_p(avfs_params.ulAVFS_meanNsigma_Acontant2
) ? (__uint32_t)(((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant2
) & 0xff) << 24 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant2
) & 0xff00) << 8 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant2
) & 0xff0000) >> 8 | ((__uint32_t)(avfs_params.ulAVFS_meanNsigma_Acontant2
) & 0xff000000) >> 24) : __swap32md(avfs_params.ulAVFS_meanNsigma_Acontant2
))
;
1621 AVFS_meanNsigma.DC_tol_sigma =
1622 PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma)(__uint16_t)(__builtin_constant_p(avfs_params.usAVFS_meanNsigma_DC_tol_sigma
) ? (__uint16_t)(((__uint16_t)(avfs_params.usAVFS_meanNsigma_DC_tol_sigma
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usAVFS_meanNsigma_DC_tol_sigma
) & 0xff00U) >> 8) : __swap16md(avfs_params.usAVFS_meanNsigma_DC_tol_sigma
))
;
1623 AVFS_meanNsigma.Platform_mean =
1624 PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean)(__uint16_t)(__builtin_constant_p(avfs_params.usAVFS_meanNsigma_Platform_mean
) ? (__uint16_t)(((__uint16_t)(avfs_params.usAVFS_meanNsigma_Platform_mean
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usAVFS_meanNsigma_Platform_mean
) & 0xff00U) >> 8) : __swap16md(avfs_params.usAVFS_meanNsigma_Platform_mean
))
;
1625 AVFS_meanNsigma.PSM_Age_CompFactor =
1626 PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor)(__uint16_t)(__builtin_constant_p(avfs_params.usPSM_Age_ComFactor
) ? (__uint16_t)(((__uint16_t)(avfs_params.usPSM_Age_ComFactor
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usPSM_Age_ComFactor
) & 0xff00U) >> 8) : __swap16md(avfs_params.usPSM_Age_ComFactor
))
;
1627 AVFS_meanNsigma.Platform_sigma =
1628 PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma)(__uint16_t)(__builtin_constant_p(avfs_params.usAVFS_meanNsigma_Platform_sigma
) ? (__uint16_t)(((__uint16_t)(avfs_params.usAVFS_meanNsigma_Platform_sigma
) & 0xffU) << 8 | ((__uint16_t)(avfs_params.usAVFS_meanNsigma_Platform_sigma
) & 0xff00U) >> 8) : __swap16md(avfs_params.usAVFS_meanNsigma_Platform_sigma
))
;
1629
1630 for (i = 0; i < sclk_table->count; i++) {
1631 AVFS_meanNsigma.Static_Voltage_Offset[i] =
1632 (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625);
1633 AVFS_SclkOffset.Sclk_Offset[i] =
1634 PP_HOST_TO_SMC_US((uint16_t)(__uint16_t)(__builtin_constant_p((uint16_t) (sclk_table->
entries[i].sclk_offset) / 100) ? (__uint16_t)(((__uint16_t)((
uint16_t) (sclk_table->entries[i].sclk_offset) / 100) &
0xffU) << 8 | ((__uint16_t)((uint16_t) (sclk_table->
entries[i].sclk_offset) / 100) & 0xff00U) >> 8) : __swap16md
((uint16_t) (sclk_table->entries[i].sclk_offset) / 100))
1635 (sclk_table->entries[i].sclk_offset) / 100)(__uint16_t)(__builtin_constant_p((uint16_t) (sclk_table->
entries[i].sclk_offset) / 100) ? (__uint16_t)(((__uint16_t)((
uint16_t) (sclk_table->entries[i].sclk_offset) / 100) &
0xffU) << 8 | ((__uint16_t)((uint16_t) (sclk_table->
entries[i].sclk_offset) / 100) & 0xff00U) >> 8) : __swap16md
((uint16_t) (sclk_table->entries[i].sclk_offset) / 100))
;
1636 }
1637
1638 result = smu7_read_smc_sram_dword(hwmgr,
1639 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
1640 offsetof(SMU75_Firmware_Header, AvfsMeanNSigma)__builtin_offsetof(SMU75_Firmware_Header, AvfsMeanNSigma),
1641 &tmp, SMC_RAM_END0x40000);
1642 smu7_copy_bytes_to_smc(hwmgr,
1643 tmp,
1644 (uint8_t *)&AVFS_meanNsigma,
1645 sizeof(AVFS_meanNsigma_t),
1646 SMC_RAM_END0x40000);
1647
1648 result = smu7_read_smc_sram_dword(hwmgr,
1649 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
1650 offsetof(SMU75_Firmware_Header, AvfsSclkOffsetTable)__builtin_offsetof(SMU75_Firmware_Header, AvfsSclkOffsetTable
)
,
1651 &tmp, SMC_RAM_END0x40000);
1652 smu7_copy_bytes_to_smc(hwmgr,
1653 tmp,
1654 (uint8_t *)&AVFS_SclkOffset,
1655 sizeof(AVFS_Sclk_Offset_t),
1656 SMC_RAM_END0x40000);
1657
1658 data->avfs_vdroop_override_setting =
1659 (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT0) |
1660 (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT1) |
1661 (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT2) |
1662 (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT3);
1663 data->apply_avfs_cks_off_voltage =
1664 (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true1 : false0;
1665 }
1666 return result;
1667}
1668
1669static int vegam_populate_vr_config(struct pp_hwmgr *hwmgr,
1670 struct SMU75_Discrete_DpmTable *table)
1671{
1672 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1673 struct vegam_smumgr *smu_data =
1674 (struct vegam_smumgr *)(hwmgr->smu_backend);
1675 uint16_t config;
1676
1677 config = VR_MERGED_WITH_VDDC0;
1678 table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT8);
1679
1680 /* Set Vddc Voltage Controller */
1681 if (SMU7_VOLTAGE_CONTROL_BY_SVID20x2 == data->voltage_control) {
1682 config = VR_SVI2_PLANE_11;
1683 table->VRConfig |= config;
1684 } else {
1685 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "VDDC should be on SVI2 control in merged mode!"
); ; } } while (0)
1686 "VDDC should be on SVI2 control in merged mode!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "VDDC should be on SVI2 control in merged mode!"
); ; } } while (0)
1687 )do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "VDDC should be on SVI2 control in merged mode!"
); ; } } while (0)
;
1688 }
1689 /* Set Vddci Voltage Controller */
1690 if (SMU7_VOLTAGE_CONTROL_BY_SVID20x2 == data->vddci_control) {
1691 config = VR_SVI2_PLANE_22; /* only in merged mode */
1692 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT16);
1693 } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO0x1 == data->vddci_control) {
1694 config = VR_SMIO_PATTERN_13;
1695 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT16);
1696 } else {
1697 config = VR_STATIC_VOLTAGE5;
1698 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT16);
1699 }
1700 /* Set Mvdd Voltage Controller */
1701 if (SMU7_VOLTAGE_CONTROL_BY_SVID20x2 == data->mvdd_control) {
1702 if (config != VR_SVI2_PLANE_22) {
1703 config = VR_SVI2_PLANE_22;
1704 table->VRConfig |= (config << VRCONF_MVDD_SHIFT24);
1705 cgs_write_ind_register(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1706 CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1707 smu_data->smu7_data.soft_regs_start +(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1708 offsetof(SMU75_SoftRegisters, AllowMvddSwitch),(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1709 0x1)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
;
1710 } else {
1711 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "SVI2 Plane 2 is already taken, set MVDD as Static"
); ; } } while (0)
1712 "SVI2 Plane 2 is already taken, set MVDD as Static",)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "SVI2 Plane 2 is already taken, set MVDD as Static"
); ; } } while (0)
;
1713 config = VR_STATIC_VOLTAGE5;
1714 table->VRConfig = (config << VRCONF_MVDD_SHIFT24);
1715 }
1716 } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO0x1 == data->mvdd_control) {
1717 config = VR_SMIO_PATTERN_24;
1718 table->VRConfig = (config << VRCONF_MVDD_SHIFT24);
1719 cgs_write_ind_register(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1720 CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1721 smu_data->smu7_data.soft_regs_start +(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1722 offsetof(SMU75_SoftRegisters, AllowMvddSwitch),(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
1723 0x1)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,smu_data->smu7_data.soft_regs_start
+ __builtin_offsetof(SMU75_SoftRegisters, AllowMvddSwitch),0x1
))
;
1724 } else {
1725 config = VR_STATIC_VOLTAGE5;
1726 table->VRConfig |= (config << VRCONF_MVDD_SHIFT24);
1727 }
1728
1729 return 0;
1730}
1731
1732static int vegam_populate_svi_load_line(struct pp_hwmgr *hwmgr)
1733{
1734 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1735 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1736
1737 smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn;
1738 smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC;
1739 smu_data->power_tune_table.SviLoadLineTrimVddC = 3;
1740 smu_data->power_tune_table.SviLoadLineOffsetVddC = 0;
1741
1742 return 0;
1743}
1744
1745static int vegam_populate_tdc_limit(struct pp_hwmgr *hwmgr)
1746{
1747 uint16_t tdc_limit;
1748 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1749 struct phm_ppt_v1_information *table_info =
1750 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1751 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1752
1753 tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128);
1754 smu_data->power_tune_table.TDC_VDDC_PkgLimit =
1755 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit)((tdc_limit) = (__uint16_t)(__builtin_constant_p(tdc_limit) ?
(__uint16_t)(((__uint16_t)(tdc_limit) & 0xffU) << 8
| ((__uint16_t)(tdc_limit) & 0xff00U) >> 8) : __swap16md
(tdc_limit)))
;
1756 smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc =
1757 defaults->TDC_VDDC_ThrottleReleaseLimitPerc;
1758 smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt;
1759
1760 return 0;
1761}
1762
1763static int vegam_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset)
1764{
1765 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1766 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1767 uint32_t temp;
1768
1769 if (smu7_read_smc_sram_dword(hwmgr,
1770 fuse_table_offset +
1771 offsetof(SMU75_Discrete_PmFuses, TdcWaterfallCtl)__builtin_offsetof(SMU75_Discrete_PmFuses, TdcWaterfallCtl),
1772 (uint32_t *)&temp, SMC_RAM_END0x40000))
1773 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!"
); return -22; } } while (0)
1774 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!"
); return -22; } } while (0)
1775 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!"
); return -22; } } while (0)
;
1776 else {
1777 smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl;
1778 smu_data->power_tune_table.LPMLTemperatureMin =
1779 (uint8_t)((temp >> 16) & 0xff);
1780 smu_data->power_tune_table.LPMLTemperatureMax =
1781 (uint8_t)((temp >> 8) & 0xff);
1782 smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff);
1783 }
1784 return 0;
1785}
1786
1787static int vegam_populate_temperature_scaler(struct pp_hwmgr *hwmgr)
1788{
1789 int i;
1790 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1791
1792 /* Currently not used. Set all to zero. */
1793 for (i = 0; i < 16; i++)
1794 smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0;
1795
1796 return 0;
1797}
1798
1799static int vegam_populate_fuzzy_fan(struct pp_hwmgr *hwmgr)
1800{
1801 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1802
1803/* TO DO move to hwmgr */
1804 if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15))
1805 || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity)
1806 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
1807 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity;
1808
1809 smu_data->power_tune_table.FuzzyFan_PwmSetDelta = PP_HOST_TO_SMC_US((__uint16_t)(__builtin_constant_p(hwmgr->thermal_controller
.advanceFanControlParameters.usFanOutputSensitivity) ? (__uint16_t
)(((__uint16_t)(hwmgr->thermal_controller.advanceFanControlParameters
.usFanOutputSensitivity) & 0xffU) << 8 | ((__uint16_t
)(hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
) & 0xff00U) >> 8) : __swap16md(hwmgr->thermal_controller
.advanceFanControlParameters.usFanOutputSensitivity))
1810 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity)(__uint16_t)(__builtin_constant_p(hwmgr->thermal_controller
.advanceFanControlParameters.usFanOutputSensitivity) ? (__uint16_t
)(((__uint16_t)(hwmgr->thermal_controller.advanceFanControlParameters
.usFanOutputSensitivity) & 0xffU) << 8 | ((__uint16_t
)(hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
) & 0xff00U) >> 8) : __swap16md(hwmgr->thermal_controller
.advanceFanControlParameters.usFanOutputSensitivity))
;
1811 return 0;
1812}
1813
1814static int vegam_populate_gnb_lpml(struct pp_hwmgr *hwmgr)
1815{
1816 int i;
1817 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1818
1819 /* Currently not used. Set all to zero. */
1820 for (i = 0; i < 16; i++)
1821 smu_data->power_tune_table.GnbLPML[i] = 0;
1822
1823 return 0;
1824}
1825
1826static int vegam_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
1827{
1828 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1829 struct phm_ppt_v1_information *table_info =
1830 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1831 uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd;
Value stored to 'hi_sidd' during its initialization is never read
1832 uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd;
1833 struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
1834
1835 hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
1836 lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256);
1837
1838 smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd =
1839 CONVERT_FROM_HOST_TO_SMC_US(hi_sidd)((hi_sidd) = (__uint16_t)(__builtin_constant_p(hi_sidd) ? (__uint16_t
)(((__uint16_t)(hi_sidd) & 0xffU) << 8 | ((__uint16_t
)(hi_sidd) & 0xff00U) >> 8) : __swap16md(hi_sidd)))
;
1840 smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd =
1841 CONVERT_FROM_HOST_TO_SMC_US(lo_sidd)((lo_sidd) = (__uint16_t)(__builtin_constant_p(lo_sidd) ? (__uint16_t
)(((__uint16_t)(lo_sidd) & 0xffU) << 8 | ((__uint16_t
)(lo_sidd) & 0xff00U) >> 8) : __swap16md(lo_sidd)))
;
1842
1843 return 0;
1844}
1845
1846static int vegam_populate_pm_fuses(struct pp_hwmgr *hwmgr)
1847{
1848 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1849 uint32_t pm_fuse_table_offset;
1850
1851 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1852 PHM_PlatformCaps_PowerContainment)) {
1853 if (smu7_read_smc_sram_dword(hwmgr,
1854 SMU7_FIRMWARE_HEADER_LOCATION0x20000 +
1855 offsetof(SMU75_Firmware_Header, PmFuseTable)__builtin_offsetof(SMU75_Firmware_Header, PmFuseTable),
1856 &pm_fuse_table_offset, SMC_RAM_END0x40000))
1857 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to get pm_fuse_table_offset Failed!"
); return -22; } } while (0)
1858 "Attempt to get pm_fuse_table_offset Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to get pm_fuse_table_offset Failed!"
); return -22; } } while (0)
1859 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to get pm_fuse_table_offset Failed!"
); return -22; } } while (0)
;
1860
1861 if (vegam_populate_svi_load_line(hwmgr))
1862 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate SviLoadLine Failed!"
); return -22; } } while (0)
1863 "Attempt to populate SviLoadLine Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate SviLoadLine Failed!"
); return -22; } } while (0)
1864 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate SviLoadLine Failed!"
); return -22; } } while (0)
;
1865
1866 if (vegam_populate_tdc_limit(hwmgr))
1867 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate TDCLimit Failed!"
); return -22; } } while (0)
1868 "Attempt to populate TDCLimit Failed!", return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate TDCLimit Failed!"
); return -22; } } while (0)
;
1869
1870 if (vegam_populate_dw8(hwmgr, pm_fuse_table_offset))
1871 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate TdcWaterfallCtl, "
"LPMLTemperature Min and Max Failed!"); return -22; } } while
(0)
1872 "Attempt to populate TdcWaterfallCtl, "do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate TdcWaterfallCtl, "
"LPMLTemperature Min and Max Failed!"); return -22; } } while
(0)
1873 "LPMLTemperature Min and Max Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate TdcWaterfallCtl, "
"LPMLTemperature Min and Max Failed!"); return -22; } } while
(0)
1874 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate TdcWaterfallCtl, "
"LPMLTemperature Min and Max Failed!"); return -22; } } while
(0)
;
1875
1876 if (0 != vegam_populate_temperature_scaler(hwmgr))
1877 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate LPMLTemperatureScaler Failed!"
); return -22; } } while (0)
1878 "Attempt to populate LPMLTemperatureScaler Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate LPMLTemperatureScaler Failed!"
); return -22; } } while (0)
1879 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate LPMLTemperatureScaler Failed!"
); return -22; } } while (0)
;
1880
1881 if (vegam_populate_fuzzy_fan(hwmgr))
1882 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate Fuzzy Fan Control parameters Failed!"
); return -22; } } while (0)
1883 "Attempt to populate Fuzzy Fan Control parameters Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate Fuzzy Fan Control parameters Failed!"
); return -22; } } while (0)
1884 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate Fuzzy Fan Control parameters Failed!"
); return -22; } } while (0)
;
1885
1886 if (vegam_populate_gnb_lpml(hwmgr))
1887 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate GnbLPML Failed!"
); return -22; } } while (0)
1888 "Attempt to populate GnbLPML Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate GnbLPML Failed!"
); return -22; } } while (0)
1889 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate GnbLPML Failed!"
); return -22; } } while (0)
;
1890
1891 if (vegam_populate_bapm_vddc_base_leakage_sidd(hwmgr))
1892 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
"Sidd Failed!"); return -22; } } while (0)
1893 "Attempt to populate BapmVddCBaseLeakage Hi and Lo "do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
"Sidd Failed!"); return -22; } } while (0)
1894 "Sidd Failed!", return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
"Sidd Failed!"); return -22; } } while (0)
;
1895
1896 if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset,
1897 (uint8_t *)&smu_data->power_tune_table,
1898 (sizeof(struct SMU75_Discrete_PmFuses) - PMFUSES_AVFSSIZE104),
1899 SMC_RAM_END0x40000))
1900 PP_ASSERT_WITH_CODE(false,do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to download PmFuseTable Failed!"
); return -22; } } while (0)
1901 "Attempt to download PmFuseTable Failed!",do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to download PmFuseTable Failed!"
); return -22; } } while (0)
1902 return -EINVAL)do { if (!(0)) { printk("\0014" "amdgpu: " "%s\n", "Attempt to download PmFuseTable Failed!"
); return -22; } } while (0)
;
1903 }
1904 return 0;
1905}
1906
1907static int vegam_enable_reconfig_cus(struct pp_hwmgr *hwmgr)
1908{
1909 struct amdgpu_device *adev = hwmgr->adev;
1910
1911 smum_send_msg_to_smc_with_parameter(hwmgr,
1912 PPSMC_MSG_EnableModeSwitchRLCNotification((uint16_t) 0x305),
1913 adev->gfx.cu_info.number,
1914 NULL((void *)0));
1915
1916 return 0;
1917}
1918
1919static int vegam_init_smc_table(struct pp_hwmgr *hwmgr)
1920{
1921 int result;
1922 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1923 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1924
1925 struct phm_ppt_v1_information *table_info =
1926 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1927 struct SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1928 uint8_t i;
1929 struct pp_atomctrl_gpio_pin_assignment gpio_pin;
1930 struct phm_ppt_v1_gpio_table *gpio_table =
1931 (struct phm_ppt_v1_gpio_table *)table_info->gpio_table;
1932 pp_atomctrl_clock_dividers_vi dividers;
1933
1934 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
1935 PHM_PlatformCaps_AutomaticDCTransition);
1936
1937 vegam_initialize_power_tune_defaults(hwmgr);
1938
1939 if (SMU7_VOLTAGE_CONTROL_NONE0x0 != hw_data->voltage_control)
1940 vegam_populate_smc_voltage_tables(hwmgr, table);
1941
1942 table->SystemFlags = 0;
1943 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1944 PHM_PlatformCaps_AutomaticDCTransition))
1945 table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC0x01;
1946
1947 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1948 PHM_PlatformCaps_StepVddc))
1949 table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC0x02;
1950
1951 if (hw_data->is_memory_gddr5)
1952 table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR50x04;
1953
1954 if (hw_data->ulv_supported && table_info->us_ulv_voltage_offset) {
1955 result = vegam_populate_ulv_state(hwmgr, table);
1956 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize ULV state!"
); return result; } } while (0)
1957 "Failed to initialize ULV state!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize ULV state!"
); return result; } } while (0)
;
1958 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xc020015c,0x00040035))
1959 ixCG_ULV_PARAMETER, SMU7_CGULVPARAMETER_DFLT)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register
(hwmgr->device,CGS_IND_REG__SMC,0xc020015c,0x00040035))
;
1960 }
1961
1962 result = vegam_populate_smc_link_level(hwmgr, table);
1963 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Link Level!"
); return result; } } while (0)
1964 "Failed to initialize Link Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Link Level!"
); return result; } } while (0)
;
1965
1966 result = vegam_populate_all_graphic_levels(hwmgr);
1967 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Graphics Level!"
); return result; } } while (0)
1968 "Failed to initialize Graphics Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Graphics Level!"
); return result; } } while (0)
;
1969
1970 result = vegam_populate_all_memory_levels(hwmgr);
1971 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Memory Level!"
); return result; } } while (0)
1972 "Failed to initialize Memory Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Memory Level!"
); return result; } } while (0)
;
1973
1974 result = vegam_populate_smc_acpi_level(hwmgr, table);
1975 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize ACPI Level!"
); return result; } } while (0)
1976 "Failed to initialize ACPI Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize ACPI Level!"
); return result; } } while (0)
;
1977
1978 result = vegam_populate_smc_vce_level(hwmgr, table);
1979 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize VCE Level!"
); return result; } } while (0)
1980 "Failed to initialize VCE Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize VCE Level!"
); return result; } } while (0)
;
1981
1982 /* Since only the initial state is completely set up at this point
1983 * (the other states are just copies of the boot state) we only
1984 * need to populate the ARB settings for the initial state.
1985 */
1986 result = vegam_program_memory_timing_parameters(hwmgr);
1987 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to Write ARB settings for the initial state."
); return result; } } while (0)
1988 "Failed to Write ARB settings for the initial state.", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to Write ARB settings for the initial state."
); return result; } } while (0)
;
1989
1990 result = vegam_populate_smc_uvd_level(hwmgr, table);
1991 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize UVD Level!"
); return result; } } while (0)
1992 "Failed to initialize UVD Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize UVD Level!"
); return result; } } while (0)
;
1993
1994 result = vegam_populate_smc_boot_level(hwmgr, table);
1995 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Boot Level!"
); return result; } } while (0)
1996 "Failed to initialize Boot Level!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Boot Level!"
); return result; } } while (0)
;
1997
1998 result = vegam_populate_smc_initial_state(hwmgr);
1999 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Boot State!"
); return result; } } while (0)
2000 "Failed to initialize Boot State!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to initialize Boot State!"
); return result; } } while (0)
;
2001
2002 result = vegam_populate_bapm_parameters_in_dpm_table(hwmgr);
2003 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate BAPM Parameters!"
); return result; } } while (0)
2004 "Failed to populate BAPM Parameters!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate BAPM Parameters!"
); return result; } } while (0)
;
2005
2006 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2007 PHM_PlatformCaps_ClockStretcher)) {
2008 result = vegam_populate_clock_stretcher_data_table(hwmgr);
2009 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate Clock Stretcher Data Table!"
); return result; } } while (0)
2010 "Failed to populate Clock Stretcher Data Table!",do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate Clock Stretcher Data Table!"
); return result; } } while (0)
2011 return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate Clock Stretcher Data Table!"
); return result; } } while (0)
;
2012 }
2013
2014 result = vegam_populate_avfs_parameters(hwmgr);
2015 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate AVFS Parameters!"
); return result;; } } while (0)
2016 "Failed to populate AVFS Parameters!", return result;)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate AVFS Parameters!"
); return result;; } } while (0)
;
2017
2018 table->CurrSclkPllRange = 0xff;
2019 table->GraphicsVoltageChangeEnable = 1;
2020 table->GraphicsThermThrottleEnable = 1;
2021 table->GraphicsInterval = 1;
2022 table->VoltageInterval = 1;
2023 table->ThermalInterval = 1;
2024 table->TemperatureLimitHigh =
2025 table_info->cac_dtp_table->usTargetOperatingTemp *
2026 SMU7_Q88_FORMAT_CONVERSION_UNIT256;
2027 table->TemperatureLimitLow =
2028 (table_info->cac_dtp_table->usTargetOperatingTemp - 1) *
2029 SMU7_Q88_FORMAT_CONVERSION_UNIT256;
2030 table->MemoryVoltageChangeEnable = 1;
2031 table->MemoryInterval = 1;
2032 table->VoltageResponseTime = 0;
2033 table->PhaseResponseTime = 0;
2034 table->MemoryThermThrottleEnable = 1;
2035
2036 PP_ASSERT_WITH_CODE(hw_data->dpm_table.pcie_speed_table.count >= 1,do { if (!(hw_data->dpm_table.pcie_speed_table.count >=
1)) { printk("\0014" "amdgpu: " "%s\n", "There must be 1 or more PCIE levels defined in PPTable."
); return -22; } } while (0)
2037 "There must be 1 or more PCIE levels defined in PPTable.",do { if (!(hw_data->dpm_table.pcie_speed_table.count >=
1)) { printk("\0014" "amdgpu: " "%s\n", "There must be 1 or more PCIE levels defined in PPTable."
); return -22; } } while (0)
2038 return -EINVAL)do { if (!(hw_data->dpm_table.pcie_speed_table.count >=
1)) { printk("\0014" "amdgpu: " "%s\n", "There must be 1 or more PCIE levels defined in PPTable."
); return -22; } } while (0)
;
2039 table->PCIeBootLinkLevel =
2040 hw_data->dpm_table.pcie_speed_table.count;
2041 table->PCIeGenInterval = 1;
2042 table->VRConfig = 0;
2043
2044 result = vegam_populate_vr_config(hwmgr, table);
2045 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate VRConfig setting!"
); return result; } } while (0)
2046 "Failed to populate VRConfig setting!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate VRConfig setting!"
); return result; } } while (0)
;
2047
2048 table->ThermGpio = 17;
2049 table->SclkStepSize = 0x4000;
2050
2051 if (atomctrl_get_pp_assign_pin(hwmgr,
2052 VDDC_VRHOT_GPIO_PINID61, &gpio_pin)) {
2053 table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift;
2054 if (gpio_table)
2055 table->VRHotLevel =
2056 table_info->gpio_table->vrhot_triggered_sclk_dpm_index;
2057 } else {
2058 table->VRHotGpio = SMU7_UNUSED_GPIO_PIN0x7F;
2059 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2060 PHM_PlatformCaps_RegulatorHot);
2061 }
2062
2063 if (atomctrl_get_pp_assign_pin(hwmgr,
2064 PP_AC_DC_SWITCH_GPIO_PINID60, &gpio_pin)) {
2065 table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift;
2066 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2067 PHM_PlatformCaps_AutomaticDCTransition) &&
2068 !smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UseNewGPIOScheme((uint16_t) 0x277), NULL((void *)0)))
2069 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2070 PHM_PlatformCaps_SMCtoPPLIBAcdcGpioScheme);
2071 } else {
2072 table->AcDcGpio = SMU7_UNUSED_GPIO_PIN0x7F;
2073 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2074 PHM_PlatformCaps_AutomaticDCTransition);
2075 }
2076
2077 /* Thermal Output GPIO */
2078 if (atomctrl_get_pp_assign_pin(hwmgr,
2079 THERMAL_INT_OUTPUT_GPIO_PINID65, &gpio_pin)) {
2080 table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift;
2081
2082 /* For porlarity read GPIOPAD_A with assigned Gpio pin
2083 * since VBIOS will program this register to set 'inactive state',
2084 * driver can then determine 'active state' from this and
2085 * program SMU with correct polarity
2086 */
2087 table->ThermOutPolarity =
2088 (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A)(((struct cgs_device *)hwmgr->device)->ops->read_register
(hwmgr->device,0x183))
&
2089 (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0;
2090 table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY0x1;
2091
2092 /* if required, combine VRHot/PCC with thermal out GPIO */
2093 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2094 PHM_PlatformCaps_RegulatorHot) &&
2095 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2096 PHM_PlatformCaps_CombinePCCWithThermalSignal))
2097 table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT0x2;
2098 } else {
2099 table->ThermOutGpio = 17;
2100 table->ThermOutPolarity = 1;
2101 table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE0x0;
2102 }
2103
2104 /* Populate BIF_SCLK levels into SMC DPM table */
2105 for (i = 0; i <= hw_data->dpm_table.pcie_speed_table.count; i++) {
2106 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
2107 smu_data->bif_sclk_table[i], &dividers);
2108 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Can not find DFS divide id for Sclk"
); return result; } } while (0)
2109 "Can not find DFS divide id for Sclk",do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Can not find DFS divide id for Sclk"
); return result; } } while (0)
2110 return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Can not find DFS divide id for Sclk"
); return result; } } while (0)
;
2111
2112 if (i == 0)
2113 table->Ulv.BifSclkDfs =
2114 PP_HOST_TO_SMC_US((uint16_t)(dividers.pll_post_divider))(__uint16_t)(__builtin_constant_p((uint16_t)(dividers.pll_post_divider
)) ? (__uint16_t)(((__uint16_t)((uint16_t)(dividers.pll_post_divider
)) & 0xffU) << 8 | ((__uint16_t)((uint16_t)(dividers
.pll_post_divider)) & 0xff00U) >> 8) : __swap16md((
uint16_t)(dividers.pll_post_divider)))
;
2115 else
2116 table->LinkLevel[i - 1].BifSclkDfs =
2117 PP_HOST_TO_SMC_US((uint16_t)(dividers.pll_post_divider))(__uint16_t)(__builtin_constant_p((uint16_t)(dividers.pll_post_divider
)) ? (__uint16_t)(((__uint16_t)((uint16_t)(dividers.pll_post_divider
)) & 0xffU) << 8 | ((__uint16_t)((uint16_t)(dividers
.pll_post_divider)) & 0xff00U) >> 8) : __swap16md((
uint16_t)(dividers.pll_post_divider)))
;
2118 }
2119
2120 for (i = 0; i < SMU75_MAX_ENTRIES_SMIO32; i++)
2121 table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i])(__uint32_t)(__builtin_constant_p(table->Smio[i]) ? (__uint32_t
)(((__uint32_t)(table->Smio[i]) & 0xff) << 24 | (
(__uint32_t)(table->Smio[i]) & 0xff00) << 8 | ((
__uint32_t)(table->Smio[i]) & 0xff0000) >> 8 | (
(__uint32_t)(table->Smio[i]) & 0xff000000) >> 24
) : __swap32md(table->Smio[i]))
;
2122
2123 CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags)((table->SystemFlags) = (__uint32_t)(__builtin_constant_p(
table->SystemFlags) ? (__uint32_t)(((__uint32_t)(table->
SystemFlags) & 0xff) << 24 | ((__uint32_t)(table->
SystemFlags) & 0xff00) << 8 | ((__uint32_t)(table->
SystemFlags) & 0xff0000) >> 8 | ((__uint32_t)(table
->SystemFlags) & 0xff000000) >> 24) : __swap32md
(table->SystemFlags)))
;
2124 CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig)((table->VRConfig) = (__uint32_t)(__builtin_constant_p(table
->VRConfig) ? (__uint32_t)(((__uint32_t)(table->VRConfig
) & 0xff) << 24 | ((__uint32_t)(table->VRConfig)
& 0xff00) << 8 | ((__uint32_t)(table->VRConfig)
& 0xff0000) >> 8 | ((__uint32_t)(table->VRConfig
) & 0xff000000) >> 24) : __swap32md(table->VRConfig
)))
;
2125 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1)((table->SmioMask1) = (__uint32_t)(__builtin_constant_p(table
->SmioMask1) ? (__uint32_t)(((__uint32_t)(table->SmioMask1
) & 0xff) << 24 | ((__uint32_t)(table->SmioMask1
) & 0xff00) << 8 | ((__uint32_t)(table->SmioMask1
) & 0xff0000) >> 8 | ((__uint32_t)(table->SmioMask1
) & 0xff000000) >> 24) : __swap32md(table->SmioMask1
)))
;
2126 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2)((table->SmioMask2) = (__uint32_t)(__builtin_constant_p(table
->SmioMask2) ? (__uint32_t)(((__uint32_t)(table->SmioMask2
) & 0xff) << 24 | ((__uint32_t)(table->SmioMask2
) & 0xff00) << 8 | ((__uint32_t)(table->SmioMask2
) & 0xff0000) >> 8 | ((__uint32_t)(table->SmioMask2
) & 0xff000000) >> 24) : __swap32md(table->SmioMask2
)))
;
2127 CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize)((table->SclkStepSize) = (__uint32_t)(__builtin_constant_p
(table->SclkStepSize) ? (__uint32_t)(((__uint32_t)(table->
SclkStepSize) & 0xff) << 24 | ((__uint32_t)(table->
SclkStepSize) & 0xff00) << 8 | ((__uint32_t)(table->
SclkStepSize) & 0xff0000) >> 8 | ((__uint32_t)(table
->SclkStepSize) & 0xff000000) >> 24) : __swap32md
(table->SclkStepSize)))
;
2128 CONVERT_FROM_HOST_TO_SMC_UL(table->CurrSclkPllRange)((table->CurrSclkPllRange) = (__uint32_t)(__builtin_constant_p
(table->CurrSclkPllRange) ? (__uint32_t)(((__uint32_t)(table
->CurrSclkPllRange) & 0xff) << 24 | ((__uint32_t
)(table->CurrSclkPllRange) & 0xff00) << 8 | ((__uint32_t
)(table->CurrSclkPllRange) & 0xff0000) >> 8 | ((
__uint32_t)(table->CurrSclkPllRange) & 0xff000000) >>
24) : __swap32md(table->CurrSclkPllRange)))
;
2129 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh)((table->TemperatureLimitHigh) = (__uint16_t)(__builtin_constant_p
(table->TemperatureLimitHigh) ? (__uint16_t)(((__uint16_t)
(table->TemperatureLimitHigh) & 0xffU) << 8 | ((
__uint16_t)(table->TemperatureLimitHigh) & 0xff00U) >>
8) : __swap16md(table->TemperatureLimitHigh)))
;
2130 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow)((table->TemperatureLimitLow) = (__uint16_t)(__builtin_constant_p
(table->TemperatureLimitLow) ? (__uint16_t)(((__uint16_t)(
table->TemperatureLimitLow) & 0xffU) << 8 | ((__uint16_t
)(table->TemperatureLimitLow) & 0xff00U) >> 8) :
__swap16md(table->TemperatureLimitLow)))
;
2131 CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime)((table->VoltageResponseTime) = (__uint16_t)(__builtin_constant_p
(table->VoltageResponseTime) ? (__uint16_t)(((__uint16_t)(
table->VoltageResponseTime) & 0xffU) << 8 | ((__uint16_t
)(table->VoltageResponseTime) & 0xff00U) >> 8) :
__swap16md(table->VoltageResponseTime)))
;
2132 CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime)((table->PhaseResponseTime) = (__uint16_t)(__builtin_constant_p
(table->PhaseResponseTime) ? (__uint16_t)(((__uint16_t)(table
->PhaseResponseTime) & 0xffU) << 8 | ((__uint16_t
)(table->PhaseResponseTime) & 0xff00U) >> 8) : __swap16md
(table->PhaseResponseTime)))
;
2133
2134 /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
2135 result = smu7_copy_bytes_to_smc(hwmgr,
2136 smu_data->smu7_data.dpm_table_start +
2137 offsetof(SMU75_Discrete_DpmTable, SystemFlags)__builtin_offsetof(SMU75_Discrete_DpmTable, SystemFlags),
2138 (uint8_t *)&(table->SystemFlags),
2139 sizeof(SMU75_Discrete_DpmTable) - 3 * sizeof(SMU75_PIDController),
2140 SMC_RAM_END0x40000);
2141 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to upload dpm data to SMC memory!"
); return result; } } while (0)
2142 "Failed to upload dpm data to SMC memory!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to upload dpm data to SMC memory!"
); return result; } } while (0)
;
2143
2144 result = vegam_populate_pm_fuses(hwmgr);
2145 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate PM fuses to SMC memory!"
); return result; } } while (0)
2146 "Failed to populate PM fuses to SMC memory!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to populate PM fuses to SMC memory!"
); return result; } } while (0)
;
2147
2148 result = vegam_enable_reconfig_cus(hwmgr);
2149 PP_ASSERT_WITH_CODE(!result,do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to enable reconfigurable CUs!"
); return result; } } while (0)
2150 "Failed to enable reconfigurable CUs!", return result)do { if (!(!result)) { printk("\0014" "amdgpu: " "%s\n", "Failed to enable reconfigurable CUs!"
); return result; } } while (0)
;
2151
2152 return 0;
2153}
2154
2155static uint32_t vegam_get_offsetof(uint32_t type, uint32_t member)
2156{
2157 switch (type) {
2158 case SMU_SoftRegisters:
2159 switch (member) {
2160 case HandshakeDisables:
2161 return offsetof(SMU75_SoftRegisters, HandshakeDisables)__builtin_offsetof(SMU75_SoftRegisters, HandshakeDisables);
2162 case VoltageChangeTimeout:
2163 return offsetof(SMU75_SoftRegisters, VoltageChangeTimeout)__builtin_offsetof(SMU75_SoftRegisters, VoltageChangeTimeout);
2164 case AverageGraphicsActivity:
2165 return offsetof(SMU75_SoftRegisters, AverageGraphicsActivity)__builtin_offsetof(SMU75_SoftRegisters, AverageGraphicsActivity
)
;
2166 case AverageMemoryActivity:
2167 return offsetof(SMU75_SoftRegisters, AverageMemoryActivity)__builtin_offsetof(SMU75_SoftRegisters, AverageMemoryActivity
)
;
2168 case PreVBlankGap:
2169 return offsetof(SMU75_SoftRegisters, PreVBlankGap)__builtin_offsetof(SMU75_SoftRegisters, PreVBlankGap);
2170 case VBlankTimeout:
2171 return offsetof(SMU75_SoftRegisters, VBlankTimeout)__builtin_offsetof(SMU75_SoftRegisters, VBlankTimeout);
2172 case UcodeLoadStatus:
2173 return offsetof(SMU75_SoftRegisters, UcodeLoadStatus)__builtin_offsetof(SMU75_SoftRegisters, UcodeLoadStatus);
2174 case DRAM_LOG_ADDR_H:
2175 return offsetof(SMU75_SoftRegisters, DRAM_LOG_ADDR_H)__builtin_offsetof(SMU75_SoftRegisters, DRAM_LOG_ADDR_H);
2176 case DRAM_LOG_ADDR_L:
2177 return offsetof(SMU75_SoftRegisters, DRAM_LOG_ADDR_L)__builtin_offsetof(SMU75_SoftRegisters, DRAM_LOG_ADDR_L);
2178 case DRAM_LOG_PHY_ADDR_H:
2179 return offsetof(SMU75_SoftRegisters, DRAM_LOG_PHY_ADDR_H)__builtin_offsetof(SMU75_SoftRegisters, DRAM_LOG_PHY_ADDR_H);
2180 case DRAM_LOG_PHY_ADDR_L:
2181 return offsetof(SMU75_SoftRegisters, DRAM_LOG_PHY_ADDR_L)__builtin_offsetof(SMU75_SoftRegisters, DRAM_LOG_PHY_ADDR_L);
2182 case DRAM_LOG_BUFF_SIZE:
2183 return offsetof(SMU75_SoftRegisters, DRAM_LOG_BUFF_SIZE)__builtin_offsetof(SMU75_SoftRegisters, DRAM_LOG_BUFF_SIZE);
2184 }
2185 break;
2186 case SMU_Discrete_DpmTable:
2187 switch (member) {
2188 case UvdBootLevel:
2189 return offsetof(SMU75_Discrete_DpmTable, UvdBootLevel)__builtin_offsetof(SMU75_Discrete_DpmTable, UvdBootLevel);
2190 case VceBootLevel:
2191 return offsetof(SMU75_Discrete_DpmTable, VceBootLevel)__builtin_offsetof(SMU75_Discrete_DpmTable, VceBootLevel);
2192 case LowSclkInterruptThreshold:
2193 return offsetof(SMU75_Discrete_DpmTable, LowSclkInterruptThreshold)__builtin_offsetof(SMU75_Discrete_DpmTable, LowSclkInterruptThreshold
)
;
2194 }
2195 break;
2196 }
2197 pr_warn("can't get the offset of type %x member %x\n", type, member)printk("\0014" "amdgpu: " "can't get the offset of type %x member %x\n"
, type, member)
;
2198 return 0;
2199}
2200
2201static int vegam_program_mem_timing_parameters(struct pp_hwmgr *hwmgr)
2202{
2203 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2204
2205 if (data->need_update_smu7_dpm_table &
2206 (DPMTABLE_OD_UPDATE_SCLK0x00000001 +
2207 DPMTABLE_UPDATE_SCLK0x00000004 +
2208 DPMTABLE_UPDATE_MCLK0x00000008))
2209 return vegam_program_memory_timing_parameters(hwmgr);
2210
2211 return 0;
2212}
2213
2214static int vegam_update_sclk_threshold(struct pp_hwmgr *hwmgr)
2215{
2216 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2217 struct vegam_smumgr *smu_data =
2218 (struct vegam_smumgr *)(hwmgr->smu_backend);
2219 int result = 0;
2220 uint32_t low_sclk_interrupt_threshold = 0;
2221
2222 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2223 PHM_PlatformCaps_SclkThrottleLowNotification)
2224 && (data->low_sclk_interrupt_threshold != 0)) {
2225 low_sclk_interrupt_threshold =
2226 data->low_sclk_interrupt_threshold;
2227
2228 CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold)((low_sclk_interrupt_threshold) = (__uint32_t)(__builtin_constant_p
(low_sclk_interrupt_threshold) ? (__uint32_t)(((__uint32_t)(low_sclk_interrupt_threshold
) & 0xff) << 24 | ((__uint32_t)(low_sclk_interrupt_threshold
) & 0xff00) << 8 | ((__uint32_t)(low_sclk_interrupt_threshold
) & 0xff0000) >> 8 | ((__uint32_t)(low_sclk_interrupt_threshold
) & 0xff000000) >> 24) : __swap32md(low_sclk_interrupt_threshold
)))
;
2229
2230 result = smu7_copy_bytes_to_smc(
2231 hwmgr,
2232 smu_data->smu7_data.dpm_table_start +
2233 offsetof(SMU75_Discrete_DpmTable,__builtin_offsetof(SMU75_Discrete_DpmTable, LowSclkInterruptThreshold
)
2234 LowSclkInterruptThreshold)__builtin_offsetof(SMU75_Discrete_DpmTable, LowSclkInterruptThreshold
)
,
2235 (uint8_t *)&low_sclk_interrupt_threshold,
2236 sizeof(uint32_t),
2237 SMC_RAM_END0x40000);
2238 }
2239 PP_ASSERT_WITH_CODE((result == 0),do { if (!((result == 0))) { printk("\0014" "amdgpu: " "%s\n"
, "Failed to update SCLK threshold!"); return result; } } while
(0)
2240 "Failed to update SCLK threshold!", return result)do { if (!((result == 0))) { printk("\0014" "amdgpu: " "%s\n"
, "Failed to update SCLK threshold!"); return result; } } while
(0)
;
2241
2242 result = vegam_program_mem_timing_parameters(hwmgr);
2243 PP_ASSERT_WITH_CODE((result == 0),do { if (!((result == 0))) { printk("\0014" "amdgpu: " "%s\n"
, "Failed to program memory timing parameters!"); ; } } while
(0)
2244 "Failed to program memory timing parameters!",do { if (!((result == 0))) { printk("\0014" "amdgpu: " "%s\n"
, "Failed to program memory timing parameters!"); ; } } while
(0)
2245 )do { if (!((result == 0))) { printk("\0014" "amdgpu: " "%s\n"
, "Failed to program memory timing parameters!"); ; } } while
(0)
;
2246
2247 return result;
2248}
2249
2250int vegam_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
2251{
2252 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2253 int ret;
2254
2255 if (!hwmgr->avfs_supported)
2256 return 0;
2257
2258 ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs((uint16_t) 0x26A), NULL((void *)0));
2259 if (!ret) {
2260 if (data->apply_avfs_cks_off_voltage)
2261 ret = smum_send_msg_to_smc(hwmgr,
2262 PPSMC_MSG_ApplyAvfsCksOffVoltage((uint16_t) 0x415),
2263 NULL((void *)0));
2264 }
2265
2266 return ret;
2267}
2268
2269static int vegam_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
2270{
2271 PP_ASSERT_WITH_CODE(hwmgr->thermal_controller.fanInfo.bNoFan,do { if (!(hwmgr->thermal_controller.fanInfo.bNoFan)) { printk
("\0014" "amdgpu: " "%s\n", "VBIOS fan info is not correct!")
; ; } } while (0)
2272 "VBIOS fan info is not correct!",do { if (!(hwmgr->thermal_controller.fanInfo.bNoFan)) { printk
("\0014" "amdgpu: " "%s\n", "VBIOS fan info is not correct!")
; ; } } while (0)
2273 )do { if (!(hwmgr->thermal_controller.fanInfo.bNoFan)) { printk
("\0014" "amdgpu: " "%s\n", "VBIOS fan info is not correct!")
; ; } } while (0)
;
2274 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2275 PHM_PlatformCaps_MicrocodeFanControl);
2276 return 0;
2277}
2278
2279const struct pp_smumgr_func vegam_smu_funcs = {
2280 .name = "vegam_smu",
2281 .smu_init = vegam_smu_init,
2282 .smu_fini = smu7_smu_fini,
2283 .start_smu = vegam_start_smu,
2284 .check_fw_load_finish = smu7_check_fw_load_finish,
2285 .request_smu_load_fw = smu7_reload_firmware,
2286 .request_smu_load_specific_fw = NULL((void *)0),
2287 .send_msg_to_smc = smu7_send_msg_to_smc,
2288 .send_msg_to_smc_with_parameter = smu7_send_msg_to_smc_with_parameter,
2289 .get_argument = smu7_get_argument,
2290 .process_firmware_header = vegam_process_firmware_header,
2291 .is_dpm_running = vegam_is_dpm_running,
2292 .get_mac_definition = vegam_get_mac_definition,
2293 .update_smc_table = vegam_update_smc_table,
2294 .init_smc_table = vegam_init_smc_table,
2295 .get_offsetof = vegam_get_offsetof,
2296 .populate_all_graphic_levels = vegam_populate_all_graphic_levels,
2297 .populate_all_memory_levels = vegam_populate_all_memory_levels,
2298 .update_sclk_threshold = vegam_update_sclk_threshold,
2299 .is_hw_avfs_present = vegam_is_hw_avfs_present,
2300 .thermal_avfs_enable = vegam_thermal_avfs_enable,
2301 .thermal_setup_fan_table = vegam_thermal_setup_fan_table,
2302};