2 * Copyright 2015 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
27 #include "smu_ucode_xfer_vi.h"
28 #include "polaris10_smumgr.h"
29 #include "smu74_discrete.h"
30 #include "smu/smu_7_1_3_d.h"
31 #include "smu/smu_7_1_3_sh_mask.h"
32 #include "gmc/gmc_8_1_d.h"
33 #include "gmc/gmc_8_1_sh_mask.h"
34 #include "oss/oss_3_0_d.h"
35 #include "gca/gfx_8_0_d.h"
36 #include "bif/bif_5_0_d.h"
37 #include "bif/bif_5_0_sh_mask.h"
38 #include "ppatomctrl.h"
39 #include "cgs_common.h"
40 #include "smu7_ppsmc.h"
41 #include "smu7_smumgr.h"
43 #include "smu7_dyn_defaults.h"
45 #include "smu7_hwmgr.h"
46 #include "hardwaremanager.h"
47 #include "ppatomctrl.h"
49 #include "pppcielanes.h"
51 #include "dce/dce_10_0_d.h"
52 #include "dce/dce_10_0_sh_mask.h"
54 #define POLARIS10_SMC_SIZE 0x20000
55 #define POWERTUNE_DEFAULT_SET_MAX 1
56 #define VDDC_VDDCI_DELTA 200
57 #define MC_CG_ARB_FREQ_F1 0x0b
59 static const struct polaris10_pt_defaults polaris10_power_tune_data_set_array
[POWERTUNE_DEFAULT_SET_MAX
] = {
60 /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt,
61 * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */
62 { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
63 { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61},
64 { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } },
67 static const sclkFcwRange_t Range_Table
[NUM_SCLK_RANGE
] = {
68 {VCO_2_4
, POSTDIV_DIV_BY_16
, 75, 160, 112},
69 {VCO_3_6
, POSTDIV_DIV_BY_16
, 112, 224, 160},
70 {VCO_2_4
, POSTDIV_DIV_BY_8
, 75, 160, 112},
71 {VCO_3_6
, POSTDIV_DIV_BY_8
, 112, 224, 160},
72 {VCO_2_4
, POSTDIV_DIV_BY_4
, 75, 160, 112},
73 {VCO_3_6
, POSTDIV_DIV_BY_4
, 112, 216, 160},
74 {VCO_2_4
, POSTDIV_DIV_BY_2
, 75, 160, 108},
75 {VCO_3_6
, POSTDIV_DIV_BY_2
, 112, 216, 160} };
77 #define PPPOLARIS10_TARGETACTIVITY_DFLT 50
79 static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10
[8] = {
80 /* Min pcie DeepSleep Activity CgSpll CgSpll CcPwr CcPwr Sclk Enabled Enabled Voltage Power */
81 /* Voltage, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, DynRm, DynRm1 Did, Padding,ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */
82 { 0x100ea446, 0x00, 0x03, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x30750000, 0x3000, 0, 0x2600, 0, 0, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } },
83 { 0x400ea446, 0x01, 0x04, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x409c0000, 0x2000, 0, 0x1e00, 1, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } },
84 { 0x740ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x50c30000, 0x2800, 0, 0x2000, 1, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } },
85 { 0xa40ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x60ea0000, 0x3000, 0, 0x2600, 1, 1, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } },
86 { 0xd80ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x70110100, 0x3800, 0, 0x2c00, 1, 1, 0x0004, 0x1203, 0xffff, 0x3600, 0xc9e2, 0x2e00 } },
87 { 0x3c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x80380100, 0x2000, 0, 0x1e00, 2, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } },
88 { 0x6c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x905f0100, 0x2400, 0, 0x1e00, 2, 1, 0x0004, 0x8901, 0xffff, 0x2300, 0x314c, 0x1d00 } },
89 { 0xa00fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0xa0860100, 0x2800, 0, 0x2000, 2, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } }
92 static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10
= {
93 0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00};
95 static int polaris10_perform_btc(struct pp_hwmgr
*hwmgr
)
98 struct smu7_smumgr
*smu_data
= (struct smu7_smumgr
*)(hwmgr
->smu_backend
);
100 if (0 != smu_data
->avfs_btc_param
) {
101 if (0 != smu7_send_msg_to_smc_with_parameter(hwmgr
, PPSMC_MSG_PerformBtc
, smu_data
->avfs_btc_param
)) {
102 pr_info("[AVFS][SmuPolaris10_PerformBtc] PerformBTC SMU msg failed");
106 if (smu_data
->avfs_btc_param
> 1) {
107 /* Soft-Reset to reset the engine before loading uCode */
109 cgs_write_register(hwmgr
->device
, mmCP_MEC_CNTL
, 0x50000000);
110 /* reset everything */
111 cgs_write_register(hwmgr
->device
, mmGRBM_SOFT_RESET
, 0xffffffff);
112 cgs_write_register(hwmgr
->device
, mmGRBM_SOFT_RESET
, 0);
118 static int polaris10_setup_graphics_level_structure(struct pp_hwmgr
*hwmgr
)
121 uint32_t dpm_table_start
;
123 uint16_t u16_boot_mvdd
;
124 uint32_t graphics_level_address
, vr_config_address
, graphics_level_size
;
126 graphics_level_size
= sizeof(avfs_graphics_level_polaris10
);
127 u16_boot_mvdd
= PP_HOST_TO_SMC_US(1300 * VOLTAGE_SCALE
);
129 PP_ASSERT_WITH_CODE(0 == smu7_read_smc_sram_dword(hwmgr
,
130 SMU7_FIRMWARE_HEADER_LOCATION
+ offsetof(SMU74_Firmware_Header
, DpmTable
),
131 &dpm_table_start
, 0x40000),
132 "[AVFS][Polaris10_SetupGfxLvlStruct] SMU could not communicate starting address of DPM table",
135 /* Default value for VRConfig = VR_MERGED_WITH_VDDC + VR_STATIC_VOLTAGE(VDDCI) */
136 vr_config
= 0x01000500; /* Real value:0x50001 */
138 vr_config_address
= dpm_table_start
+ offsetof(SMU74_Discrete_DpmTable
, VRConfig
);
140 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr
, vr_config_address
,
141 (uint8_t *)&vr_config
, sizeof(uint32_t), 0x40000),
142 "[AVFS][Polaris10_SetupGfxLvlStruct] Problems copying VRConfig value over to SMC",
145 graphics_level_address
= dpm_table_start
+ offsetof(SMU74_Discrete_DpmTable
, GraphicsLevel
);
147 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr
, graphics_level_address
,
148 (uint8_t *)(&avfs_graphics_level_polaris10
),
149 graphics_level_size
, 0x40000),
150 "[AVFS][Polaris10_SetupGfxLvlStruct] Copying of SCLK DPM table failed!",
153 graphics_level_address
= dpm_table_start
+ offsetof(SMU74_Discrete_DpmTable
, MemoryLevel
);
155 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr
, graphics_level_address
,
156 (uint8_t *)(&avfs_memory_level_polaris10
), sizeof(avfs_memory_level_polaris10
), 0x40000),
157 "[AVFS][Polaris10_SetupGfxLvlStruct] Copying of MCLK DPM table failed!",
160 /* MVDD Boot value - neccessary for getting rid of the hang that occurs during Mclk DPM enablement */
162 graphics_level_address
= dpm_table_start
+ offsetof(SMU74_Discrete_DpmTable
, BootMVdd
);
164 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr
, graphics_level_address
,
165 (uint8_t *)(&u16_boot_mvdd
), sizeof(u16_boot_mvdd
), 0x40000),
166 "[AVFS][Polaris10_SetupGfxLvlStruct] Copying of DPM table failed!",
173 static int polaris10_avfs_event_mgr(struct pp_hwmgr
*hwmgr
)
175 struct smu7_smumgr
*smu_data
= (struct smu7_smumgr
*)(hwmgr
->smu_backend
);
177 if (!hwmgr
->avfs_supported
)
180 PP_ASSERT_WITH_CODE(0 == polaris10_setup_graphics_level_structure(hwmgr
),
181 "[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
184 if (smu_data
->avfs_btc_param
> 1) {
185 pr_info("[AVFS][Polaris10_AVFSEventMgr] AC BTC has not been successfully verified on Fiji. There may be in this setting.");
186 PP_ASSERT_WITH_CODE(0 == smu7_setup_pwr_virus(hwmgr
),
187 "[AVFS][Polaris10_AVFSEventMgr] Could not setup Pwr Virus for AVFS ",
191 PP_ASSERT_WITH_CODE(0 == polaris10_perform_btc(hwmgr
),
192 "[AVFS][Polaris10_AVFSEventMgr] Failure at SmuPolaris10_PerformBTC. AVFS Disabled",
198 static int polaris10_start_smu_in_protection_mode(struct pp_hwmgr
*hwmgr
)
202 /* Wait for smc boot up */
203 /* PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0) */
206 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
207 SMC_SYSCON_RESET_CNTL
, rst_reg
, 1);
209 result
= smu7_upload_smu_firmware_image(hwmgr
);
214 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixSMU_STATUS
, 0);
216 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
217 SMC_SYSCON_CLOCK_CNTL_0
, ck_disable
, 0);
219 /* De-assert reset */
220 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
221 SMC_SYSCON_RESET_CNTL
, rst_reg
, 0);
224 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr
, SMC_IND
, RCU_UC_EVENTS
, INTERRUPTS_ENABLED
, 1);
227 /* Call Test SMU message with 0x20000 offset to trigger SMU start */
228 smu7_send_msg_to_smc_offset(hwmgr
);
230 /* Wait done bit to be set */
231 /* Check pass/failed indicator */
233 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr
, SMC_IND
, SMU_STATUS
, SMU_DONE
, 0);
235 if (1 != PHM_READ_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
236 SMU_STATUS
, SMU_PASS
))
237 PP_ASSERT_WITH_CODE(false, "SMU Firmware start failed!", return -1);
239 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixFIRMWARE_FLAGS
, 0);
241 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
242 SMC_SYSCON_RESET_CNTL
, rst_reg
, 1);
244 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
245 SMC_SYSCON_RESET_CNTL
, rst_reg
, 0);
247 /* Wait for firmware to initialize */
248 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr
, SMC_IND
, FIRMWARE_FLAGS
, INTERRUPTS_ENABLED
, 1);
253 static int polaris10_start_smu_in_non_protection_mode(struct pp_hwmgr
*hwmgr
)
257 /* wait for smc boot up */
258 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr
, SMC_IND
, RCU_UC_EVENTS
, boot_seq_done
, 0);
260 /* Clear firmware interrupt enable flag */
261 /* PHM_WRITE_VFPF_INDIRECT_FIELD(pSmuMgr, SMC_IND, SMC_SYSCON_MISC_CNTL, pre_fetcher_en, 1); */
262 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
,
263 ixFIRMWARE_FLAGS
, 0);
265 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
266 SMC_SYSCON_RESET_CNTL
,
269 result
= smu7_upload_smu_firmware_image(hwmgr
);
273 /* Set smc instruct start point at 0x0 */
274 smu7_program_jump_on_start(hwmgr
);
276 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
277 SMC_SYSCON_CLOCK_CNTL_0
, ck_disable
, 0);
279 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
280 SMC_SYSCON_RESET_CNTL
, rst_reg
, 0);
282 /* Wait for firmware to initialize */
284 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr
, SMC_IND
,
285 FIRMWARE_FLAGS
, INTERRUPTS_ENABLED
, 1);
290 static int polaris10_start_smu(struct pp_hwmgr
*hwmgr
)
293 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
295 /* Only start SMC if SMC RAM is not running */
296 if (!smu7_is_smc_ram_running(hwmgr
) && hwmgr
->not_vf
) {
297 smu_data
->protected_mode
= (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
, SMU_FIRMWARE
, SMU_MODE
));
298 smu_data
->smu7_data
.security_hard_key
= (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
, SMU_FIRMWARE
, SMU_SEL
));
300 /* Check if SMU is running in protected mode */
301 if (smu_data
->protected_mode
== 0)
302 result
= polaris10_start_smu_in_non_protection_mode(hwmgr
);
304 result
= polaris10_start_smu_in_protection_mode(hwmgr
);
307 PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result
);
309 polaris10_avfs_event_mgr(hwmgr
);
312 /* Setup SoftRegsStart here for register lookup in case DummyBackEnd is used and ProcessFirmwareHeader is not executed */
313 smu7_read_smc_sram_dword(hwmgr
, SMU7_FIRMWARE_HEADER_LOCATION
+ offsetof(SMU74_Firmware_Header
, SoftRegisters
),
314 &(smu_data
->smu7_data
.soft_regs_start
), 0x40000);
316 result
= smu7_request_smu_load_fw(hwmgr
);
321 static bool polaris10_is_hw_avfs_present(struct pp_hwmgr
*hwmgr
)
325 efuse
= cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixSMU_EFUSE_0
+ (49*4));
333 static int polaris10_smu_init(struct pp_hwmgr
*hwmgr
)
335 struct polaris10_smumgr
*smu_data
;
337 smu_data
= kzalloc(sizeof(struct polaris10_smumgr
), GFP_KERNEL
);
338 if (smu_data
== NULL
)
341 hwmgr
->smu_backend
= smu_data
;
343 if (smu7_init(hwmgr
)) {
351 static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr
*hwmgr
,
352 struct phm_ppt_v1_clock_voltage_dependency_table
*dep_table
,
353 uint32_t clock
, SMU_VoltageLevel
*voltage
, uint32_t *mvdd
)
357 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
359 *voltage
= *mvdd
= 0;
361 /* clock - voltage dependency table is empty table */
362 if (dep_table
->count
== 0)
365 for (i
= 0; i
< dep_table
->count
; i
++) {
366 /* find first sclk bigger than request */
367 if (dep_table
->entries
[i
].clk
>= clock
) {
368 *voltage
|= (dep_table
->entries
[i
].vddc
*
369 VOLTAGE_SCALE
) << VDDC_SHIFT
;
370 if (SMU7_VOLTAGE_CONTROL_NONE
== data
->vddci_control
)
371 *voltage
|= (data
->vbios_boot_state
.vddci_bootup_value
*
372 VOLTAGE_SCALE
) << VDDCI_SHIFT
;
373 else if (dep_table
->entries
[i
].vddci
)
374 *voltage
|= (dep_table
->entries
[i
].vddci
*
375 VOLTAGE_SCALE
) << VDDCI_SHIFT
;
377 vddci
= phm_find_closest_vddci(&(data
->vddci_voltage_table
),
378 (dep_table
->entries
[i
].vddc
-
379 (uint16_t)VDDC_VDDCI_DELTA
));
380 *voltage
|= (vddci
* VOLTAGE_SCALE
) << VDDCI_SHIFT
;
383 if (SMU7_VOLTAGE_CONTROL_NONE
== data
->mvdd_control
)
384 *mvdd
= data
->vbios_boot_state
.mvdd_bootup_value
*
386 else if (dep_table
->entries
[i
].mvdd
)
387 *mvdd
= (uint32_t) dep_table
->entries
[i
].mvdd
*
390 *voltage
|= 1 << PHASES_SHIFT
;
395 /* sclk is bigger than max sclk in the dependence table */
396 *voltage
|= (dep_table
->entries
[i
- 1].vddc
* VOLTAGE_SCALE
) << VDDC_SHIFT
;
398 if (SMU7_VOLTAGE_CONTROL_NONE
== data
->vddci_control
)
399 *voltage
|= (data
->vbios_boot_state
.vddci_bootup_value
*
400 VOLTAGE_SCALE
) << VDDCI_SHIFT
;
401 else if (dep_table
->entries
[i
-1].vddci
) {
402 vddci
= phm_find_closest_vddci(&(data
->vddci_voltage_table
),
403 (dep_table
->entries
[i
].vddc
-
404 (uint16_t)VDDC_VDDCI_DELTA
));
405 *voltage
|= (vddci
* VOLTAGE_SCALE
) << VDDCI_SHIFT
;
408 if (SMU7_VOLTAGE_CONTROL_NONE
== data
->mvdd_control
)
409 *mvdd
= data
->vbios_boot_state
.mvdd_bootup_value
* VOLTAGE_SCALE
;
410 else if (dep_table
->entries
[i
].mvdd
)
411 *mvdd
= (uint32_t) dep_table
->entries
[i
- 1].mvdd
* VOLTAGE_SCALE
;
416 static uint16_t scale_fan_gain_settings(uint16_t raw_setting
)
419 tmp
= raw_setting
* 4096 / 100;
420 return (uint16_t)tmp
;
423 static int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr
*hwmgr
)
425 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
427 const struct polaris10_pt_defaults
*defaults
= smu_data
->power_tune_defaults
;
428 SMU74_Discrete_DpmTable
*table
= &(smu_data
->smc_state_table
);
429 struct phm_ppt_v1_information
*table_info
=
430 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
431 struct phm_cac_tdp_table
*cac_dtp_table
= table_info
->cac_dtp_table
;
432 struct pp_advance_fan_control_parameters
*fan_table
=
433 &hwmgr
->thermal_controller
.advanceFanControlParameters
;
435 const uint16_t *pdef1
;
436 const uint16_t *pdef2
;
438 table
->DefaultTdp
= PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table
->usTDP
* 128));
439 table
->TargetTdp
= PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table
->usTDP
* 128));
441 PP_ASSERT_WITH_CODE(cac_dtp_table
->usTargetOperatingTemp
<= 255,
442 "Target Operating Temp is out of Range!",
445 table
->TemperatureLimitEdge
= PP_HOST_TO_SMC_US(
446 cac_dtp_table
->usTargetOperatingTemp
* 256);
447 table
->TemperatureLimitHotspot
= PP_HOST_TO_SMC_US(
448 cac_dtp_table
->usTemperatureLimitHotspot
* 256);
449 table
->FanGainEdge
= PP_HOST_TO_SMC_US(
450 scale_fan_gain_settings(fan_table
->usFanGainEdge
));
451 table
->FanGainHotspot
= PP_HOST_TO_SMC_US(
452 scale_fan_gain_settings(fan_table
->usFanGainHotspot
));
454 pdef1
= defaults
->BAPMTI_R
;
455 pdef2
= defaults
->BAPMTI_RC
;
457 for (i
= 0; i
< SMU74_DTE_ITERATIONS
; i
++) {
458 for (j
= 0; j
< SMU74_DTE_SOURCES
; j
++) {
459 for (k
= 0; k
< SMU74_DTE_SINKS
; k
++) {
460 table
->BAPMTI_R
[i
][j
][k
] = PP_HOST_TO_SMC_US(*pdef1
);
461 table
->BAPMTI_RC
[i
][j
][k
] = PP_HOST_TO_SMC_US(*pdef2
);
471 static int polaris10_populate_svi_load_line(struct pp_hwmgr
*hwmgr
)
473 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
474 const struct polaris10_pt_defaults
*defaults
= smu_data
->power_tune_defaults
;
476 smu_data
->power_tune_table
.SviLoadLineEn
= defaults
->SviLoadLineEn
;
477 smu_data
->power_tune_table
.SviLoadLineVddC
= defaults
->SviLoadLineVddC
;
478 smu_data
->power_tune_table
.SviLoadLineTrimVddC
= 3;
479 smu_data
->power_tune_table
.SviLoadLineOffsetVddC
= 0;
484 static int polaris10_populate_tdc_limit(struct pp_hwmgr
*hwmgr
)
487 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
488 struct phm_ppt_v1_information
*table_info
=
489 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
490 const struct polaris10_pt_defaults
*defaults
= smu_data
->power_tune_defaults
;
492 tdc_limit
= (uint16_t)(table_info
->cac_dtp_table
->usTDC
* 128);
493 smu_data
->power_tune_table
.TDC_VDDC_PkgLimit
=
494 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit
);
495 smu_data
->power_tune_table
.TDC_VDDC_ThrottleReleaseLimitPerc
=
496 defaults
->TDC_VDDC_ThrottleReleaseLimitPerc
;
497 smu_data
->power_tune_table
.TDC_MAWt
= defaults
->TDC_MAWt
;
502 static int polaris10_populate_dw8(struct pp_hwmgr
*hwmgr
, uint32_t fuse_table_offset
)
504 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
505 const struct polaris10_pt_defaults
*defaults
= smu_data
->power_tune_defaults
;
508 if (smu7_read_smc_sram_dword(hwmgr
,
510 offsetof(SMU74_Discrete_PmFuses
, TdcWaterfallCtl
),
511 (uint32_t *)&temp
, SMC_RAM_END
))
512 PP_ASSERT_WITH_CODE(false,
513 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
516 smu_data
->power_tune_table
.TdcWaterfallCtl
= defaults
->TdcWaterfallCtl
;
517 smu_data
->power_tune_table
.LPMLTemperatureMin
=
518 (uint8_t)((temp
>> 16) & 0xff);
519 smu_data
->power_tune_table
.LPMLTemperatureMax
=
520 (uint8_t)((temp
>> 8) & 0xff);
521 smu_data
->power_tune_table
.Reserved
= (uint8_t)(temp
& 0xff);
526 static int polaris10_populate_temperature_scaler(struct pp_hwmgr
*hwmgr
)
529 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
531 /* Currently not used. Set all to zero. */
532 for (i
= 0; i
< 16; i
++)
533 smu_data
->power_tune_table
.LPMLTemperatureScaler
[i
] = 0;
538 static int polaris10_populate_fuzzy_fan(struct pp_hwmgr
*hwmgr
)
540 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
542 /* TO DO move to hwmgr */
543 if ((hwmgr
->thermal_controller
.advanceFanControlParameters
.usFanOutputSensitivity
& (1 << 15))
544 || 0 == hwmgr
->thermal_controller
.advanceFanControlParameters
.usFanOutputSensitivity
)
545 hwmgr
->thermal_controller
.advanceFanControlParameters
.usFanOutputSensitivity
=
546 hwmgr
->thermal_controller
.advanceFanControlParameters
.usDefaultFanOutputSensitivity
;
548 smu_data
->power_tune_table
.FuzzyFan_PwmSetDelta
= PP_HOST_TO_SMC_US(
549 hwmgr
->thermal_controller
.advanceFanControlParameters
.usFanOutputSensitivity
);
553 static int polaris10_populate_gnb_lpml(struct pp_hwmgr
*hwmgr
)
556 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
558 /* Currently not used. Set all to zero. */
559 for (i
= 0; i
< 16; i
++)
560 smu_data
->power_tune_table
.GnbLPML
[i
] = 0;
565 static int polaris10_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr
*hwmgr
)
567 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
568 struct phm_ppt_v1_information
*table_info
=
569 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
570 uint16_t hi_sidd
= smu_data
->power_tune_table
.BapmVddCBaseLeakageHiSidd
;
571 uint16_t lo_sidd
= smu_data
->power_tune_table
.BapmVddCBaseLeakageLoSidd
;
572 struct phm_cac_tdp_table
*cac_table
= table_info
->cac_dtp_table
;
574 hi_sidd
= (uint16_t)(cac_table
->usHighCACLeakage
/ 100 * 256);
575 lo_sidd
= (uint16_t)(cac_table
->usLowCACLeakage
/ 100 * 256);
577 smu_data
->power_tune_table
.BapmVddCBaseLeakageHiSidd
=
578 CONVERT_FROM_HOST_TO_SMC_US(hi_sidd
);
579 smu_data
->power_tune_table
.BapmVddCBaseLeakageLoSidd
=
580 CONVERT_FROM_HOST_TO_SMC_US(lo_sidd
);
585 static int polaris10_populate_pm_fuses(struct pp_hwmgr
*hwmgr
)
587 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
588 uint32_t pm_fuse_table_offset
;
590 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
591 PHM_PlatformCaps_PowerContainment
)) {
592 if (smu7_read_smc_sram_dword(hwmgr
,
593 SMU7_FIRMWARE_HEADER_LOCATION
+
594 offsetof(SMU74_Firmware_Header
, PmFuseTable
),
595 &pm_fuse_table_offset
, SMC_RAM_END
))
596 PP_ASSERT_WITH_CODE(false,
597 "Attempt to get pm_fuse_table_offset Failed!",
600 if (polaris10_populate_svi_load_line(hwmgr
))
601 PP_ASSERT_WITH_CODE(false,
602 "Attempt to populate SviLoadLine Failed!",
605 if (polaris10_populate_tdc_limit(hwmgr
))
606 PP_ASSERT_WITH_CODE(false,
607 "Attempt to populate TDCLimit Failed!", return -EINVAL
);
609 if (polaris10_populate_dw8(hwmgr
, pm_fuse_table_offset
))
610 PP_ASSERT_WITH_CODE(false,
611 "Attempt to populate TdcWaterfallCtl, "
612 "LPMLTemperature Min and Max Failed!",
615 if (0 != polaris10_populate_temperature_scaler(hwmgr
))
616 PP_ASSERT_WITH_CODE(false,
617 "Attempt to populate LPMLTemperatureScaler Failed!",
620 if (polaris10_populate_fuzzy_fan(hwmgr
))
621 PP_ASSERT_WITH_CODE(false,
622 "Attempt to populate Fuzzy Fan Control parameters Failed!",
625 if (polaris10_populate_gnb_lpml(hwmgr
))
626 PP_ASSERT_WITH_CODE(false,
627 "Attempt to populate GnbLPML Failed!",
630 if (polaris10_populate_bapm_vddc_base_leakage_sidd(hwmgr
))
631 PP_ASSERT_WITH_CODE(false,
632 "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
633 "Sidd Failed!", return -EINVAL
);
635 if (smu7_copy_bytes_to_smc(hwmgr
, pm_fuse_table_offset
,
636 (uint8_t *)&smu_data
->power_tune_table
,
637 (sizeof(struct SMU74_Discrete_PmFuses
) - 92), SMC_RAM_END
))
638 PP_ASSERT_WITH_CODE(false,
639 "Attempt to download PmFuseTable Failed!",
645 static int polaris10_populate_smc_mvdd_table(struct pp_hwmgr
*hwmgr
,
646 SMU74_Discrete_DpmTable
*table
)
648 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
649 uint32_t count
, level
;
651 if (SMU7_VOLTAGE_CONTROL_BY_GPIO
== data
->mvdd_control
) {
652 count
= data
->mvdd_voltage_table
.count
;
653 if (count
> SMU_MAX_SMIO_LEVELS
)
654 count
= SMU_MAX_SMIO_LEVELS
;
655 for (level
= 0; level
< count
; level
++) {
656 table
->SmioTable2
.Pattern
[level
].Voltage
=
657 PP_HOST_TO_SMC_US(data
->mvdd_voltage_table
.entries
[count
].value
* VOLTAGE_SCALE
);
658 /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/
659 table
->SmioTable2
.Pattern
[level
].Smio
=
661 table
->Smio
[level
] |=
662 data
->mvdd_voltage_table
.entries
[level
].smio_low
;
664 table
->SmioMask2
= data
->mvdd_voltage_table
.mask_low
;
666 table
->MvddLevelCount
= (uint32_t) PP_HOST_TO_SMC_UL(count
);
672 static int polaris10_populate_smc_vddci_table(struct pp_hwmgr
*hwmgr
,
673 struct SMU74_Discrete_DpmTable
*table
)
675 uint32_t count
, level
;
676 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
678 count
= data
->vddci_voltage_table
.count
;
680 if (SMU7_VOLTAGE_CONTROL_BY_GPIO
== data
->vddci_control
) {
681 if (count
> SMU_MAX_SMIO_LEVELS
)
682 count
= SMU_MAX_SMIO_LEVELS
;
683 for (level
= 0; level
< count
; ++level
) {
684 table
->SmioTable1
.Pattern
[level
].Voltage
=
685 PP_HOST_TO_SMC_US(data
->vddci_voltage_table
.entries
[level
].value
* VOLTAGE_SCALE
);
686 table
->SmioTable1
.Pattern
[level
].Smio
= (uint8_t) level
;
688 table
->Smio
[level
] |= data
->vddci_voltage_table
.entries
[level
].smio_low
;
692 table
->SmioMask1
= data
->vddci_voltage_table
.mask_low
;
697 static int polaris10_populate_cac_table(struct pp_hwmgr
*hwmgr
,
698 struct SMU74_Discrete_DpmTable
*table
)
702 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
703 struct phm_ppt_v1_information
*table_info
=
704 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
705 struct phm_ppt_v1_voltage_lookup_table
*lookup_table
=
706 table_info
->vddc_lookup_table
;
707 /* tables is already swapped, so in order to use the value from it,
708 * we need to swap it back.
709 * We are populating vddc CAC data to BapmVddc table
710 * in split and merged mode
712 for (count
= 0; count
< lookup_table
->count
; count
++) {
713 index
= phm_get_voltage_index(lookup_table
,
714 data
->vddc_voltage_table
.entries
[count
].value
);
715 table
->BapmVddcVidLoSidd
[count
] = convert_to_vid(lookup_table
->entries
[index
].us_cac_low
);
716 table
->BapmVddcVidHiSidd
[count
] = convert_to_vid(lookup_table
->entries
[index
].us_cac_mid
);
717 table
->BapmVddcVidHiSidd2
[count
] = convert_to_vid(lookup_table
->entries
[index
].us_cac_high
);
723 static int polaris10_populate_smc_voltage_tables(struct pp_hwmgr
*hwmgr
,
724 struct SMU74_Discrete_DpmTable
*table
)
726 polaris10_populate_smc_vddci_table(hwmgr
, table
);
727 polaris10_populate_smc_mvdd_table(hwmgr
, table
);
728 polaris10_populate_cac_table(hwmgr
, table
);
733 static int polaris10_populate_ulv_level(struct pp_hwmgr
*hwmgr
,
734 struct SMU74_Discrete_Ulv
*state
)
736 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
737 struct phm_ppt_v1_information
*table_info
=
738 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
740 state
->CcPwrDynRm
= 0;
741 state
->CcPwrDynRm1
= 0;
743 state
->VddcOffset
= (uint16_t) table_info
->us_ulv_voltage_offset
;
744 state
->VddcOffsetVid
= (uint8_t)(table_info
->us_ulv_voltage_offset
*
745 VOLTAGE_VID_OFFSET_SCALE2
/ VOLTAGE_VID_OFFSET_SCALE1
);
747 if (hwmgr
->chip_id
== CHIP_POLARIS12
|| hwmgr
->is_kicker
)
748 state
->VddcPhase
= data
->vddc_phase_shed_control
^ 0x3;
750 state
->VddcPhase
= (data
->vddc_phase_shed_control
) ? 0 : 1;
752 CONVERT_FROM_HOST_TO_SMC_UL(state
->CcPwrDynRm
);
753 CONVERT_FROM_HOST_TO_SMC_UL(state
->CcPwrDynRm1
);
754 CONVERT_FROM_HOST_TO_SMC_US(state
->VddcOffset
);
759 static int polaris10_populate_ulv_state(struct pp_hwmgr
*hwmgr
,
760 struct SMU74_Discrete_DpmTable
*table
)
762 return polaris10_populate_ulv_level(hwmgr
, &table
->Ulv
);
765 static int polaris10_populate_smc_link_level(struct pp_hwmgr
*hwmgr
,
766 struct SMU74_Discrete_DpmTable
*table
)
768 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
769 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
770 struct smu7_dpm_table
*dpm_table
= &data
->dpm_table
;
773 /* Index (dpm_table->pcie_speed_table.count)
774 * is reserved for PCIE boot level. */
775 for (i
= 0; i
<= dpm_table
->pcie_speed_table
.count
; i
++) {
776 table
->LinkLevel
[i
].PcieGenSpeed
=
777 (uint8_t)dpm_table
->pcie_speed_table
.dpm_levels
[i
].value
;
778 table
->LinkLevel
[i
].PcieLaneCount
= (uint8_t)encode_pcie_lane_width(
779 dpm_table
->pcie_speed_table
.dpm_levels
[i
].param1
);
780 table
->LinkLevel
[i
].EnabledForActivity
= 1;
781 table
->LinkLevel
[i
].SPC
= (uint8_t)(data
->pcie_spc_cap
& 0xff);
782 table
->LinkLevel
[i
].DownThreshold
= PP_HOST_TO_SMC_UL(5);
783 table
->LinkLevel
[i
].UpThreshold
= PP_HOST_TO_SMC_UL(30);
786 smu_data
->smc_state_table
.LinkLevelCount
=
787 (uint8_t)dpm_table
->pcie_speed_table
.count
;
789 /* To Do move to hwmgr */
790 data
->dpm_level_enable_mask
.pcie_dpm_enable_mask
=
791 phm_get_dpm_level_enable_mask_value(&dpm_table
->pcie_speed_table
);
797 static void polaris10_get_sclk_range_table(struct pp_hwmgr
*hwmgr
,
798 SMU74_Discrete_DpmTable
*table
)
800 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
803 struct pp_atom_ctrl_sclk_range_table range_table_from_vbios
= { { {0} } };
805 ref_clk
= amdgpu_asic_get_xclk((struct amdgpu_device
*)hwmgr
->adev
);
807 if (0 == atomctrl_get_smc_sclk_range_table(hwmgr
, &range_table_from_vbios
)) {
808 for (i
= 0; i
< NUM_SCLK_RANGE
; i
++) {
809 table
->SclkFcwRangeTable
[i
].vco_setting
= range_table_from_vbios
.entry
[i
].ucVco_setting
;
810 table
->SclkFcwRangeTable
[i
].postdiv
= range_table_from_vbios
.entry
[i
].ucPostdiv
;
811 table
->SclkFcwRangeTable
[i
].fcw_pcc
= range_table_from_vbios
.entry
[i
].usFcw_pcc
;
813 table
->SclkFcwRangeTable
[i
].fcw_trans_upper
= range_table_from_vbios
.entry
[i
].usFcw_trans_upper
;
814 table
->SclkFcwRangeTable
[i
].fcw_trans_lower
= range_table_from_vbios
.entry
[i
].usRcw_trans_lower
;
816 CONVERT_FROM_HOST_TO_SMC_US(table
->SclkFcwRangeTable
[i
].fcw_pcc
);
817 CONVERT_FROM_HOST_TO_SMC_US(table
->SclkFcwRangeTable
[i
].fcw_trans_upper
);
818 CONVERT_FROM_HOST_TO_SMC_US(table
->SclkFcwRangeTable
[i
].fcw_trans_lower
);
823 for (i
= 0; i
< NUM_SCLK_RANGE
; i
++) {
824 smu_data
->range_table
[i
].trans_lower_frequency
= (ref_clk
* Range_Table
[i
].fcw_trans_lower
) >> Range_Table
[i
].postdiv
;
825 smu_data
->range_table
[i
].trans_upper_frequency
= (ref_clk
* Range_Table
[i
].fcw_trans_upper
) >> Range_Table
[i
].postdiv
;
827 table
->SclkFcwRangeTable
[i
].vco_setting
= Range_Table
[i
].vco_setting
;
828 table
->SclkFcwRangeTable
[i
].postdiv
= Range_Table
[i
].postdiv
;
829 table
->SclkFcwRangeTable
[i
].fcw_pcc
= Range_Table
[i
].fcw_pcc
;
831 table
->SclkFcwRangeTable
[i
].fcw_trans_upper
= Range_Table
[i
].fcw_trans_upper
;
832 table
->SclkFcwRangeTable
[i
].fcw_trans_lower
= Range_Table
[i
].fcw_trans_lower
;
834 CONVERT_FROM_HOST_TO_SMC_US(table
->SclkFcwRangeTable
[i
].fcw_pcc
);
835 CONVERT_FROM_HOST_TO_SMC_US(table
->SclkFcwRangeTable
[i
].fcw_trans_upper
);
836 CONVERT_FROM_HOST_TO_SMC_US(table
->SclkFcwRangeTable
[i
].fcw_trans_lower
);
840 static int polaris10_calculate_sclk_params(struct pp_hwmgr
*hwmgr
,
841 uint32_t clock
, SMU_SclkSetting
*sclk_setting
)
843 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
844 const SMU74_Discrete_DpmTable
*table
= &(smu_data
->smc_state_table
);
845 struct pp_atomctrl_clock_dividers_ai dividers
;
847 uint32_t pcc_target_percent
, pcc_target_freq
, ss_target_percent
, ss_target_freq
;
852 sclk_setting
->SclkFrequency
= clock
;
853 /* get the engine clock dividers for this clock value */
854 result
= atomctrl_get_engine_pll_dividers_ai(hwmgr
, clock
, ÷rs
);
856 sclk_setting
->Fcw_int
= dividers
.usSclk_fcw_int
;
857 sclk_setting
->Fcw_frac
= dividers
.usSclk_fcw_frac
;
858 sclk_setting
->Pcc_fcw_int
= dividers
.usPcc_fcw_int
;
859 sclk_setting
->PllRange
= dividers
.ucSclkPllRange
;
860 sclk_setting
->Sclk_slew_rate
= 0x400;
861 sclk_setting
->Pcc_up_slew_rate
= dividers
.usPcc_fcw_slew_frac
;
862 sclk_setting
->Pcc_down_slew_rate
= 0xffff;
863 sclk_setting
->SSc_En
= dividers
.ucSscEnable
;
864 sclk_setting
->Fcw1_int
= dividers
.usSsc_fcw1_int
;
865 sclk_setting
->Fcw1_frac
= dividers
.usSsc_fcw1_frac
;
866 sclk_setting
->Sclk_ss_slew_rate
= dividers
.usSsc_fcw_slew_frac
;
870 ref_clock
= amdgpu_asic_get_xclk((struct amdgpu_device
*)hwmgr
->adev
);
872 for (i
= 0; i
< NUM_SCLK_RANGE
; i
++) {
873 if (clock
> smu_data
->range_table
[i
].trans_lower_frequency
874 && clock
<= smu_data
->range_table
[i
].trans_upper_frequency
) {
875 sclk_setting
->PllRange
= i
;
880 sclk_setting
->Fcw_int
= (uint16_t)((clock
<< table
->SclkFcwRangeTable
[sclk_setting
->PllRange
].postdiv
) / ref_clock
);
881 temp
= clock
<< table
->SclkFcwRangeTable
[sclk_setting
->PllRange
].postdiv
;
883 do_div(temp
, ref_clock
);
884 sclk_setting
->Fcw_frac
= temp
& 0xffff;
886 pcc_target_percent
= 10; /* Hardcode 10% for now. */
887 pcc_target_freq
= clock
- (clock
* pcc_target_percent
/ 100);
888 sclk_setting
->Pcc_fcw_int
= (uint16_t)((pcc_target_freq
<< table
->SclkFcwRangeTable
[sclk_setting
->PllRange
].postdiv
) / ref_clock
);
890 ss_target_percent
= 2; /* Hardcode 2% for now. */
891 sclk_setting
->SSc_En
= 0;
892 if (ss_target_percent
) {
893 sclk_setting
->SSc_En
= 1;
894 ss_target_freq
= clock
- (clock
* ss_target_percent
/ 100);
895 sclk_setting
->Fcw1_int
= (uint16_t)((ss_target_freq
<< table
->SclkFcwRangeTable
[sclk_setting
->PllRange
].postdiv
) / ref_clock
);
896 temp
= ss_target_freq
<< table
->SclkFcwRangeTable
[sclk_setting
->PllRange
].postdiv
;
898 do_div(temp
, ref_clock
);
899 sclk_setting
->Fcw1_frac
= temp
& 0xffff;
905 static int polaris10_populate_single_graphic_level(struct pp_hwmgr
*hwmgr
,
906 uint32_t clock
, struct SMU74_Discrete_GraphicsLevel
*level
)
909 /* PP_Clocks minClocks; */
911 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
912 struct phm_ppt_v1_information
*table_info
=
913 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
914 SMU_SclkSetting curr_sclk_setting
= { 0 };
915 phm_ppt_v1_clock_voltage_dependency_table
*vdd_dep_table
= NULL
;
917 result
= polaris10_calculate_sclk_params(hwmgr
, clock
, &curr_sclk_setting
);
919 if (hwmgr
->od_enabled
)
920 vdd_dep_table
= (phm_ppt_v1_clock_voltage_dependency_table
*)&data
->odn_dpm_table
.vdd_dependency_on_sclk
;
922 vdd_dep_table
= table_info
->vdd_dep_on_sclk
;
924 /* populate graphics levels */
925 result
= polaris10_get_dependency_volt_by_clk(hwmgr
,
926 vdd_dep_table
, clock
,
927 &level
->MinVoltage
, &mvdd
);
929 PP_ASSERT_WITH_CODE((0 == result
),
930 "can not find VDDC voltage value for "
931 "VDDC engine clock dependency table",
933 level
->ActivityLevel
= data
->current_profile_setting
.sclk_activity
;
935 level
->CcPwrDynRm
= 0;
936 level
->CcPwrDynRm1
= 0;
937 level
->EnabledForActivity
= 0;
938 level
->EnabledForThrottle
= 1;
939 level
->UpHyst
= data
->current_profile_setting
.sclk_up_hyst
;
940 level
->DownHyst
= data
->current_profile_setting
.sclk_down_hyst
;
941 level
->VoltageDownHyst
= 0;
942 level
->PowerThrottle
= 0;
943 data
->display_timing
.min_clock_in_sr
= hwmgr
->display_config
->min_core_set_clock_in_sr
;
945 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_SclkDeepSleep
))
946 level
->DeepSleepDivId
= smu7_get_sleep_divider_id_from_clock(clock
,
947 hwmgr
->display_config
->min_core_set_clock_in_sr
);
949 /* Default to slow, highest DPM level will be
950 * set to PPSMC_DISPLAY_WATERMARK_LOW later.
952 if (data
->update_up_hyst
)
953 level
->UpHyst
= (uint8_t)data
->up_hyst
;
954 if (data
->update_down_hyst
)
955 level
->DownHyst
= (uint8_t)data
->down_hyst
;
957 level
->SclkSetting
= curr_sclk_setting
;
959 CONVERT_FROM_HOST_TO_SMC_UL(level
->MinVoltage
);
960 CONVERT_FROM_HOST_TO_SMC_UL(level
->CcPwrDynRm
);
961 CONVERT_FROM_HOST_TO_SMC_UL(level
->CcPwrDynRm1
);
962 CONVERT_FROM_HOST_TO_SMC_US(level
->ActivityLevel
);
963 CONVERT_FROM_HOST_TO_SMC_UL(level
->SclkSetting
.SclkFrequency
);
964 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Fcw_int
);
965 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Fcw_frac
);
966 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Pcc_fcw_int
);
967 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Sclk_slew_rate
);
968 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Pcc_up_slew_rate
);
969 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Pcc_down_slew_rate
);
970 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Fcw1_int
);
971 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Fcw1_frac
);
972 CONVERT_FROM_HOST_TO_SMC_US(level
->SclkSetting
.Sclk_ss_slew_rate
);
976 static int polaris10_populate_all_graphic_levels(struct pp_hwmgr
*hwmgr
)
978 struct smu7_hwmgr
*hw_data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
979 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
980 struct smu7_dpm_table
*dpm_table
= &hw_data
->dpm_table
;
981 struct phm_ppt_v1_information
*table_info
=
982 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
983 struct phm_ppt_v1_pcie_table
*pcie_table
= table_info
->pcie_table
;
984 uint8_t pcie_entry_cnt
= (uint8_t) hw_data
->dpm_table
.pcie_speed_table
.count
;
986 uint32_t array
= smu_data
->smu7_data
.dpm_table_start
+
987 offsetof(SMU74_Discrete_DpmTable
, GraphicsLevel
);
988 uint32_t array_size
= sizeof(struct SMU74_Discrete_GraphicsLevel
) *
989 SMU74_MAX_LEVELS_GRAPHICS
;
990 struct SMU74_Discrete_GraphicsLevel
*levels
=
991 smu_data
->smc_state_table
.GraphicsLevel
;
992 uint32_t i
, max_entry
;
993 uint8_t hightest_pcie_level_enabled
= 0,
994 lowest_pcie_level_enabled
= 0,
995 mid_pcie_level_enabled
= 0,
998 polaris10_get_sclk_range_table(hwmgr
, &(smu_data
->smc_state_table
));
1000 for (i
= 0; i
< dpm_table
->sclk_table
.count
; i
++) {
1002 result
= polaris10_populate_single_graphic_level(hwmgr
,
1003 dpm_table
->sclk_table
.dpm_levels
[i
].value
,
1004 &(smu_data
->smc_state_table
.GraphicsLevel
[i
]));
1008 /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
1010 levels
[i
].DeepSleepDivId
= 0;
1012 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1013 PHM_PlatformCaps_SPLLShutdownSupport
))
1014 smu_data
->smc_state_table
.GraphicsLevel
[0].SclkSetting
.SSc_En
= 0;
1016 smu_data
->smc_state_table
.GraphicsLevel
[0].EnabledForActivity
= 1;
1017 smu_data
->smc_state_table
.GraphicsDpmLevelCount
=
1018 (uint8_t)dpm_table
->sclk_table
.count
;
1019 hw_data
->dpm_level_enable_mask
.sclk_dpm_enable_mask
=
1020 phm_get_dpm_level_enable_mask_value(&dpm_table
->sclk_table
);
1023 if (pcie_table
!= NULL
) {
1024 PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt
),
1025 "There must be 1 or more PCIE levels defined in PPTable.",
1027 max_entry
= pcie_entry_cnt
- 1;
1028 for (i
= 0; i
< dpm_table
->sclk_table
.count
; i
++)
1029 levels
[i
].pcieDpmLevel
=
1030 (uint8_t) ((i
< max_entry
) ? i
: max_entry
);
1032 while (hw_data
->dpm_level_enable_mask
.pcie_dpm_enable_mask
&&
1033 ((hw_data
->dpm_level_enable_mask
.pcie_dpm_enable_mask
&
1034 (1 << (hightest_pcie_level_enabled
+ 1))) != 0))
1035 hightest_pcie_level_enabled
++;
1037 while (hw_data
->dpm_level_enable_mask
.pcie_dpm_enable_mask
&&
1038 ((hw_data
->dpm_level_enable_mask
.pcie_dpm_enable_mask
&
1039 (1 << lowest_pcie_level_enabled
)) == 0))
1040 lowest_pcie_level_enabled
++;
1042 while ((count
< hightest_pcie_level_enabled
) &&
1043 ((hw_data
->dpm_level_enable_mask
.pcie_dpm_enable_mask
&
1044 (1 << (lowest_pcie_level_enabled
+ 1 + count
))) == 0))
1047 mid_pcie_level_enabled
= (lowest_pcie_level_enabled
+ 1 + count
) <
1048 hightest_pcie_level_enabled
?
1049 (lowest_pcie_level_enabled
+ 1 + count
) :
1050 hightest_pcie_level_enabled
;
1052 /* set pcieDpmLevel to hightest_pcie_level_enabled */
1053 for (i
= 2; i
< dpm_table
->sclk_table
.count
; i
++)
1054 levels
[i
].pcieDpmLevel
= hightest_pcie_level_enabled
;
1056 /* set pcieDpmLevel to lowest_pcie_level_enabled */
1057 levels
[0].pcieDpmLevel
= lowest_pcie_level_enabled
;
1059 /* set pcieDpmLevel to mid_pcie_level_enabled */
1060 levels
[1].pcieDpmLevel
= mid_pcie_level_enabled
;
1062 /* level count will send to smc once at init smc table and never change */
1063 result
= smu7_copy_bytes_to_smc(hwmgr
, array
, (uint8_t *)levels
,
1064 (uint32_t)array_size
, SMC_RAM_END
);
1070 static int polaris10_populate_single_memory_level(struct pp_hwmgr
*hwmgr
,
1071 uint32_t clock
, struct SMU74_Discrete_MemoryLevel
*mem_level
)
1073 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1074 struct phm_ppt_v1_information
*table_info
=
1075 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1077 uint32_t mclk_stutter_mode_threshold
= 40000;
1078 phm_ppt_v1_clock_voltage_dependency_table
*vdd_dep_table
= NULL
;
1081 if (hwmgr
->od_enabled
)
1082 vdd_dep_table
= (phm_ppt_v1_clock_voltage_dependency_table
*)&data
->odn_dpm_table
.vdd_dependency_on_mclk
;
1084 vdd_dep_table
= table_info
->vdd_dep_on_mclk
;
1086 if (vdd_dep_table
) {
1087 result
= polaris10_get_dependency_volt_by_clk(hwmgr
,
1088 vdd_dep_table
, clock
,
1089 &mem_level
->MinVoltage
, &mem_level
->MinMvdd
);
1090 PP_ASSERT_WITH_CODE((0 == result
),
1091 "can not find MinVddc voltage value from memory "
1092 "VDDC voltage dependency table", return result
);
1095 mem_level
->MclkFrequency
= clock
;
1096 mem_level
->EnabledForThrottle
= 1;
1097 mem_level
->EnabledForActivity
= 0;
1098 mem_level
->UpHyst
= data
->current_profile_setting
.mclk_up_hyst
;
1099 mem_level
->DownHyst
= data
->current_profile_setting
.mclk_down_hyst
;
1100 mem_level
->VoltageDownHyst
= 0;
1101 mem_level
->ActivityLevel
= data
->current_profile_setting
.mclk_activity
;
1102 mem_level
->StutterEnable
= false;
1103 mem_level
->DisplayWatermark
= PPSMC_DISPLAY_WATERMARK_LOW
;
1105 data
->display_timing
.num_existing_displays
= hwmgr
->display_config
->num_display
;
1107 if (mclk_stutter_mode_threshold
&&
1108 (clock
<= mclk_stutter_mode_threshold
) &&
1109 (PHM_READ_FIELD(hwmgr
->device
, DPG_PIPE_STUTTER_CONTROL
,
1110 STUTTER_ENABLE
) & 0x1))
1111 mem_level
->StutterEnable
= true;
1114 CONVERT_FROM_HOST_TO_SMC_UL(mem_level
->MinMvdd
);
1115 CONVERT_FROM_HOST_TO_SMC_UL(mem_level
->MclkFrequency
);
1116 CONVERT_FROM_HOST_TO_SMC_US(mem_level
->ActivityLevel
);
1117 CONVERT_FROM_HOST_TO_SMC_UL(mem_level
->MinVoltage
);
1122 static int polaris10_populate_all_memory_levels(struct pp_hwmgr
*hwmgr
)
1124 struct smu7_hwmgr
*hw_data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1125 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1126 struct smu7_dpm_table
*dpm_table
= &hw_data
->dpm_table
;
1128 /* populate MCLK dpm table to SMU7 */
1129 uint32_t array
= smu_data
->smu7_data
.dpm_table_start
+
1130 offsetof(SMU74_Discrete_DpmTable
, MemoryLevel
);
1131 uint32_t array_size
= sizeof(SMU74_Discrete_MemoryLevel
) *
1132 SMU74_MAX_LEVELS_MEMORY
;
1133 struct SMU74_Discrete_MemoryLevel
*levels
=
1134 smu_data
->smc_state_table
.MemoryLevel
;
1137 for (i
= 0; i
< dpm_table
->mclk_table
.count
; i
++) {
1138 PP_ASSERT_WITH_CODE((0 != dpm_table
->mclk_table
.dpm_levels
[i
].value
),
1139 "can not populate memory level as memory clock is zero",
1141 result
= polaris10_populate_single_memory_level(hwmgr
,
1142 dpm_table
->mclk_table
.dpm_levels
[i
].value
,
1144 if (i
== dpm_table
->mclk_table
.count
- 1) {
1145 levels
[i
].DisplayWatermark
= PPSMC_DISPLAY_WATERMARK_HIGH
;
1146 levels
[i
].EnabledForActivity
= 1;
1152 /* In order to prevent MC activity from stutter mode to push DPM up,
1153 * the UVD change complements this by putting the MCLK in
1154 * a higher state by default such that we are not affected by
1155 * up threshold or and MCLK DPM latency.
1157 levels
[0].ActivityLevel
= 0x1f;
1158 CONVERT_FROM_HOST_TO_SMC_US(levels
[0].ActivityLevel
);
1160 smu_data
->smc_state_table
.MemoryDpmLevelCount
=
1161 (uint8_t)dpm_table
->mclk_table
.count
;
1162 hw_data
->dpm_level_enable_mask
.mclk_dpm_enable_mask
=
1163 phm_get_dpm_level_enable_mask_value(&dpm_table
->mclk_table
);
1165 /* level count will send to smc once at init smc table and never change */
1166 result
= smu7_copy_bytes_to_smc(hwmgr
, array
, (uint8_t *)levels
,
1167 (uint32_t)array_size
, SMC_RAM_END
);
1172 static int polaris10_populate_mvdd_value(struct pp_hwmgr
*hwmgr
,
1173 uint32_t mclk
, SMIO_Pattern
*smio_pat
)
1175 const struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1176 struct phm_ppt_v1_information
*table_info
=
1177 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1180 if (SMU7_VOLTAGE_CONTROL_NONE
!= data
->mvdd_control
) {
1181 /* find mvdd value which clock is more than request */
1182 for (i
= 0; i
< table_info
->vdd_dep_on_mclk
->count
; i
++) {
1183 if (mclk
<= table_info
->vdd_dep_on_mclk
->entries
[i
].clk
) {
1184 smio_pat
->Voltage
= data
->mvdd_voltage_table
.entries
[i
].value
;
1188 PP_ASSERT_WITH_CODE(i
< table_info
->vdd_dep_on_mclk
->count
,
1189 "MVDD Voltage is outside the supported range.",
1197 static int polaris10_populate_smc_acpi_level(struct pp_hwmgr
*hwmgr
,
1198 SMU74_Discrete_DpmTable
*table
)
1201 uint32_t sclk_frequency
;
1202 const struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1203 struct phm_ppt_v1_information
*table_info
=
1204 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1205 SMIO_Pattern vol_level
;
1208 table
->ACPILevel
.Flags
&= ~PPSMC_SWSTATE_FLAG_DC
;
1210 /* Get MinVoltage and Frequency from DPM0,
1211 * already converted to SMC_UL */
1212 sclk_frequency
= data
->vbios_boot_state
.sclk_bootup_value
;
1213 result
= polaris10_get_dependency_volt_by_clk(hwmgr
,
1214 table_info
->vdd_dep_on_sclk
,
1216 &table
->ACPILevel
.MinVoltage
, &mvdd
);
1217 PP_ASSERT_WITH_CODE((0 == result
),
1218 "Cannot find ACPI VDDC voltage value "
1219 "in Clock Dependency Table",
1222 result
= polaris10_calculate_sclk_params(hwmgr
, sclk_frequency
, &(table
->ACPILevel
.SclkSetting
));
1223 PP_ASSERT_WITH_CODE(result
== 0, "Error retrieving Engine Clock dividers from VBIOS.", return result
);
1225 table
->ACPILevel
.DeepSleepDivId
= 0;
1226 table
->ACPILevel
.CcPwrDynRm
= 0;
1227 table
->ACPILevel
.CcPwrDynRm1
= 0;
1229 CONVERT_FROM_HOST_TO_SMC_UL(table
->ACPILevel
.Flags
);
1230 CONVERT_FROM_HOST_TO_SMC_UL(table
->ACPILevel
.MinVoltage
);
1231 CONVERT_FROM_HOST_TO_SMC_UL(table
->ACPILevel
.CcPwrDynRm
);
1232 CONVERT_FROM_HOST_TO_SMC_UL(table
->ACPILevel
.CcPwrDynRm1
);
1234 CONVERT_FROM_HOST_TO_SMC_UL(table
->ACPILevel
.SclkSetting
.SclkFrequency
);
1235 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Fcw_int
);
1236 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Fcw_frac
);
1237 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Pcc_fcw_int
);
1238 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Sclk_slew_rate
);
1239 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Pcc_up_slew_rate
);
1240 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Pcc_down_slew_rate
);
1241 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Fcw1_int
);
1242 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Fcw1_frac
);
1243 CONVERT_FROM_HOST_TO_SMC_US(table
->ACPILevel
.SclkSetting
.Sclk_ss_slew_rate
);
1246 /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
1247 table
->MemoryACPILevel
.MclkFrequency
= data
->vbios_boot_state
.mclk_bootup_value
;
1248 result
= polaris10_get_dependency_volt_by_clk(hwmgr
,
1249 table_info
->vdd_dep_on_mclk
,
1250 table
->MemoryACPILevel
.MclkFrequency
,
1251 &table
->MemoryACPILevel
.MinVoltage
, &mvdd
);
1252 PP_ASSERT_WITH_CODE((0 == result
),
1253 "Cannot find ACPI VDDCI voltage value "
1254 "in Clock Dependency Table",
1257 if (!((SMU7_VOLTAGE_CONTROL_NONE
== data
->mvdd_control
) ||
1258 (data
->mclk_dpm_key_disabled
)))
1259 polaris10_populate_mvdd_value(hwmgr
,
1260 data
->dpm_table
.mclk_table
.dpm_levels
[0].value
,
1263 if (0 == polaris10_populate_mvdd_value(hwmgr
, 0, &vol_level
))
1264 table
->MemoryACPILevel
.MinMvdd
= PP_HOST_TO_SMC_UL(vol_level
.Voltage
);
1266 table
->MemoryACPILevel
.MinMvdd
= 0;
1268 table
->MemoryACPILevel
.StutterEnable
= false;
1270 table
->MemoryACPILevel
.EnabledForThrottle
= 0;
1271 table
->MemoryACPILevel
.EnabledForActivity
= 0;
1272 table
->MemoryACPILevel
.UpHyst
= 0;
1273 table
->MemoryACPILevel
.DownHyst
= 100;
1274 table
->MemoryACPILevel
.VoltageDownHyst
= 0;
1275 table
->MemoryACPILevel
.ActivityLevel
=
1276 PP_HOST_TO_SMC_US(data
->current_profile_setting
.mclk_activity
);
1278 CONVERT_FROM_HOST_TO_SMC_UL(table
->MemoryACPILevel
.MclkFrequency
);
1279 CONVERT_FROM_HOST_TO_SMC_UL(table
->MemoryACPILevel
.MinVoltage
);
1284 static int polaris10_populate_smc_vce_level(struct pp_hwmgr
*hwmgr
,
1285 SMU74_Discrete_DpmTable
*table
)
1287 int result
= -EINVAL
;
1289 struct pp_atomctrl_clock_dividers_vi dividers
;
1290 struct phm_ppt_v1_information
*table_info
=
1291 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1292 struct phm_ppt_v1_mm_clock_voltage_dependency_table
*mm_table
=
1293 table_info
->mm_dep_table
;
1294 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1297 table
->VceLevelCount
= (uint8_t)(mm_table
->count
);
1298 table
->VceBootLevel
= 0;
1300 for (count
= 0; count
< table
->VceLevelCount
; count
++) {
1301 table
->VceLevel
[count
].Frequency
= mm_table
->entries
[count
].eclk
;
1302 table
->VceLevel
[count
].MinVoltage
= 0;
1303 table
->VceLevel
[count
].MinVoltage
|=
1304 (mm_table
->entries
[count
].vddc
* VOLTAGE_SCALE
) << VDDC_SHIFT
;
1306 if (SMU7_VOLTAGE_CONTROL_BY_GPIO
== data
->vddci_control
)
1307 vddci
= (uint32_t)phm_find_closest_vddci(&(data
->vddci_voltage_table
),
1308 mm_table
->entries
[count
].vddc
- VDDC_VDDCI_DELTA
);
1309 else if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->vddci_control
)
1310 vddci
= mm_table
->entries
[count
].vddc
- VDDC_VDDCI_DELTA
;
1312 vddci
= (data
->vbios_boot_state
.vddci_bootup_value
* VOLTAGE_SCALE
) << VDDCI_SHIFT
;
1315 table
->VceLevel
[count
].MinVoltage
|=
1316 (vddci
* VOLTAGE_SCALE
) << VDDCI_SHIFT
;
1317 table
->VceLevel
[count
].MinVoltage
|= 1 << PHASES_SHIFT
;
1319 /*retrieve divider value for VBIOS */
1320 result
= atomctrl_get_dfs_pll_dividers_vi(hwmgr
,
1321 table
->VceLevel
[count
].Frequency
, ÷rs
);
1322 PP_ASSERT_WITH_CODE((0 == result
),
1323 "can not find divide id for VCE engine clock",
1326 table
->VceLevel
[count
].Divider
= (uint8_t)dividers
.pll_post_divider
;
1328 CONVERT_FROM_HOST_TO_SMC_UL(table
->VceLevel
[count
].Frequency
);
1329 CONVERT_FROM_HOST_TO_SMC_UL(table
->VceLevel
[count
].MinVoltage
);
1334 static int polaris10_populate_memory_timing_parameters(struct pp_hwmgr
*hwmgr
,
1335 int32_t eng_clock
, int32_t mem_clock
,
1336 SMU74_Discrete_MCArbDramTimingTableEntry
*arb_regs
)
1338 uint32_t dram_timing
;
1339 uint32_t dram_timing2
;
1340 uint32_t burst_time
;
1343 result
= atomctrl_set_engine_dram_timings_rv770(hwmgr
,
1344 eng_clock
, mem_clock
);
1345 PP_ASSERT_WITH_CODE(result
== 0,
1346 "Error calling VBIOS to set DRAM_TIMING.", return result
);
1348 dram_timing
= cgs_read_register(hwmgr
->device
, mmMC_ARB_DRAM_TIMING
);
1349 dram_timing2
= cgs_read_register(hwmgr
->device
, mmMC_ARB_DRAM_TIMING2
);
1350 burst_time
= PHM_READ_FIELD(hwmgr
->device
, MC_ARB_BURST_TIME
, STATE0
);
1353 arb_regs
->McArbDramTiming
= PP_HOST_TO_SMC_UL(dram_timing
);
1354 arb_regs
->McArbDramTiming2
= PP_HOST_TO_SMC_UL(dram_timing2
);
1355 arb_regs
->McArbBurstTime
= (uint8_t)burst_time
;
1360 static int polaris10_program_memory_timing_parameters(struct pp_hwmgr
*hwmgr
)
1362 struct smu7_hwmgr
*hw_data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1363 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1364 struct SMU74_Discrete_MCArbDramTimingTable arb_regs
;
1368 for (i
= 0; i
< hw_data
->dpm_table
.sclk_table
.count
; i
++) {
1369 for (j
= 0; j
< hw_data
->dpm_table
.mclk_table
.count
; j
++) {
1370 result
= polaris10_populate_memory_timing_parameters(hwmgr
,
1371 hw_data
->dpm_table
.sclk_table
.dpm_levels
[i
].value
,
1372 hw_data
->dpm_table
.mclk_table
.dpm_levels
[j
].value
,
1373 &arb_regs
.entries
[i
][j
]);
1375 result
= atomctrl_set_ac_timing_ai(hwmgr
, hw_data
->dpm_table
.mclk_table
.dpm_levels
[j
].value
, j
);
1381 result
= smu7_copy_bytes_to_smc(
1383 smu_data
->smu7_data
.arb_table_start
,
1384 (uint8_t *)&arb_regs
,
1385 sizeof(SMU74_Discrete_MCArbDramTimingTable
),
1390 static int polaris10_populate_smc_uvd_level(struct pp_hwmgr
*hwmgr
,
1391 struct SMU74_Discrete_DpmTable
*table
)
1393 int result
= -EINVAL
;
1395 struct pp_atomctrl_clock_dividers_vi dividers
;
1396 struct phm_ppt_v1_information
*table_info
=
1397 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1398 struct phm_ppt_v1_mm_clock_voltage_dependency_table
*mm_table
=
1399 table_info
->mm_dep_table
;
1400 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1403 table
->UvdLevelCount
= (uint8_t)(mm_table
->count
);
1404 table
->UvdBootLevel
= 0;
1406 for (count
= 0; count
< table
->UvdLevelCount
; count
++) {
1407 table
->UvdLevel
[count
].MinVoltage
= 0;
1408 table
->UvdLevel
[count
].VclkFrequency
= mm_table
->entries
[count
].vclk
;
1409 table
->UvdLevel
[count
].DclkFrequency
= mm_table
->entries
[count
].dclk
;
1410 table
->UvdLevel
[count
].MinVoltage
|= (mm_table
->entries
[count
].vddc
*
1411 VOLTAGE_SCALE
) << VDDC_SHIFT
;
1413 if (SMU7_VOLTAGE_CONTROL_BY_GPIO
== data
->vddci_control
)
1414 vddci
= (uint32_t)phm_find_closest_vddci(&(data
->vddci_voltage_table
),
1415 mm_table
->entries
[count
].vddc
- VDDC_VDDCI_DELTA
);
1416 else if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->vddci_control
)
1417 vddci
= mm_table
->entries
[count
].vddc
- VDDC_VDDCI_DELTA
;
1419 vddci
= (data
->vbios_boot_state
.vddci_bootup_value
* VOLTAGE_SCALE
) << VDDCI_SHIFT
;
1421 table
->UvdLevel
[count
].MinVoltage
|= (vddci
* VOLTAGE_SCALE
) << VDDCI_SHIFT
;
1422 table
->UvdLevel
[count
].MinVoltage
|= 1 << PHASES_SHIFT
;
1424 /* retrieve divider value for VBIOS */
1425 result
= atomctrl_get_dfs_pll_dividers_vi(hwmgr
,
1426 table
->UvdLevel
[count
].VclkFrequency
, ÷rs
);
1427 PP_ASSERT_WITH_CODE((0 == result
),
1428 "can not find divide id for Vclk clock", return result
);
1430 table
->UvdLevel
[count
].VclkDivider
= (uint8_t)dividers
.pll_post_divider
;
1432 result
= atomctrl_get_dfs_pll_dividers_vi(hwmgr
,
1433 table
->UvdLevel
[count
].DclkFrequency
, ÷rs
);
1434 PP_ASSERT_WITH_CODE((0 == result
),
1435 "can not find divide id for Dclk clock", return result
);
1437 table
->UvdLevel
[count
].DclkDivider
= (uint8_t)dividers
.pll_post_divider
;
1439 CONVERT_FROM_HOST_TO_SMC_UL(table
->UvdLevel
[count
].VclkFrequency
);
1440 CONVERT_FROM_HOST_TO_SMC_UL(table
->UvdLevel
[count
].DclkFrequency
);
1441 CONVERT_FROM_HOST_TO_SMC_UL(table
->UvdLevel
[count
].MinVoltage
);
1447 static int polaris10_populate_smc_boot_level(struct pp_hwmgr
*hwmgr
,
1448 struct SMU74_Discrete_DpmTable
*table
)
1451 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1453 table
->GraphicsBootLevel
= 0;
1454 table
->MemoryBootLevel
= 0;
1456 /* find boot level from dpm table */
1457 result
= phm_find_boot_level(&(data
->dpm_table
.sclk_table
),
1458 data
->vbios_boot_state
.sclk_bootup_value
,
1459 (uint32_t *)&(table
->GraphicsBootLevel
));
1461 result
= phm_find_boot_level(&(data
->dpm_table
.mclk_table
),
1462 data
->vbios_boot_state
.mclk_bootup_value
,
1463 (uint32_t *)&(table
->MemoryBootLevel
));
1465 table
->BootVddc
= data
->vbios_boot_state
.vddc_bootup_value
*
1467 table
->BootVddci
= data
->vbios_boot_state
.vddci_bootup_value
*
1469 table
->BootMVdd
= data
->vbios_boot_state
.mvdd_bootup_value
*
1472 CONVERT_FROM_HOST_TO_SMC_US(table
->BootVddc
);
1473 CONVERT_FROM_HOST_TO_SMC_US(table
->BootVddci
);
1474 CONVERT_FROM_HOST_TO_SMC_US(table
->BootMVdd
);
1479 static int polaris10_populate_smc_initailial_state(struct pp_hwmgr
*hwmgr
)
1481 struct smu7_hwmgr
*hw_data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1482 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1483 struct phm_ppt_v1_information
*table_info
=
1484 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1485 uint8_t count
, level
;
1487 count
= (uint8_t)(table_info
->vdd_dep_on_sclk
->count
);
1489 for (level
= 0; level
< count
; level
++) {
1490 if (table_info
->vdd_dep_on_sclk
->entries
[level
].clk
>=
1491 hw_data
->vbios_boot_state
.sclk_bootup_value
) {
1492 smu_data
->smc_state_table
.GraphicsBootLevel
= level
;
1497 count
= (uint8_t)(table_info
->vdd_dep_on_mclk
->count
);
1498 for (level
= 0; level
< count
; level
++) {
1499 if (table_info
->vdd_dep_on_mclk
->entries
[level
].clk
>=
1500 hw_data
->vbios_boot_state
.mclk_bootup_value
) {
1501 smu_data
->smc_state_table
.MemoryBootLevel
= level
;
1509 static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr
*hwmgr
)
1511 uint32_t ro
, efuse
, volt_without_cks
, volt_with_cks
, value
, max
, min
;
1512 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1514 uint8_t i
, stretch_amount
, volt_offset
= 0;
1515 struct phm_ppt_v1_information
*table_info
=
1516 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1517 struct phm_ppt_v1_clock_voltage_dependency_table
*sclk_table
=
1518 table_info
->vdd_dep_on_sclk
;
1520 stretch_amount
= (uint8_t)table_info
->cac_dtp_table
->usClockStretchAmount
;
1522 /* Read SMU_Eefuse to read and calculate RO and determine
1523 * if the part is SS or FF. if RO >= 1660MHz, part is FF.
1525 efuse
= cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
,
1526 ixSMU_EFUSE_0
+ (67 * 4));
1527 efuse
&= 0xFF000000;
1528 efuse
= efuse
>> 24;
1530 if (hwmgr
->chip_id
== CHIP_POLARIS10
) {
1538 ro
= efuse
* (max
- min
) / 255 + min
;
1540 /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
1541 for (i
= 0; i
< sclk_table
->count
; i
++) {
1542 smu_data
->smc_state_table
.Sclk_CKS_masterEn0_7
|=
1543 sclk_table
->entries
[i
].cks_enable
<< i
;
1544 if (hwmgr
->chip_id
== CHIP_POLARIS10
) {
1545 volt_without_cks
= (uint32_t)((2753594000U + (sclk_table
->entries
[i
].clk
/100) * 136418 - (ro
- 70) * 1000000) / \
1546 (2424180 - (sclk_table
->entries
[i
].clk
/100) * 1132925/1000));
1547 volt_with_cks
= (uint32_t)((2797202000U + sclk_table
->entries
[i
].clk
/100 * 3232 - (ro
- 65) * 1000000) / \
1548 (2522480 - sclk_table
->entries
[i
].clk
/100 * 115764/100));
1550 volt_without_cks
= (uint32_t)((2416794800U + (sclk_table
->entries
[i
].clk
/100) * 1476925/10 - (ro
- 50) * 1000000) / \
1551 (2625416 - (sclk_table
->entries
[i
].clk
/100) * (12586807/10000)));
1552 volt_with_cks
= (uint32_t)((2999656000U - sclk_table
->entries
[i
].clk
/100 * 392803 - (ro
- 44) * 1000000) / \
1553 (3422454 - sclk_table
->entries
[i
].clk
/100 * (18886376/10000)));
1556 if (volt_without_cks
>= volt_with_cks
)
1557 volt_offset
= (uint8_t)(((volt_without_cks
- volt_with_cks
+
1558 sclk_table
->entries
[i
].cks_voffset
) * 100 + 624) / 625);
1560 smu_data
->smc_state_table
.Sclk_voltageOffset
[i
] = volt_offset
;
1563 smu_data
->smc_state_table
.LdoRefSel
= (table_info
->cac_dtp_table
->ucCKS_LDO_REFSEL
!= 0) ? table_info
->cac_dtp_table
->ucCKS_LDO_REFSEL
: 6;
1564 /* Populate CKS Lookup Table */
1565 if (stretch_amount
== 0 || stretch_amount
> 5) {
1566 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
1567 PHM_PlatformCaps_ClockStretcher
);
1568 PP_ASSERT_WITH_CODE(false,
1569 "Stretch Amount in PPTable not supported",
1573 value
= cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixPWR_CKS_CNTL
);
1574 value
&= 0xFFFFFFFE;
1575 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixPWR_CKS_CNTL
, value
);
1580 static int polaris10_populate_vr_config(struct pp_hwmgr
*hwmgr
,
1581 struct SMU74_Discrete_DpmTable
*table
)
1583 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1584 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1587 config
= VR_MERGED_WITH_VDDC
;
1588 table
->VRConfig
|= (config
<< VRCONF_VDDGFX_SHIFT
);
1590 /* Set Vddc Voltage Controller */
1591 if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->voltage_control
) {
1592 config
= VR_SVI2_PLANE_1
;
1593 table
->VRConfig
|= config
;
1595 PP_ASSERT_WITH_CODE(false,
1596 "VDDC should be on SVI2 control in merged mode!",
1599 /* Set Vddci Voltage Controller */
1600 if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->vddci_control
) {
1601 config
= VR_SVI2_PLANE_2
; /* only in merged mode */
1602 table
->VRConfig
|= (config
<< VRCONF_VDDCI_SHIFT
);
1603 } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO
== data
->vddci_control
) {
1604 config
= VR_SMIO_PATTERN_1
;
1605 table
->VRConfig
|= (config
<< VRCONF_VDDCI_SHIFT
);
1607 config
= VR_STATIC_VOLTAGE
;
1608 table
->VRConfig
|= (config
<< VRCONF_VDDCI_SHIFT
);
1610 /* Set Mvdd Voltage Controller */
1611 if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->mvdd_control
) {
1612 config
= VR_SVI2_PLANE_2
;
1613 table
->VRConfig
|= (config
<< VRCONF_MVDD_SHIFT
);
1614 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, smu_data
->smu7_data
.soft_regs_start
+
1615 offsetof(SMU74_SoftRegisters
, AllowMvddSwitch
), 0x1);
1617 config
= VR_STATIC_VOLTAGE
;
1618 table
->VRConfig
|= (config
<< VRCONF_MVDD_SHIFT
);
1625 static int polaris10_populate_avfs_parameters(struct pp_hwmgr
*hwmgr
)
1627 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1628 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1630 SMU74_Discrete_DpmTable
*table
= &(smu_data
->smc_state_table
);
1632 struct pp_atom_ctrl__avfs_parameters avfs_params
= {0};
1633 AVFS_meanNsigma_t AVFS_meanNsigma
= { {0} };
1634 AVFS_Sclk_Offset_t AVFS_SclkOffset
= { {0} };
1637 struct phm_ppt_v1_information
*table_info
=
1638 (struct phm_ppt_v1_information
*)hwmgr
->pptable
;
1639 struct phm_ppt_v1_clock_voltage_dependency_table
*sclk_table
=
1640 table_info
->vdd_dep_on_sclk
;
1643 if (!hwmgr
->avfs_supported
)
1646 result
= atomctrl_get_avfs_information(hwmgr
, &avfs_params
);
1649 table
->BTCGB_VDROOP_TABLE
[0].a0
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSON_a0
);
1650 table
->BTCGB_VDROOP_TABLE
[0].a1
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSON_a1
);
1651 table
->BTCGB_VDROOP_TABLE
[0].a2
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSON_a2
);
1652 table
->BTCGB_VDROOP_TABLE
[1].a0
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSOFF_a0
);
1653 table
->BTCGB_VDROOP_TABLE
[1].a1
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSOFF_a1
);
1654 table
->BTCGB_VDROOP_TABLE
[1].a2
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSOFF_a2
);
1655 table
->AVFSGB_VDROOP_TABLE
[0].m1
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSON_m1
);
1656 table
->AVFSGB_VDROOP_TABLE
[0].m2
= PP_HOST_TO_SMC_US(avfs_params
.usAVFSGB_FUSE_TABLE_CKSON_m2
);
1657 table
->AVFSGB_VDROOP_TABLE
[0].b
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSON_b
);
1658 table
->AVFSGB_VDROOP_TABLE
[0].m1_shift
= 24;
1659 table
->AVFSGB_VDROOP_TABLE
[0].m2_shift
= 12;
1660 table
->AVFSGB_VDROOP_TABLE
[1].m1
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
);
1661 table
->AVFSGB_VDROOP_TABLE
[1].m2
= PP_HOST_TO_SMC_US(avfs_params
.usAVFSGB_FUSE_TABLE_CKSOFF_m2
);
1662 table
->AVFSGB_VDROOP_TABLE
[1].b
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSOFF_b
);
1663 table
->AVFSGB_VDROOP_TABLE
[1].m1_shift
= 24;
1664 table
->AVFSGB_VDROOP_TABLE
[1].m2_shift
= 12;
1665 table
->MaxVoltage
= PP_HOST_TO_SMC_US(avfs_params
.usMaxVoltage_0_25mv
);
1666 AVFS_meanNsigma
.Aconstant
[0] = PP_HOST_TO_SMC_UL(avfs_params
.ulAVFS_meanNsigma_Acontant0
);
1667 AVFS_meanNsigma
.Aconstant
[1] = PP_HOST_TO_SMC_UL(avfs_params
.ulAVFS_meanNsigma_Acontant1
);
1668 AVFS_meanNsigma
.Aconstant
[2] = PP_HOST_TO_SMC_UL(avfs_params
.ulAVFS_meanNsigma_Acontant2
);
1669 AVFS_meanNsigma
.DC_tol_sigma
= PP_HOST_TO_SMC_US(avfs_params
.usAVFS_meanNsigma_DC_tol_sigma
);
1670 AVFS_meanNsigma
.Platform_mean
= PP_HOST_TO_SMC_US(avfs_params
.usAVFS_meanNsigma_Platform_mean
);
1671 AVFS_meanNsigma
.PSM_Age_CompFactor
= PP_HOST_TO_SMC_US(avfs_params
.usPSM_Age_ComFactor
);
1672 AVFS_meanNsigma
.Platform_sigma
= PP_HOST_TO_SMC_US(avfs_params
.usAVFS_meanNsigma_Platform_sigma
);
1674 for (i
= 0; i
< NUM_VFT_COLUMNS
; i
++) {
1675 AVFS_meanNsigma
.Static_Voltage_Offset
[i
] = (uint8_t)(sclk_table
->entries
[i
].cks_voffset
* 100 / 625);
1676 AVFS_SclkOffset
.Sclk_Offset
[i
] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table
->entries
[i
].sclk_offset
) / 100);
1679 result
= smu7_read_smc_sram_dword(hwmgr
,
1680 SMU7_FIRMWARE_HEADER_LOCATION
+ offsetof(SMU74_Firmware_Header
, AvfsMeanNSigma
),
1683 smu7_copy_bytes_to_smc(hwmgr
,
1685 (uint8_t *)&AVFS_meanNsigma
,
1686 sizeof(AVFS_meanNsigma_t
),
1689 result
= smu7_read_smc_sram_dword(hwmgr
,
1690 SMU7_FIRMWARE_HEADER_LOCATION
+ offsetof(SMU74_Firmware_Header
, AvfsSclkOffsetTable
),
1692 smu7_copy_bytes_to_smc(hwmgr
,
1694 (uint8_t *)&AVFS_SclkOffset
,
1695 sizeof(AVFS_Sclk_Offset_t
),
1698 data
->avfs_vdroop_override_setting
= (avfs_params
.ucEnableGB_VDROOP_TABLE_CKSON
<< BTCGB0_Vdroop_Enable_SHIFT
) |
1699 (avfs_params
.ucEnableGB_VDROOP_TABLE_CKSOFF
<< BTCGB1_Vdroop_Enable_SHIFT
) |
1700 (avfs_params
.ucEnableGB_FUSE_TABLE_CKSON
<< AVFSGB0_Vdroop_Enable_SHIFT
) |
1701 (avfs_params
.ucEnableGB_FUSE_TABLE_CKSOFF
<< AVFSGB1_Vdroop_Enable_SHIFT
);
1702 data
->apply_avfs_cks_off_voltage
= (avfs_params
.ucEnableApplyAVFS_CKS_OFF_Voltage
== 1) ? true : false;
1707 static int polaris10_init_arb_table_index(struct pp_hwmgr
*hwmgr
)
1709 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1713 /* This is a read-modify-write on the first byte of the ARB table.
1714 * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure
1715 * is the field 'current'.
1716 * This solution is ugly, but we never write the whole table only
1717 * individual fields in it.
1718 * In reality this field should not be in that structure
1719 * but in a soft register.
1721 result
= smu7_read_smc_sram_dword(hwmgr
,
1722 smu_data
->smu7_data
.arb_table_start
, &tmp
, SMC_RAM_END
);
1728 tmp
|= ((uint32_t)MC_CG_ARB_FREQ_F1
) << 24;
1730 return smu7_write_smc_sram_dword(hwmgr
,
1731 smu_data
->smu7_data
.arb_table_start
, tmp
, SMC_RAM_END
);
1734 static void polaris10_initialize_power_tune_defaults(struct pp_hwmgr
*hwmgr
)
1736 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1737 struct phm_ppt_v1_information
*table_info
=
1738 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1741 table_info
->cac_dtp_table
->usPowerTuneDataSetID
<= POWERTUNE_DEFAULT_SET_MAX
&&
1742 table_info
->cac_dtp_table
->usPowerTuneDataSetID
)
1743 smu_data
->power_tune_defaults
=
1744 &polaris10_power_tune_data_set_array
1745 [table_info
->cac_dtp_table
->usPowerTuneDataSetID
- 1];
1747 smu_data
->power_tune_defaults
= &polaris10_power_tune_data_set_array
[0];
1751 static int polaris10_init_smc_table(struct pp_hwmgr
*hwmgr
)
1754 struct smu7_hwmgr
*hw_data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1755 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1757 struct phm_ppt_v1_information
*table_info
=
1758 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1759 struct SMU74_Discrete_DpmTable
*table
= &(smu_data
->smc_state_table
);
1761 struct pp_atomctrl_gpio_pin_assignment gpio_pin
;
1762 pp_atomctrl_clock_dividers_vi dividers
;
1764 polaris10_initialize_power_tune_defaults(hwmgr
);
1766 if (SMU7_VOLTAGE_CONTROL_NONE
!= hw_data
->voltage_control
)
1767 polaris10_populate_smc_voltage_tables(hwmgr
, table
);
1769 table
->SystemFlags
= 0;
1770 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1771 PHM_PlatformCaps_AutomaticDCTransition
))
1772 table
->SystemFlags
|= PPSMC_SYSTEMFLAG_GPIO_DC
;
1774 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1775 PHM_PlatformCaps_StepVddc
))
1776 table
->SystemFlags
|= PPSMC_SYSTEMFLAG_STEPVDDC
;
1778 if (hw_data
->is_memory_gddr5
)
1779 table
->SystemFlags
|= PPSMC_SYSTEMFLAG_GDDR5
;
1781 if (hw_data
->ulv_supported
&& table_info
->us_ulv_voltage_offset
) {
1782 result
= polaris10_populate_ulv_state(hwmgr
, table
);
1783 PP_ASSERT_WITH_CODE(0 == result
,
1784 "Failed to initialize ULV state!", return result
);
1785 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
,
1786 ixCG_ULV_PARAMETER
, SMU7_CGULVPARAMETER_DFLT
);
1789 result
= polaris10_populate_smc_link_level(hwmgr
, table
);
1790 PP_ASSERT_WITH_CODE(0 == result
,
1791 "Failed to initialize Link Level!", return result
);
1793 result
= polaris10_populate_all_graphic_levels(hwmgr
);
1794 PP_ASSERT_WITH_CODE(0 == result
,
1795 "Failed to initialize Graphics Level!", return result
);
1797 result
= polaris10_populate_all_memory_levels(hwmgr
);
1798 PP_ASSERT_WITH_CODE(0 == result
,
1799 "Failed to initialize Memory Level!", return result
);
1801 result
= polaris10_populate_smc_acpi_level(hwmgr
, table
);
1802 PP_ASSERT_WITH_CODE(0 == result
,
1803 "Failed to initialize ACPI Level!", return result
);
1805 result
= polaris10_populate_smc_vce_level(hwmgr
, table
);
1806 PP_ASSERT_WITH_CODE(0 == result
,
1807 "Failed to initialize VCE Level!", return result
);
1809 /* Since only the initial state is completely set up at this point
1810 * (the other states are just copies of the boot state) we only
1811 * need to populate the ARB settings for the initial state.
1813 result
= polaris10_program_memory_timing_parameters(hwmgr
);
1814 PP_ASSERT_WITH_CODE(0 == result
,
1815 "Failed to Write ARB settings for the initial state.", return result
);
1817 result
= polaris10_populate_smc_uvd_level(hwmgr
, table
);
1818 PP_ASSERT_WITH_CODE(0 == result
,
1819 "Failed to initialize UVD Level!", return result
);
1821 result
= polaris10_populate_smc_boot_level(hwmgr
, table
);
1822 PP_ASSERT_WITH_CODE(0 == result
,
1823 "Failed to initialize Boot Level!", return result
);
1825 result
= polaris10_populate_smc_initailial_state(hwmgr
);
1826 PP_ASSERT_WITH_CODE(0 == result
,
1827 "Failed to initialize Boot State!", return result
);
1829 result
= polaris10_populate_bapm_parameters_in_dpm_table(hwmgr
);
1830 PP_ASSERT_WITH_CODE(0 == result
,
1831 "Failed to populate BAPM Parameters!", return result
);
1833 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1834 PHM_PlatformCaps_ClockStretcher
)) {
1835 result
= polaris10_populate_clock_stretcher_data_table(hwmgr
);
1836 PP_ASSERT_WITH_CODE(0 == result
,
1837 "Failed to populate Clock Stretcher Data Table!",
1841 result
= polaris10_populate_avfs_parameters(hwmgr
);
1842 PP_ASSERT_WITH_CODE(0 == result
, "Failed to populate AVFS Parameters!", return result
;);
1844 table
->CurrSclkPllRange
= 0xff;
1845 table
->GraphicsVoltageChangeEnable
= 1;
1846 table
->GraphicsThermThrottleEnable
= 1;
1847 table
->GraphicsInterval
= 1;
1848 table
->VoltageInterval
= 1;
1849 table
->ThermalInterval
= 1;
1850 table
->TemperatureLimitHigh
=
1851 table_info
->cac_dtp_table
->usTargetOperatingTemp
*
1852 SMU7_Q88_FORMAT_CONVERSION_UNIT
;
1853 table
->TemperatureLimitLow
=
1854 (table_info
->cac_dtp_table
->usTargetOperatingTemp
- 1) *
1855 SMU7_Q88_FORMAT_CONVERSION_UNIT
;
1856 table
->MemoryVoltageChangeEnable
= 1;
1857 table
->MemoryInterval
= 1;
1858 table
->VoltageResponseTime
= 0;
1859 table
->PhaseResponseTime
= 0;
1860 table
->MemoryThermThrottleEnable
= 1;
1861 table
->PCIeBootLinkLevel
= 0;
1862 table
->PCIeGenInterval
= 1;
1863 table
->VRConfig
= 0;
1865 result
= polaris10_populate_vr_config(hwmgr
, table
);
1866 PP_ASSERT_WITH_CODE(0 == result
,
1867 "Failed to populate VRConfig setting!", return result
);
1868 hw_data
->vr_config
= table
->VRConfig
;
1869 table
->ThermGpio
= 17;
1870 table
->SclkStepSize
= 0x4000;
1872 if (atomctrl_get_pp_assign_pin(hwmgr
, VDDC_VRHOT_GPIO_PINID
, &gpio_pin
)) {
1873 table
->VRHotGpio
= gpio_pin
.uc_gpio_pin_bit_shift
;
1875 table
->VRHotGpio
= SMU7_UNUSED_GPIO_PIN
;
1876 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
1877 PHM_PlatformCaps_RegulatorHot
);
1880 if (atomctrl_get_pp_assign_pin(hwmgr
, PP_AC_DC_SWITCH_GPIO_PINID
,
1882 table
->AcDcGpio
= gpio_pin
.uc_gpio_pin_bit_shift
;
1883 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
1884 PHM_PlatformCaps_AutomaticDCTransition
);
1886 table
->AcDcGpio
= SMU7_UNUSED_GPIO_PIN
;
1887 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
1888 PHM_PlatformCaps_AutomaticDCTransition
);
1891 /* Thermal Output GPIO */
1892 if (atomctrl_get_pp_assign_pin(hwmgr
, THERMAL_INT_OUTPUT_GPIO_PINID
,
1894 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
1895 PHM_PlatformCaps_ThermalOutGPIO
);
1897 table
->ThermOutGpio
= gpio_pin
.uc_gpio_pin_bit_shift
;
1899 /* For porlarity read GPIOPAD_A with assigned Gpio pin
1900 * since VBIOS will program this register to set 'inactive state',
1901 * driver can then determine 'active state' from this and
1902 * program SMU with correct polarity
1904 table
->ThermOutPolarity
= (0 == (cgs_read_register(hwmgr
->device
, mmGPIOPAD_A
)
1905 & (1 << gpio_pin
.uc_gpio_pin_bit_shift
))) ? 1:0;
1906 table
->ThermOutMode
= SMU7_THERM_OUT_MODE_THERM_ONLY
;
1908 /* if required, combine VRHot/PCC with thermal out GPIO */
1909 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_RegulatorHot
)
1910 && phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_CombinePCCWithThermalSignal
))
1911 table
->ThermOutMode
= SMU7_THERM_OUT_MODE_THERM_VRHOT
;
1913 table
->ThermOutGpio
= 17;
1914 table
->ThermOutPolarity
= 1;
1915 table
->ThermOutMode
= SMU7_THERM_OUT_MODE_DISABLE
;
1918 /* Populate BIF_SCLK levels into SMC DPM table */
1919 for (i
= 0; i
<= hw_data
->dpm_table
.pcie_speed_table
.count
; i
++) {
1920 result
= atomctrl_get_dfs_pll_dividers_vi(hwmgr
, smu_data
->bif_sclk_table
[i
], ÷rs
);
1921 PP_ASSERT_WITH_CODE((result
== 0), "Can not find DFS divide id for Sclk", return result
);
1924 table
->Ulv
.BifSclkDfs
= PP_HOST_TO_SMC_US((USHORT
)(dividers
.pll_post_divider
));
1926 table
->LinkLevel
[i
-1].BifSclkDfs
= PP_HOST_TO_SMC_US((USHORT
)(dividers
.pll_post_divider
));
1929 for (i
= 0; i
< SMU74_MAX_ENTRIES_SMIO
; i
++)
1930 table
->Smio
[i
] = PP_HOST_TO_SMC_UL(table
->Smio
[i
]);
1932 CONVERT_FROM_HOST_TO_SMC_UL(table
->SystemFlags
);
1933 CONVERT_FROM_HOST_TO_SMC_UL(table
->VRConfig
);
1934 CONVERT_FROM_HOST_TO_SMC_UL(table
->SmioMask1
);
1935 CONVERT_FROM_HOST_TO_SMC_UL(table
->SmioMask2
);
1936 CONVERT_FROM_HOST_TO_SMC_UL(table
->SclkStepSize
);
1937 CONVERT_FROM_HOST_TO_SMC_UL(table
->CurrSclkPllRange
);
1938 CONVERT_FROM_HOST_TO_SMC_US(table
->TemperatureLimitHigh
);
1939 CONVERT_FROM_HOST_TO_SMC_US(table
->TemperatureLimitLow
);
1940 CONVERT_FROM_HOST_TO_SMC_US(table
->VoltageResponseTime
);
1941 CONVERT_FROM_HOST_TO_SMC_US(table
->PhaseResponseTime
);
1943 /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
1944 result
= smu7_copy_bytes_to_smc(hwmgr
,
1945 smu_data
->smu7_data
.dpm_table_start
+
1946 offsetof(SMU74_Discrete_DpmTable
, SystemFlags
),
1947 (uint8_t *)&(table
->SystemFlags
),
1948 sizeof(SMU74_Discrete_DpmTable
) - 3 * sizeof(SMU74_PIDController
),
1950 PP_ASSERT_WITH_CODE(0 == result
,
1951 "Failed to upload dpm data to SMC memory!", return result
);
1953 result
= polaris10_init_arb_table_index(hwmgr
);
1954 PP_ASSERT_WITH_CODE(0 == result
,
1955 "Failed to upload arb data to SMC memory!", return result
);
1957 result
= polaris10_populate_pm_fuses(hwmgr
);
1958 PP_ASSERT_WITH_CODE(0 == result
,
1959 "Failed to populate PM fuses to SMC memory!", return result
);
1964 static int polaris10_program_mem_timing_parameters(struct pp_hwmgr
*hwmgr
)
1966 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1968 if (data
->need_update_smu7_dpm_table
&
1969 (DPMTABLE_OD_UPDATE_SCLK
+ DPMTABLE_OD_UPDATE_MCLK
))
1970 return polaris10_program_memory_timing_parameters(hwmgr
);
1975 int polaris10_thermal_avfs_enable(struct pp_hwmgr
*hwmgr
)
1977 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1979 if (!hwmgr
->avfs_supported
)
1982 smum_send_msg_to_smc_with_parameter(hwmgr
,
1983 PPSMC_MSG_SetGBDroopSettings
, data
->avfs_vdroop_override_setting
);
1985 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_EnableAvfs
);
1987 /* Apply avfs cks-off voltages to avoid the overshoot
1988 * when switching to the highest sclk frequency
1990 if (data
->apply_avfs_cks_off_voltage
)
1991 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_ApplyAvfsCksOffVoltage
);
1996 static int polaris10_thermal_setup_fan_table(struct pp_hwmgr
*hwmgr
)
1998 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1999 SMU74_Discrete_FanTable fan_table
= { FDO_MODE_HARDWARE
};
2001 uint32_t t_diff1
, t_diff2
, pwm_diff1
, pwm_diff2
;
2002 uint16_t fdo_min
, slope1
, slope2
;
2003 uint32_t reference_clock
;
2007 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
) {
2008 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2009 PHM_PlatformCaps_MicrocodeFanControl
);
2013 if (smu_data
->smu7_data
.fan_table_start
== 0) {
2014 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2015 PHM_PlatformCaps_MicrocodeFanControl
);
2019 duty100
= PHM_READ_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
2020 CG_FDO_CTRL1
, FMAX_DUTY100
);
2023 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2024 PHM_PlatformCaps_MicrocodeFanControl
);
2028 tmp64
= hwmgr
->thermal_controller
.advanceFanControlParameters
.
2030 do_div(tmp64
, 10000);
2031 fdo_min
= (uint16_t)tmp64
;
2033 t_diff1
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usTMed
-
2034 hwmgr
->thermal_controller
.advanceFanControlParameters
.usTMin
;
2035 t_diff2
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usTHigh
-
2036 hwmgr
->thermal_controller
.advanceFanControlParameters
.usTMed
;
2038 pwm_diff1
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMMed
-
2039 hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMMin
;
2040 pwm_diff2
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMHigh
-
2041 hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMMed
;
2043 slope1
= (uint16_t)((50 + ((16 * duty100
* pwm_diff1
) / t_diff1
)) / 100);
2044 slope2
= (uint16_t)((50 + ((16 * duty100
* pwm_diff2
) / t_diff2
)) / 100);
2046 fan_table
.TempMin
= cpu_to_be16((50 + hwmgr
->
2047 thermal_controller
.advanceFanControlParameters
.usTMin
) / 100);
2048 fan_table
.TempMed
= cpu_to_be16((50 + hwmgr
->
2049 thermal_controller
.advanceFanControlParameters
.usTMed
) / 100);
2050 fan_table
.TempMax
= cpu_to_be16((50 + hwmgr
->
2051 thermal_controller
.advanceFanControlParameters
.usTMax
) / 100);
2053 fan_table
.Slope1
= cpu_to_be16(slope1
);
2054 fan_table
.Slope2
= cpu_to_be16(slope2
);
2056 fan_table
.FdoMin
= cpu_to_be16(fdo_min
);
2058 fan_table
.HystDown
= cpu_to_be16(hwmgr
->
2059 thermal_controller
.advanceFanControlParameters
.ucTHyst
);
2061 fan_table
.HystUp
= cpu_to_be16(1);
2063 fan_table
.HystSlope
= cpu_to_be16(1);
2065 fan_table
.TempRespLim
= cpu_to_be16(5);
2067 reference_clock
= amdgpu_asic_get_xclk((struct amdgpu_device
*)hwmgr
->adev
);
2069 fan_table
.RefreshPeriod
= cpu_to_be32((hwmgr
->
2070 thermal_controller
.advanceFanControlParameters
.ulCycleDelay
*
2071 reference_clock
) / 1600);
2073 fan_table
.FdoMax
= cpu_to_be16((uint16_t)duty100
);
2075 fan_table
.TempSrc
= (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(
2076 hwmgr
->device
, CGS_IND_REG__SMC
,
2077 CG_MULT_THERMAL_CTRL
, TEMP_SEL
);
2079 res
= smu7_copy_bytes_to_smc(hwmgr
, smu_data
->smu7_data
.fan_table_start
,
2080 (uint8_t *)&fan_table
, (uint32_t)sizeof(fan_table
),
2083 if (!res
&& hwmgr
->thermal_controller
.
2084 advanceFanControlParameters
.ucMinimumPWMLimit
)
2085 res
= smum_send_msg_to_smc_with_parameter(hwmgr
,
2086 PPSMC_MSG_SetFanMinPwm
,
2087 hwmgr
->thermal_controller
.
2088 advanceFanControlParameters
.ucMinimumPWMLimit
);
2090 if (!res
&& hwmgr
->thermal_controller
.
2091 advanceFanControlParameters
.ulMinFanSCLKAcousticLimit
)
2092 res
= smum_send_msg_to_smc_with_parameter(hwmgr
,
2093 PPSMC_MSG_SetFanSclkTarget
,
2094 hwmgr
->thermal_controller
.
2095 advanceFanControlParameters
.ulMinFanSCLKAcousticLimit
);
2098 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2099 PHM_PlatformCaps_MicrocodeFanControl
);
2104 static int polaris10_update_uvd_smc_table(struct pp_hwmgr
*hwmgr
)
2106 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2107 uint32_t mm_boot_level_offset
, mm_boot_level_value
;
2108 struct phm_ppt_v1_information
*table_info
=
2109 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
2111 smu_data
->smc_state_table
.UvdBootLevel
= 0;
2112 if (table_info
->mm_dep_table
->count
> 0)
2113 smu_data
->smc_state_table
.UvdBootLevel
=
2114 (uint8_t) (table_info
->mm_dep_table
->count
- 1);
2115 mm_boot_level_offset
= smu_data
->smu7_data
.dpm_table_start
+ offsetof(SMU74_Discrete_DpmTable
,
2117 mm_boot_level_offset
/= 4;
2118 mm_boot_level_offset
*= 4;
2119 mm_boot_level_value
= cgs_read_ind_register(hwmgr
->device
,
2120 CGS_IND_REG__SMC
, mm_boot_level_offset
);
2121 mm_boot_level_value
&= 0x00FFFFFF;
2122 mm_boot_level_value
|= smu_data
->smc_state_table
.UvdBootLevel
<< 24;
2123 cgs_write_ind_register(hwmgr
->device
,
2124 CGS_IND_REG__SMC
, mm_boot_level_offset
, mm_boot_level_value
);
2126 if (!phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2127 PHM_PlatformCaps_UVDDPM
) ||
2128 phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2129 PHM_PlatformCaps_StablePState
))
2130 smum_send_msg_to_smc_with_parameter(hwmgr
,
2131 PPSMC_MSG_UVDDPM_SetEnabledMask
,
2132 (uint32_t)(1 << smu_data
->smc_state_table
.UvdBootLevel
));
2136 static int polaris10_update_vce_smc_table(struct pp_hwmgr
*hwmgr
)
2138 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2139 uint32_t mm_boot_level_offset
, mm_boot_level_value
;
2140 struct phm_ppt_v1_information
*table_info
=
2141 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
2143 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2144 PHM_PlatformCaps_StablePState
))
2145 smu_data
->smc_state_table
.VceBootLevel
=
2146 (uint8_t) (table_info
->mm_dep_table
->count
- 1);
2148 smu_data
->smc_state_table
.VceBootLevel
= 0;
2150 mm_boot_level_offset
= smu_data
->smu7_data
.dpm_table_start
+
2151 offsetof(SMU74_Discrete_DpmTable
, VceBootLevel
);
2152 mm_boot_level_offset
/= 4;
2153 mm_boot_level_offset
*= 4;
2154 mm_boot_level_value
= cgs_read_ind_register(hwmgr
->device
,
2155 CGS_IND_REG__SMC
, mm_boot_level_offset
);
2156 mm_boot_level_value
&= 0xFF00FFFF;
2157 mm_boot_level_value
|= smu_data
->smc_state_table
.VceBootLevel
<< 16;
2158 cgs_write_ind_register(hwmgr
->device
,
2159 CGS_IND_REG__SMC
, mm_boot_level_offset
, mm_boot_level_value
);
2161 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_StablePState
))
2162 smum_send_msg_to_smc_with_parameter(hwmgr
,
2163 PPSMC_MSG_VCEDPM_SetEnabledMask
,
2164 (uint32_t)1 << smu_data
->smc_state_table
.VceBootLevel
);
2168 static int polaris10_update_bif_smc_table(struct pp_hwmgr
*hwmgr
)
2170 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2171 struct phm_ppt_v1_information
*table_info
=
2172 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
2173 struct phm_ppt_v1_pcie_table
*pcie_table
= table_info
->pcie_table
;
2176 max_entry
= (SMU74_MAX_LEVELS_LINK
< pcie_table
->count
) ?
2177 SMU74_MAX_LEVELS_LINK
:
2179 /* Setup BIF_SCLK levels */
2180 for (i
= 0; i
< max_entry
; i
++)
2181 smu_data
->bif_sclk_table
[i
] = pcie_table
->entries
[i
].pcie_sclk
;
2185 static int polaris10_update_smc_table(struct pp_hwmgr
*hwmgr
, uint32_t type
)
2189 polaris10_update_uvd_smc_table(hwmgr
);
2192 polaris10_update_vce_smc_table(hwmgr
);
2195 polaris10_update_bif_smc_table(hwmgr
);
2202 static int polaris10_update_sclk_threshold(struct pp_hwmgr
*hwmgr
)
2204 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
2205 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2208 uint32_t low_sclk_interrupt_threshold
= 0;
2210 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2211 PHM_PlatformCaps_SclkThrottleLowNotification
)
2212 && (data
->low_sclk_interrupt_threshold
!= 0)) {
2213 low_sclk_interrupt_threshold
=
2214 data
->low_sclk_interrupt_threshold
;
2216 CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold
);
2218 result
= smu7_copy_bytes_to_smc(
2220 smu_data
->smu7_data
.dpm_table_start
+
2221 offsetof(SMU74_Discrete_DpmTable
,
2222 LowSclkInterruptThreshold
),
2223 (uint8_t *)&low_sclk_interrupt_threshold
,
2227 PP_ASSERT_WITH_CODE((result
== 0),
2228 "Failed to update SCLK threshold!", return result
);
2230 result
= polaris10_program_mem_timing_parameters(hwmgr
);
2231 PP_ASSERT_WITH_CODE((result
== 0),
2232 "Failed to program memory timing parameters!",
2238 static uint32_t polaris10_get_offsetof(uint32_t type
, uint32_t member
)
2241 case SMU_SoftRegisters
:
2243 case HandshakeDisables
:
2244 return offsetof(SMU74_SoftRegisters
, HandshakeDisables
);
2245 case VoltageChangeTimeout
:
2246 return offsetof(SMU74_SoftRegisters
, VoltageChangeTimeout
);
2247 case AverageGraphicsActivity
:
2248 return offsetof(SMU74_SoftRegisters
, AverageGraphicsActivity
);
2250 return offsetof(SMU74_SoftRegisters
, PreVBlankGap
);
2252 return offsetof(SMU74_SoftRegisters
, VBlankTimeout
);
2253 case UcodeLoadStatus
:
2254 return offsetof(SMU74_SoftRegisters
, UcodeLoadStatus
);
2255 case DRAM_LOG_ADDR_H
:
2256 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_ADDR_H
);
2257 case DRAM_LOG_ADDR_L
:
2258 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_ADDR_L
);
2259 case DRAM_LOG_PHY_ADDR_H
:
2260 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_PHY_ADDR_H
);
2261 case DRAM_LOG_PHY_ADDR_L
:
2262 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_PHY_ADDR_L
);
2263 case DRAM_LOG_BUFF_SIZE
:
2264 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_BUFF_SIZE
);
2266 case SMU_Discrete_DpmTable
:
2269 return offsetof(SMU74_Discrete_DpmTable
, UvdBootLevel
);
2271 return offsetof(SMU74_Discrete_DpmTable
, VceBootLevel
);
2272 case LowSclkInterruptThreshold
:
2273 return offsetof(SMU74_Discrete_DpmTable
, LowSclkInterruptThreshold
);
2276 pr_warn("can't get the offset of type %x member %x\n", type
, member
);
2280 static uint32_t polaris10_get_mac_definition(uint32_t value
)
2283 case SMU_MAX_LEVELS_GRAPHICS
:
2284 return SMU74_MAX_LEVELS_GRAPHICS
;
2285 case SMU_MAX_LEVELS_MEMORY
:
2286 return SMU74_MAX_LEVELS_MEMORY
;
2287 case SMU_MAX_LEVELS_LINK
:
2288 return SMU74_MAX_LEVELS_LINK
;
2289 case SMU_MAX_ENTRIES_SMIO
:
2290 return SMU74_MAX_ENTRIES_SMIO
;
2291 case SMU_MAX_LEVELS_VDDC
:
2292 return SMU74_MAX_LEVELS_VDDC
;
2293 case SMU_MAX_LEVELS_VDDGFX
:
2294 return SMU74_MAX_LEVELS_VDDGFX
;
2295 case SMU_MAX_LEVELS_VDDCI
:
2296 return SMU74_MAX_LEVELS_VDDCI
;
2297 case SMU_MAX_LEVELS_MVDD
:
2298 return SMU74_MAX_LEVELS_MVDD
;
2299 case SMU_UVD_MCLK_HANDSHAKE_DISABLE
:
2300 return SMU7_UVD_MCLK_HANDSHAKE_DISABLE
;
2303 pr_warn("can't get the mac of %x\n", value
);
2307 static int polaris10_process_firmware_header(struct pp_hwmgr
*hwmgr
)
2309 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2310 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
2315 result
= smu7_read_smc_sram_dword(hwmgr
,
2316 SMU7_FIRMWARE_HEADER_LOCATION
+
2317 offsetof(SMU74_Firmware_Header
, DpmTable
),
2321 smu_data
->smu7_data
.dpm_table_start
= tmp
;
2323 error
|= (0 != result
);
2325 result
= smu7_read_smc_sram_dword(hwmgr
,
2326 SMU7_FIRMWARE_HEADER_LOCATION
+
2327 offsetof(SMU74_Firmware_Header
, SoftRegisters
),
2331 data
->soft_regs_start
= tmp
;
2332 smu_data
->smu7_data
.soft_regs_start
= tmp
;
2335 error
|= (0 != result
);
2337 result
= smu7_read_smc_sram_dword(hwmgr
,
2338 SMU7_FIRMWARE_HEADER_LOCATION
+
2339 offsetof(SMU74_Firmware_Header
, mcRegisterTable
),
2343 smu_data
->smu7_data
.mc_reg_table_start
= tmp
;
2345 result
= smu7_read_smc_sram_dword(hwmgr
,
2346 SMU7_FIRMWARE_HEADER_LOCATION
+
2347 offsetof(SMU74_Firmware_Header
, FanTable
),
2351 smu_data
->smu7_data
.fan_table_start
= tmp
;
2353 error
|= (0 != result
);
2355 result
= smu7_read_smc_sram_dword(hwmgr
,
2356 SMU7_FIRMWARE_HEADER_LOCATION
+
2357 offsetof(SMU74_Firmware_Header
, mcArbDramTimingTable
),
2361 smu_data
->smu7_data
.arb_table_start
= tmp
;
2363 error
|= (0 != result
);
2365 result
= smu7_read_smc_sram_dword(hwmgr
,
2366 SMU7_FIRMWARE_HEADER_LOCATION
+
2367 offsetof(SMU74_Firmware_Header
, Version
),
2371 hwmgr
->microcode_version_info
.SMC
= tmp
;
2373 error
|= (0 != result
);
2375 return error
? -1 : 0;
2378 static bool polaris10_is_dpm_running(struct pp_hwmgr
*hwmgr
)
2380 return (1 == PHM_READ_INDIRECT_FIELD(hwmgr
->device
,
2381 CGS_IND_REG__SMC
, FEATURE_STATUS
, VOLTAGE_CONTROLLER_ON
))
2385 static int polaris10_update_dpm_settings(struct pp_hwmgr
*hwmgr
,
2386 void *profile_setting
)
2388 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
2389 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)
2390 (hwmgr
->smu_backend
);
2391 struct profile_mode_setting
*setting
;
2392 struct SMU74_Discrete_GraphicsLevel
*levels
=
2393 smu_data
->smc_state_table
.GraphicsLevel
;
2394 uint32_t array
= smu_data
->smu7_data
.dpm_table_start
+
2395 offsetof(SMU74_Discrete_DpmTable
, GraphicsLevel
);
2397 uint32_t mclk_array
= smu_data
->smu7_data
.dpm_table_start
+
2398 offsetof(SMU74_Discrete_DpmTable
, MemoryLevel
);
2399 struct SMU74_Discrete_MemoryLevel
*mclk_levels
=
2400 smu_data
->smc_state_table
.MemoryLevel
;
2402 uint32_t offset
, up_hyst_offset
, down_hyst_offset
, clk_activity_offset
, tmp
;
2404 if (profile_setting
== NULL
)
2407 setting
= (struct profile_mode_setting
*)profile_setting
;
2409 if (setting
->bupdate_sclk
) {
2410 if (!data
->sclk_dpm_key_disabled
)
2411 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_SCLKDPM_FreezeLevel
);
2412 for (i
= 0; i
< smu_data
->smc_state_table
.GraphicsDpmLevelCount
; i
++) {
2413 if (levels
[i
].ActivityLevel
!=
2414 cpu_to_be16(setting
->sclk_activity
)) {
2415 levels
[i
].ActivityLevel
= cpu_to_be16(setting
->sclk_activity
);
2417 clk_activity_offset
= array
+ (sizeof(SMU74_Discrete_GraphicsLevel
) * i
)
2418 + offsetof(SMU74_Discrete_GraphicsLevel
, ActivityLevel
);
2419 offset
= clk_activity_offset
& ~0x3;
2420 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2421 tmp
= phm_set_field_to_u32(clk_activity_offset
, tmp
, levels
[i
].ActivityLevel
, sizeof(uint16_t));
2422 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2425 if (levels
[i
].UpHyst
!= setting
->sclk_up_hyst
||
2426 levels
[i
].DownHyst
!= setting
->sclk_down_hyst
) {
2427 levels
[i
].UpHyst
= setting
->sclk_up_hyst
;
2428 levels
[i
].DownHyst
= setting
->sclk_down_hyst
;
2429 up_hyst_offset
= array
+ (sizeof(SMU74_Discrete_GraphicsLevel
) * i
)
2430 + offsetof(SMU74_Discrete_GraphicsLevel
, UpHyst
);
2431 down_hyst_offset
= array
+ (sizeof(SMU74_Discrete_GraphicsLevel
) * i
)
2432 + offsetof(SMU74_Discrete_GraphicsLevel
, DownHyst
);
2433 offset
= up_hyst_offset
& ~0x3;
2434 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2435 tmp
= phm_set_field_to_u32(up_hyst_offset
, tmp
, levels
[i
].UpHyst
, sizeof(uint8_t));
2436 tmp
= phm_set_field_to_u32(down_hyst_offset
, tmp
, levels
[i
].DownHyst
, sizeof(uint8_t));
2437 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2440 if (!data
->sclk_dpm_key_disabled
)
2441 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_SCLKDPM_UnfreezeLevel
);
2444 if (setting
->bupdate_mclk
) {
2445 if (!data
->mclk_dpm_key_disabled
)
2446 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_MCLKDPM_FreezeLevel
);
2447 for (i
= 0; i
< smu_data
->smc_state_table
.MemoryDpmLevelCount
; i
++) {
2448 if (mclk_levels
[i
].ActivityLevel
!=
2449 cpu_to_be16(setting
->mclk_activity
)) {
2450 mclk_levels
[i
].ActivityLevel
= cpu_to_be16(setting
->mclk_activity
);
2452 clk_activity_offset
= mclk_array
+ (sizeof(SMU74_Discrete_MemoryLevel
) * i
)
2453 + offsetof(SMU74_Discrete_MemoryLevel
, ActivityLevel
);
2454 offset
= clk_activity_offset
& ~0x3;
2455 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2456 tmp
= phm_set_field_to_u32(clk_activity_offset
, tmp
, mclk_levels
[i
].ActivityLevel
, sizeof(uint16_t));
2457 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2460 if (mclk_levels
[i
].UpHyst
!= setting
->mclk_up_hyst
||
2461 mclk_levels
[i
].DownHyst
!= setting
->mclk_down_hyst
) {
2462 mclk_levels
[i
].UpHyst
= setting
->mclk_up_hyst
;
2463 mclk_levels
[i
].DownHyst
= setting
->mclk_down_hyst
;
2464 up_hyst_offset
= mclk_array
+ (sizeof(SMU74_Discrete_MemoryLevel
) * i
)
2465 + offsetof(SMU74_Discrete_MemoryLevel
, UpHyst
);
2466 down_hyst_offset
= mclk_array
+ (sizeof(SMU74_Discrete_MemoryLevel
) * i
)
2467 + offsetof(SMU74_Discrete_MemoryLevel
, DownHyst
);
2468 offset
= up_hyst_offset
& ~0x3;
2469 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2470 tmp
= phm_set_field_to_u32(up_hyst_offset
, tmp
, mclk_levels
[i
].UpHyst
, sizeof(uint8_t));
2471 tmp
= phm_set_field_to_u32(down_hyst_offset
, tmp
, mclk_levels
[i
].DownHyst
, sizeof(uint8_t));
2472 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2475 if (!data
->mclk_dpm_key_disabled
)
2476 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_MCLKDPM_UnfreezeLevel
);
2481 const struct pp_smumgr_func polaris10_smu_funcs
= {
2482 .smu_init
= polaris10_smu_init
,
2483 .smu_fini
= smu7_smu_fini
,
2484 .start_smu
= polaris10_start_smu
,
2485 .check_fw_load_finish
= smu7_check_fw_load_finish
,
2486 .request_smu_load_fw
= smu7_reload_firmware
,
2487 .request_smu_load_specific_fw
= NULL
,
2488 .send_msg_to_smc
= smu7_send_msg_to_smc
,
2489 .send_msg_to_smc_with_parameter
= smu7_send_msg_to_smc_with_parameter
,
2490 .download_pptable_settings
= NULL
,
2491 .upload_pptable_settings
= NULL
,
2492 .update_smc_table
= polaris10_update_smc_table
,
2493 .get_offsetof
= polaris10_get_offsetof
,
2494 .process_firmware_header
= polaris10_process_firmware_header
,
2495 .init_smc_table
= polaris10_init_smc_table
,
2496 .update_sclk_threshold
= polaris10_update_sclk_threshold
,
2497 .thermal_avfs_enable
= polaris10_thermal_avfs_enable
,
2498 .thermal_setup_fan_table
= polaris10_thermal_setup_fan_table
,
2499 .populate_all_graphic_levels
= polaris10_populate_all_graphic_levels
,
2500 .populate_all_memory_levels
= polaris10_populate_all_memory_levels
,
2501 .get_mac_definition
= polaris10_get_mac_definition
,
2502 .is_dpm_running
= polaris10_is_dpm_running
,
2503 .is_hw_avfs_present
= polaris10_is_hw_avfs_present
,
2504 .update_dpm_settings
= polaris10_update_dpm_settings
,