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
) {
1531 if (hwmgr
->is_kicker
) {
1538 } else if (hwmgr
->chip_id
== CHIP_POLARIS11
) {
1539 if (hwmgr
->is_kicker
) {
1551 ro
= efuse
* (max
- min
) / 255 + min
;
1553 /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
1554 for (i
= 0; i
< sclk_table
->count
; i
++) {
1555 smu_data
->smc_state_table
.Sclk_CKS_masterEn0_7
|=
1556 sclk_table
->entries
[i
].cks_enable
<< i
;
1557 if (hwmgr
->chip_id
== CHIP_POLARIS10
) {
1558 volt_without_cks
= (uint32_t)((2753594000U + (sclk_table
->entries
[i
].clk
/100) * 136418 - (ro
- 70) * 1000000) / \
1559 (2424180 - (sclk_table
->entries
[i
].clk
/100) * 1132925/1000));
1560 volt_with_cks
= (uint32_t)((2797202000U + sclk_table
->entries
[i
].clk
/100 * 3232 - (ro
- 65) * 1000000) / \
1561 (2522480 - sclk_table
->entries
[i
].clk
/100 * 115764/100));
1563 volt_without_cks
= (uint32_t)((2416794800U + (sclk_table
->entries
[i
].clk
/100) * 1476925/10 - (ro
- 50) * 1000000) / \
1564 (2625416 - (sclk_table
->entries
[i
].clk
/100) * (12586807/10000)));
1565 volt_with_cks
= (uint32_t)((2999656000U - sclk_table
->entries
[i
].clk
/100 * 392803 - (ro
- 44) * 1000000) / \
1566 (3422454 - sclk_table
->entries
[i
].clk
/100 * (18886376/10000)));
1569 if (volt_without_cks
>= volt_with_cks
)
1570 volt_offset
= (uint8_t)(((volt_without_cks
- volt_with_cks
+
1571 sclk_table
->entries
[i
].cks_voffset
) * 100 + 624) / 625);
1573 smu_data
->smc_state_table
.Sclk_voltageOffset
[i
] = volt_offset
;
1576 smu_data
->smc_state_table
.LdoRefSel
= (table_info
->cac_dtp_table
->ucCKS_LDO_REFSEL
!= 0) ? table_info
->cac_dtp_table
->ucCKS_LDO_REFSEL
: 6;
1577 /* Populate CKS Lookup Table */
1578 if (stretch_amount
== 0 || stretch_amount
> 5) {
1579 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
1580 PHM_PlatformCaps_ClockStretcher
);
1581 PP_ASSERT_WITH_CODE(false,
1582 "Stretch Amount in PPTable not supported",
1586 value
= cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixPWR_CKS_CNTL
);
1587 value
&= 0xFFFFFFFE;
1588 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, ixPWR_CKS_CNTL
, value
);
1593 static int polaris10_populate_vr_config(struct pp_hwmgr
*hwmgr
,
1594 struct SMU74_Discrete_DpmTable
*table
)
1596 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1597 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1600 config
= VR_MERGED_WITH_VDDC
;
1601 table
->VRConfig
|= (config
<< VRCONF_VDDGFX_SHIFT
);
1603 /* Set Vddc Voltage Controller */
1604 if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->voltage_control
) {
1605 config
= VR_SVI2_PLANE_1
;
1606 table
->VRConfig
|= config
;
1608 PP_ASSERT_WITH_CODE(false,
1609 "VDDC should be on SVI2 control in merged mode!",
1612 /* Set Vddci Voltage Controller */
1613 if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->vddci_control
) {
1614 config
= VR_SVI2_PLANE_2
; /* only in merged mode */
1615 table
->VRConfig
|= (config
<< VRCONF_VDDCI_SHIFT
);
1616 } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO
== data
->vddci_control
) {
1617 config
= VR_SMIO_PATTERN_1
;
1618 table
->VRConfig
|= (config
<< VRCONF_VDDCI_SHIFT
);
1620 config
= VR_STATIC_VOLTAGE
;
1621 table
->VRConfig
|= (config
<< VRCONF_VDDCI_SHIFT
);
1623 /* Set Mvdd Voltage Controller */
1624 if (SMU7_VOLTAGE_CONTROL_BY_SVID2
== data
->mvdd_control
) {
1625 config
= VR_SVI2_PLANE_2
;
1626 table
->VRConfig
|= (config
<< VRCONF_MVDD_SHIFT
);
1627 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, smu_data
->smu7_data
.soft_regs_start
+
1628 offsetof(SMU74_SoftRegisters
, AllowMvddSwitch
), 0x1);
1630 config
= VR_STATIC_VOLTAGE
;
1631 table
->VRConfig
|= (config
<< VRCONF_MVDD_SHIFT
);
1638 static int polaris10_populate_avfs_parameters(struct pp_hwmgr
*hwmgr
)
1640 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1641 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1643 SMU74_Discrete_DpmTable
*table
= &(smu_data
->smc_state_table
);
1645 struct pp_atom_ctrl__avfs_parameters avfs_params
= {0};
1646 AVFS_meanNsigma_t AVFS_meanNsigma
= { {0} };
1647 AVFS_Sclk_Offset_t AVFS_SclkOffset
= { {0} };
1650 struct phm_ppt_v1_information
*table_info
=
1651 (struct phm_ppt_v1_information
*)hwmgr
->pptable
;
1652 struct phm_ppt_v1_clock_voltage_dependency_table
*sclk_table
=
1653 table_info
->vdd_dep_on_sclk
;
1656 if (!hwmgr
->avfs_supported
)
1659 result
= atomctrl_get_avfs_information(hwmgr
, &avfs_params
);
1662 table
->BTCGB_VDROOP_TABLE
[0].a0
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSON_a0
);
1663 table
->BTCGB_VDROOP_TABLE
[0].a1
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSON_a1
);
1664 table
->BTCGB_VDROOP_TABLE
[0].a2
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSON_a2
);
1665 table
->BTCGB_VDROOP_TABLE
[1].a0
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSOFF_a0
);
1666 table
->BTCGB_VDROOP_TABLE
[1].a1
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSOFF_a1
);
1667 table
->BTCGB_VDROOP_TABLE
[1].a2
= PP_HOST_TO_SMC_UL(avfs_params
.ulGB_VDROOP_TABLE_CKSOFF_a2
);
1668 table
->AVFSGB_VDROOP_TABLE
[0].m1
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSON_m1
);
1669 table
->AVFSGB_VDROOP_TABLE
[0].m2
= PP_HOST_TO_SMC_US(avfs_params
.usAVFSGB_FUSE_TABLE_CKSON_m2
);
1670 table
->AVFSGB_VDROOP_TABLE
[0].b
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSON_b
);
1671 table
->AVFSGB_VDROOP_TABLE
[0].m1_shift
= 24;
1672 table
->AVFSGB_VDROOP_TABLE
[0].m2_shift
= 12;
1673 table
->AVFSGB_VDROOP_TABLE
[1].m1
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSOFF_m1
);
1674 table
->AVFSGB_VDROOP_TABLE
[1].m2
= PP_HOST_TO_SMC_US(avfs_params
.usAVFSGB_FUSE_TABLE_CKSOFF_m2
);
1675 table
->AVFSGB_VDROOP_TABLE
[1].b
= PP_HOST_TO_SMC_UL(avfs_params
.ulAVFSGB_FUSE_TABLE_CKSOFF_b
);
1676 table
->AVFSGB_VDROOP_TABLE
[1].m1_shift
= 24;
1677 table
->AVFSGB_VDROOP_TABLE
[1].m2_shift
= 12;
1678 table
->MaxVoltage
= PP_HOST_TO_SMC_US(avfs_params
.usMaxVoltage_0_25mv
);
1679 AVFS_meanNsigma
.Aconstant
[0] = PP_HOST_TO_SMC_UL(avfs_params
.ulAVFS_meanNsigma_Acontant0
);
1680 AVFS_meanNsigma
.Aconstant
[1] = PP_HOST_TO_SMC_UL(avfs_params
.ulAVFS_meanNsigma_Acontant1
);
1681 AVFS_meanNsigma
.Aconstant
[2] = PP_HOST_TO_SMC_UL(avfs_params
.ulAVFS_meanNsigma_Acontant2
);
1682 AVFS_meanNsigma
.DC_tol_sigma
= PP_HOST_TO_SMC_US(avfs_params
.usAVFS_meanNsigma_DC_tol_sigma
);
1683 AVFS_meanNsigma
.Platform_mean
= PP_HOST_TO_SMC_US(avfs_params
.usAVFS_meanNsigma_Platform_mean
);
1684 AVFS_meanNsigma
.PSM_Age_CompFactor
= PP_HOST_TO_SMC_US(avfs_params
.usPSM_Age_ComFactor
);
1685 AVFS_meanNsigma
.Platform_sigma
= PP_HOST_TO_SMC_US(avfs_params
.usAVFS_meanNsigma_Platform_sigma
);
1687 for (i
= 0; i
< NUM_VFT_COLUMNS
; i
++) {
1688 AVFS_meanNsigma
.Static_Voltage_Offset
[i
] = (uint8_t)(sclk_table
->entries
[i
].cks_voffset
* 100 / 625);
1689 AVFS_SclkOffset
.Sclk_Offset
[i
] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table
->entries
[i
].sclk_offset
) / 100);
1692 result
= smu7_read_smc_sram_dword(hwmgr
,
1693 SMU7_FIRMWARE_HEADER_LOCATION
+ offsetof(SMU74_Firmware_Header
, AvfsMeanNSigma
),
1696 smu7_copy_bytes_to_smc(hwmgr
,
1698 (uint8_t *)&AVFS_meanNsigma
,
1699 sizeof(AVFS_meanNsigma_t
),
1702 result
= smu7_read_smc_sram_dword(hwmgr
,
1703 SMU7_FIRMWARE_HEADER_LOCATION
+ offsetof(SMU74_Firmware_Header
, AvfsSclkOffsetTable
),
1705 smu7_copy_bytes_to_smc(hwmgr
,
1707 (uint8_t *)&AVFS_SclkOffset
,
1708 sizeof(AVFS_Sclk_Offset_t
),
1711 data
->avfs_vdroop_override_setting
= (avfs_params
.ucEnableGB_VDROOP_TABLE_CKSON
<< BTCGB0_Vdroop_Enable_SHIFT
) |
1712 (avfs_params
.ucEnableGB_VDROOP_TABLE_CKSOFF
<< BTCGB1_Vdroop_Enable_SHIFT
) |
1713 (avfs_params
.ucEnableGB_FUSE_TABLE_CKSON
<< AVFSGB0_Vdroop_Enable_SHIFT
) |
1714 (avfs_params
.ucEnableGB_FUSE_TABLE_CKSOFF
<< AVFSGB1_Vdroop_Enable_SHIFT
);
1715 data
->apply_avfs_cks_off_voltage
= (avfs_params
.ucEnableApplyAVFS_CKS_OFF_Voltage
== 1) ? true : false;
1720 static int polaris10_init_arb_table_index(struct pp_hwmgr
*hwmgr
)
1722 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1726 /* This is a read-modify-write on the first byte of the ARB table.
1727 * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure
1728 * is the field 'current'.
1729 * This solution is ugly, but we never write the whole table only
1730 * individual fields in it.
1731 * In reality this field should not be in that structure
1732 * but in a soft register.
1734 result
= smu7_read_smc_sram_dword(hwmgr
,
1735 smu_data
->smu7_data
.arb_table_start
, &tmp
, SMC_RAM_END
);
1741 tmp
|= ((uint32_t)MC_CG_ARB_FREQ_F1
) << 24;
1743 return smu7_write_smc_sram_dword(hwmgr
,
1744 smu_data
->smu7_data
.arb_table_start
, tmp
, SMC_RAM_END
);
1747 static void polaris10_initialize_power_tune_defaults(struct pp_hwmgr
*hwmgr
)
1749 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1750 struct phm_ppt_v1_information
*table_info
=
1751 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1754 table_info
->cac_dtp_table
->usPowerTuneDataSetID
<= POWERTUNE_DEFAULT_SET_MAX
&&
1755 table_info
->cac_dtp_table
->usPowerTuneDataSetID
)
1756 smu_data
->power_tune_defaults
=
1757 &polaris10_power_tune_data_set_array
1758 [table_info
->cac_dtp_table
->usPowerTuneDataSetID
- 1];
1760 smu_data
->power_tune_defaults
= &polaris10_power_tune_data_set_array
[0];
1764 static int polaris10_init_smc_table(struct pp_hwmgr
*hwmgr
)
1767 struct smu7_hwmgr
*hw_data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1768 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
1770 struct phm_ppt_v1_information
*table_info
=
1771 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
1772 struct SMU74_Discrete_DpmTable
*table
= &(smu_data
->smc_state_table
);
1774 struct pp_atomctrl_gpio_pin_assignment gpio_pin
;
1775 pp_atomctrl_clock_dividers_vi dividers
;
1777 polaris10_initialize_power_tune_defaults(hwmgr
);
1779 if (SMU7_VOLTAGE_CONTROL_NONE
!= hw_data
->voltage_control
)
1780 polaris10_populate_smc_voltage_tables(hwmgr
, table
);
1782 table
->SystemFlags
= 0;
1783 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1784 PHM_PlatformCaps_AutomaticDCTransition
))
1785 table
->SystemFlags
|= PPSMC_SYSTEMFLAG_GPIO_DC
;
1787 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1788 PHM_PlatformCaps_StepVddc
))
1789 table
->SystemFlags
|= PPSMC_SYSTEMFLAG_STEPVDDC
;
1791 if (hw_data
->is_memory_gddr5
)
1792 table
->SystemFlags
|= PPSMC_SYSTEMFLAG_GDDR5
;
1794 if (hw_data
->ulv_supported
&& table_info
->us_ulv_voltage_offset
) {
1795 result
= polaris10_populate_ulv_state(hwmgr
, table
);
1796 PP_ASSERT_WITH_CODE(0 == result
,
1797 "Failed to initialize ULV state!", return result
);
1798 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
,
1799 ixCG_ULV_PARAMETER
, SMU7_CGULVPARAMETER_DFLT
);
1802 result
= polaris10_populate_smc_link_level(hwmgr
, table
);
1803 PP_ASSERT_WITH_CODE(0 == result
,
1804 "Failed to initialize Link Level!", return result
);
1806 result
= polaris10_populate_all_graphic_levels(hwmgr
);
1807 PP_ASSERT_WITH_CODE(0 == result
,
1808 "Failed to initialize Graphics Level!", return result
);
1810 result
= polaris10_populate_all_memory_levels(hwmgr
);
1811 PP_ASSERT_WITH_CODE(0 == result
,
1812 "Failed to initialize Memory Level!", return result
);
1814 result
= polaris10_populate_smc_acpi_level(hwmgr
, table
);
1815 PP_ASSERT_WITH_CODE(0 == result
,
1816 "Failed to initialize ACPI Level!", return result
);
1818 result
= polaris10_populate_smc_vce_level(hwmgr
, table
);
1819 PP_ASSERT_WITH_CODE(0 == result
,
1820 "Failed to initialize VCE Level!", return result
);
1822 /* Since only the initial state is completely set up at this point
1823 * (the other states are just copies of the boot state) we only
1824 * need to populate the ARB settings for the initial state.
1826 result
= polaris10_program_memory_timing_parameters(hwmgr
);
1827 PP_ASSERT_WITH_CODE(0 == result
,
1828 "Failed to Write ARB settings for the initial state.", return result
);
1830 result
= polaris10_populate_smc_uvd_level(hwmgr
, table
);
1831 PP_ASSERT_WITH_CODE(0 == result
,
1832 "Failed to initialize UVD Level!", return result
);
1834 result
= polaris10_populate_smc_boot_level(hwmgr
, table
);
1835 PP_ASSERT_WITH_CODE(0 == result
,
1836 "Failed to initialize Boot Level!", return result
);
1838 result
= polaris10_populate_smc_initailial_state(hwmgr
);
1839 PP_ASSERT_WITH_CODE(0 == result
,
1840 "Failed to initialize Boot State!", return result
);
1842 result
= polaris10_populate_bapm_parameters_in_dpm_table(hwmgr
);
1843 PP_ASSERT_WITH_CODE(0 == result
,
1844 "Failed to populate BAPM Parameters!", return result
);
1846 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
1847 PHM_PlatformCaps_ClockStretcher
)) {
1848 result
= polaris10_populate_clock_stretcher_data_table(hwmgr
);
1849 PP_ASSERT_WITH_CODE(0 == result
,
1850 "Failed to populate Clock Stretcher Data Table!",
1854 result
= polaris10_populate_avfs_parameters(hwmgr
);
1855 PP_ASSERT_WITH_CODE(0 == result
, "Failed to populate AVFS Parameters!", return result
;);
1857 table
->CurrSclkPllRange
= 0xff;
1858 table
->GraphicsVoltageChangeEnable
= 1;
1859 table
->GraphicsThermThrottleEnable
= 1;
1860 table
->GraphicsInterval
= 1;
1861 table
->VoltageInterval
= 1;
1862 table
->ThermalInterval
= 1;
1863 table
->TemperatureLimitHigh
=
1864 table_info
->cac_dtp_table
->usTargetOperatingTemp
*
1865 SMU7_Q88_FORMAT_CONVERSION_UNIT
;
1866 table
->TemperatureLimitLow
=
1867 (table_info
->cac_dtp_table
->usTargetOperatingTemp
- 1) *
1868 SMU7_Q88_FORMAT_CONVERSION_UNIT
;
1869 table
->MemoryVoltageChangeEnable
= 1;
1870 table
->MemoryInterval
= 1;
1871 table
->VoltageResponseTime
= 0;
1872 table
->PhaseResponseTime
= 0;
1873 table
->MemoryThermThrottleEnable
= 1;
1874 table
->PCIeBootLinkLevel
= 0;
1875 table
->PCIeGenInterval
= 1;
1876 table
->VRConfig
= 0;
1878 result
= polaris10_populate_vr_config(hwmgr
, table
);
1879 PP_ASSERT_WITH_CODE(0 == result
,
1880 "Failed to populate VRConfig setting!", return result
);
1881 hw_data
->vr_config
= table
->VRConfig
;
1882 table
->ThermGpio
= 17;
1883 table
->SclkStepSize
= 0x4000;
1885 if (atomctrl_get_pp_assign_pin(hwmgr
, VDDC_VRHOT_GPIO_PINID
, &gpio_pin
)) {
1886 table
->VRHotGpio
= gpio_pin
.uc_gpio_pin_bit_shift
;
1888 table
->VRHotGpio
= SMU7_UNUSED_GPIO_PIN
;
1889 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
1890 PHM_PlatformCaps_RegulatorHot
);
1893 if (atomctrl_get_pp_assign_pin(hwmgr
, PP_AC_DC_SWITCH_GPIO_PINID
,
1895 table
->AcDcGpio
= gpio_pin
.uc_gpio_pin_bit_shift
;
1896 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
1897 PHM_PlatformCaps_AutomaticDCTransition
);
1899 table
->AcDcGpio
= SMU7_UNUSED_GPIO_PIN
;
1900 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
1901 PHM_PlatformCaps_AutomaticDCTransition
);
1904 /* Thermal Output GPIO */
1905 if (atomctrl_get_pp_assign_pin(hwmgr
, THERMAL_INT_OUTPUT_GPIO_PINID
,
1907 phm_cap_set(hwmgr
->platform_descriptor
.platformCaps
,
1908 PHM_PlatformCaps_ThermalOutGPIO
);
1910 table
->ThermOutGpio
= gpio_pin
.uc_gpio_pin_bit_shift
;
1912 /* For porlarity read GPIOPAD_A with assigned Gpio pin
1913 * since VBIOS will program this register to set 'inactive state',
1914 * driver can then determine 'active state' from this and
1915 * program SMU with correct polarity
1917 table
->ThermOutPolarity
= (0 == (cgs_read_register(hwmgr
->device
, mmGPIOPAD_A
)
1918 & (1 << gpio_pin
.uc_gpio_pin_bit_shift
))) ? 1:0;
1919 table
->ThermOutMode
= SMU7_THERM_OUT_MODE_THERM_ONLY
;
1921 /* if required, combine VRHot/PCC with thermal out GPIO */
1922 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_RegulatorHot
)
1923 && phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_CombinePCCWithThermalSignal
))
1924 table
->ThermOutMode
= SMU7_THERM_OUT_MODE_THERM_VRHOT
;
1926 table
->ThermOutGpio
= 17;
1927 table
->ThermOutPolarity
= 1;
1928 table
->ThermOutMode
= SMU7_THERM_OUT_MODE_DISABLE
;
1931 /* Populate BIF_SCLK levels into SMC DPM table */
1932 for (i
= 0; i
<= hw_data
->dpm_table
.pcie_speed_table
.count
; i
++) {
1933 result
= atomctrl_get_dfs_pll_dividers_vi(hwmgr
, smu_data
->bif_sclk_table
[i
], ÷rs
);
1934 PP_ASSERT_WITH_CODE((result
== 0), "Can not find DFS divide id for Sclk", return result
);
1937 table
->Ulv
.BifSclkDfs
= PP_HOST_TO_SMC_US((USHORT
)(dividers
.pll_post_divider
));
1939 table
->LinkLevel
[i
-1].BifSclkDfs
= PP_HOST_TO_SMC_US((USHORT
)(dividers
.pll_post_divider
));
1942 for (i
= 0; i
< SMU74_MAX_ENTRIES_SMIO
; i
++)
1943 table
->Smio
[i
] = PP_HOST_TO_SMC_UL(table
->Smio
[i
]);
1945 CONVERT_FROM_HOST_TO_SMC_UL(table
->SystemFlags
);
1946 CONVERT_FROM_HOST_TO_SMC_UL(table
->VRConfig
);
1947 CONVERT_FROM_HOST_TO_SMC_UL(table
->SmioMask1
);
1948 CONVERT_FROM_HOST_TO_SMC_UL(table
->SmioMask2
);
1949 CONVERT_FROM_HOST_TO_SMC_UL(table
->SclkStepSize
);
1950 CONVERT_FROM_HOST_TO_SMC_UL(table
->CurrSclkPllRange
);
1951 CONVERT_FROM_HOST_TO_SMC_US(table
->TemperatureLimitHigh
);
1952 CONVERT_FROM_HOST_TO_SMC_US(table
->TemperatureLimitLow
);
1953 CONVERT_FROM_HOST_TO_SMC_US(table
->VoltageResponseTime
);
1954 CONVERT_FROM_HOST_TO_SMC_US(table
->PhaseResponseTime
);
1956 /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
1957 result
= smu7_copy_bytes_to_smc(hwmgr
,
1958 smu_data
->smu7_data
.dpm_table_start
+
1959 offsetof(SMU74_Discrete_DpmTable
, SystemFlags
),
1960 (uint8_t *)&(table
->SystemFlags
),
1961 sizeof(SMU74_Discrete_DpmTable
) - 3 * sizeof(SMU74_PIDController
),
1963 PP_ASSERT_WITH_CODE(0 == result
,
1964 "Failed to upload dpm data to SMC memory!", return result
);
1966 result
= polaris10_init_arb_table_index(hwmgr
);
1967 PP_ASSERT_WITH_CODE(0 == result
,
1968 "Failed to upload arb data to SMC memory!", return result
);
1970 result
= polaris10_populate_pm_fuses(hwmgr
);
1971 PP_ASSERT_WITH_CODE(0 == result
,
1972 "Failed to populate PM fuses to SMC memory!", return result
);
1977 static int polaris10_program_mem_timing_parameters(struct pp_hwmgr
*hwmgr
)
1979 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1981 if (data
->need_update_smu7_dpm_table
&
1982 (DPMTABLE_OD_UPDATE_SCLK
+ DPMTABLE_OD_UPDATE_MCLK
))
1983 return polaris10_program_memory_timing_parameters(hwmgr
);
1988 int polaris10_thermal_avfs_enable(struct pp_hwmgr
*hwmgr
)
1990 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
1992 if (!hwmgr
->avfs_supported
)
1995 smum_send_msg_to_smc_with_parameter(hwmgr
,
1996 PPSMC_MSG_SetGBDroopSettings
, data
->avfs_vdroop_override_setting
);
1998 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_EnableAvfs
);
2000 /* Apply avfs cks-off voltages to avoid the overshoot
2001 * when switching to the highest sclk frequency
2003 if (data
->apply_avfs_cks_off_voltage
)
2004 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_ApplyAvfsCksOffVoltage
);
2009 static int polaris10_thermal_setup_fan_table(struct pp_hwmgr
*hwmgr
)
2011 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2012 SMU74_Discrete_FanTable fan_table
= { FDO_MODE_HARDWARE
};
2014 uint32_t t_diff1
, t_diff2
, pwm_diff1
, pwm_diff2
;
2015 uint16_t fdo_min
, slope1
, slope2
;
2016 uint32_t reference_clock
;
2020 if (hwmgr
->thermal_controller
.fanInfo
.bNoFan
) {
2021 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2022 PHM_PlatformCaps_MicrocodeFanControl
);
2026 if (smu_data
->smu7_data
.fan_table_start
== 0) {
2027 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2028 PHM_PlatformCaps_MicrocodeFanControl
);
2032 duty100
= PHM_READ_VFPF_INDIRECT_FIELD(hwmgr
->device
, CGS_IND_REG__SMC
,
2033 CG_FDO_CTRL1
, FMAX_DUTY100
);
2036 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2037 PHM_PlatformCaps_MicrocodeFanControl
);
2041 /* use hardware fan control */
2042 if (hwmgr
->thermal_controller
.use_hw_fan_control
)
2045 tmp64
= hwmgr
->thermal_controller
.advanceFanControlParameters
.
2047 do_div(tmp64
, 10000);
2048 fdo_min
= (uint16_t)tmp64
;
2050 t_diff1
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usTMed
-
2051 hwmgr
->thermal_controller
.advanceFanControlParameters
.usTMin
;
2052 t_diff2
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usTHigh
-
2053 hwmgr
->thermal_controller
.advanceFanControlParameters
.usTMed
;
2055 pwm_diff1
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMMed
-
2056 hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMMin
;
2057 pwm_diff2
= hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMHigh
-
2058 hwmgr
->thermal_controller
.advanceFanControlParameters
.usPWMMed
;
2060 slope1
= (uint16_t)((50 + ((16 * duty100
* pwm_diff1
) / t_diff1
)) / 100);
2061 slope2
= (uint16_t)((50 + ((16 * duty100
* pwm_diff2
) / t_diff2
)) / 100);
2063 fan_table
.TempMin
= cpu_to_be16((50 + hwmgr
->
2064 thermal_controller
.advanceFanControlParameters
.usTMin
) / 100);
2065 fan_table
.TempMed
= cpu_to_be16((50 + hwmgr
->
2066 thermal_controller
.advanceFanControlParameters
.usTMed
) / 100);
2067 fan_table
.TempMax
= cpu_to_be16((50 + hwmgr
->
2068 thermal_controller
.advanceFanControlParameters
.usTMax
) / 100);
2070 fan_table
.Slope1
= cpu_to_be16(slope1
);
2071 fan_table
.Slope2
= cpu_to_be16(slope2
);
2073 fan_table
.FdoMin
= cpu_to_be16(fdo_min
);
2075 fan_table
.HystDown
= cpu_to_be16(hwmgr
->
2076 thermal_controller
.advanceFanControlParameters
.ucTHyst
);
2078 fan_table
.HystUp
= cpu_to_be16(1);
2080 fan_table
.HystSlope
= cpu_to_be16(1);
2082 fan_table
.TempRespLim
= cpu_to_be16(5);
2084 reference_clock
= amdgpu_asic_get_xclk((struct amdgpu_device
*)hwmgr
->adev
);
2086 fan_table
.RefreshPeriod
= cpu_to_be32((hwmgr
->
2087 thermal_controller
.advanceFanControlParameters
.ulCycleDelay
*
2088 reference_clock
) / 1600);
2090 fan_table
.FdoMax
= cpu_to_be16((uint16_t)duty100
);
2092 fan_table
.TempSrc
= (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(
2093 hwmgr
->device
, CGS_IND_REG__SMC
,
2094 CG_MULT_THERMAL_CTRL
, TEMP_SEL
);
2096 res
= smu7_copy_bytes_to_smc(hwmgr
, smu_data
->smu7_data
.fan_table_start
,
2097 (uint8_t *)&fan_table
, (uint32_t)sizeof(fan_table
),
2100 if (!res
&& hwmgr
->thermal_controller
.
2101 advanceFanControlParameters
.ucMinimumPWMLimit
)
2102 res
= smum_send_msg_to_smc_with_parameter(hwmgr
,
2103 PPSMC_MSG_SetFanMinPwm
,
2104 hwmgr
->thermal_controller
.
2105 advanceFanControlParameters
.ucMinimumPWMLimit
);
2107 if (!res
&& hwmgr
->thermal_controller
.
2108 advanceFanControlParameters
.ulMinFanSCLKAcousticLimit
)
2109 res
= smum_send_msg_to_smc_with_parameter(hwmgr
,
2110 PPSMC_MSG_SetFanSclkTarget
,
2111 hwmgr
->thermal_controller
.
2112 advanceFanControlParameters
.ulMinFanSCLKAcousticLimit
);
2115 phm_cap_unset(hwmgr
->platform_descriptor
.platformCaps
,
2116 PHM_PlatformCaps_MicrocodeFanControl
);
2121 static int polaris10_update_uvd_smc_table(struct pp_hwmgr
*hwmgr
)
2123 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2124 uint32_t mm_boot_level_offset
, mm_boot_level_value
;
2125 struct phm_ppt_v1_information
*table_info
=
2126 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
2128 smu_data
->smc_state_table
.UvdBootLevel
= 0;
2129 if (table_info
->mm_dep_table
->count
> 0)
2130 smu_data
->smc_state_table
.UvdBootLevel
=
2131 (uint8_t) (table_info
->mm_dep_table
->count
- 1);
2132 mm_boot_level_offset
= smu_data
->smu7_data
.dpm_table_start
+ offsetof(SMU74_Discrete_DpmTable
,
2134 mm_boot_level_offset
/= 4;
2135 mm_boot_level_offset
*= 4;
2136 mm_boot_level_value
= cgs_read_ind_register(hwmgr
->device
,
2137 CGS_IND_REG__SMC
, mm_boot_level_offset
);
2138 mm_boot_level_value
&= 0x00FFFFFF;
2139 mm_boot_level_value
|= smu_data
->smc_state_table
.UvdBootLevel
<< 24;
2140 cgs_write_ind_register(hwmgr
->device
,
2141 CGS_IND_REG__SMC
, mm_boot_level_offset
, mm_boot_level_value
);
2143 if (!phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2144 PHM_PlatformCaps_UVDDPM
) ||
2145 phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2146 PHM_PlatformCaps_StablePState
))
2147 smum_send_msg_to_smc_with_parameter(hwmgr
,
2148 PPSMC_MSG_UVDDPM_SetEnabledMask
,
2149 (uint32_t)(1 << smu_data
->smc_state_table
.UvdBootLevel
));
2153 static int polaris10_update_vce_smc_table(struct pp_hwmgr
*hwmgr
)
2155 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2156 uint32_t mm_boot_level_offset
, mm_boot_level_value
;
2157 struct phm_ppt_v1_information
*table_info
=
2158 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
2160 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2161 PHM_PlatformCaps_StablePState
))
2162 smu_data
->smc_state_table
.VceBootLevel
=
2163 (uint8_t) (table_info
->mm_dep_table
->count
- 1);
2165 smu_data
->smc_state_table
.VceBootLevel
= 0;
2167 mm_boot_level_offset
= smu_data
->smu7_data
.dpm_table_start
+
2168 offsetof(SMU74_Discrete_DpmTable
, VceBootLevel
);
2169 mm_boot_level_offset
/= 4;
2170 mm_boot_level_offset
*= 4;
2171 mm_boot_level_value
= cgs_read_ind_register(hwmgr
->device
,
2172 CGS_IND_REG__SMC
, mm_boot_level_offset
);
2173 mm_boot_level_value
&= 0xFF00FFFF;
2174 mm_boot_level_value
|= smu_data
->smc_state_table
.VceBootLevel
<< 16;
2175 cgs_write_ind_register(hwmgr
->device
,
2176 CGS_IND_REG__SMC
, mm_boot_level_offset
, mm_boot_level_value
);
2178 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
, PHM_PlatformCaps_StablePState
))
2179 smum_send_msg_to_smc_with_parameter(hwmgr
,
2180 PPSMC_MSG_VCEDPM_SetEnabledMask
,
2181 (uint32_t)1 << smu_data
->smc_state_table
.VceBootLevel
);
2185 static int polaris10_update_bif_smc_table(struct pp_hwmgr
*hwmgr
)
2187 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2188 struct phm_ppt_v1_information
*table_info
=
2189 (struct phm_ppt_v1_information
*)(hwmgr
->pptable
);
2190 struct phm_ppt_v1_pcie_table
*pcie_table
= table_info
->pcie_table
;
2193 max_entry
= (SMU74_MAX_LEVELS_LINK
< pcie_table
->count
) ?
2194 SMU74_MAX_LEVELS_LINK
:
2196 /* Setup BIF_SCLK levels */
2197 for (i
= 0; i
< max_entry
; i
++)
2198 smu_data
->bif_sclk_table
[i
] = pcie_table
->entries
[i
].pcie_sclk
;
2202 static int polaris10_update_smc_table(struct pp_hwmgr
*hwmgr
, uint32_t type
)
2206 polaris10_update_uvd_smc_table(hwmgr
);
2209 polaris10_update_vce_smc_table(hwmgr
);
2212 polaris10_update_bif_smc_table(hwmgr
);
2219 static int polaris10_update_sclk_threshold(struct pp_hwmgr
*hwmgr
)
2221 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
2222 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2225 uint32_t low_sclk_interrupt_threshold
= 0;
2227 if (phm_cap_enabled(hwmgr
->platform_descriptor
.platformCaps
,
2228 PHM_PlatformCaps_SclkThrottleLowNotification
)
2229 && (data
->low_sclk_interrupt_threshold
!= 0)) {
2230 low_sclk_interrupt_threshold
=
2231 data
->low_sclk_interrupt_threshold
;
2233 CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold
);
2235 result
= smu7_copy_bytes_to_smc(
2237 smu_data
->smu7_data
.dpm_table_start
+
2238 offsetof(SMU74_Discrete_DpmTable
,
2239 LowSclkInterruptThreshold
),
2240 (uint8_t *)&low_sclk_interrupt_threshold
,
2244 PP_ASSERT_WITH_CODE((result
== 0),
2245 "Failed to update SCLK threshold!", return result
);
2247 result
= polaris10_program_mem_timing_parameters(hwmgr
);
2248 PP_ASSERT_WITH_CODE((result
== 0),
2249 "Failed to program memory timing parameters!",
2255 static uint32_t polaris10_get_offsetof(uint32_t type
, uint32_t member
)
2258 case SMU_SoftRegisters
:
2260 case HandshakeDisables
:
2261 return offsetof(SMU74_SoftRegisters
, HandshakeDisables
);
2262 case VoltageChangeTimeout
:
2263 return offsetof(SMU74_SoftRegisters
, VoltageChangeTimeout
);
2264 case AverageGraphicsActivity
:
2265 return offsetof(SMU74_SoftRegisters
, AverageGraphicsActivity
);
2267 return offsetof(SMU74_SoftRegisters
, PreVBlankGap
);
2269 return offsetof(SMU74_SoftRegisters
, VBlankTimeout
);
2270 case UcodeLoadStatus
:
2271 return offsetof(SMU74_SoftRegisters
, UcodeLoadStatus
);
2272 case DRAM_LOG_ADDR_H
:
2273 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_ADDR_H
);
2274 case DRAM_LOG_ADDR_L
:
2275 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_ADDR_L
);
2276 case DRAM_LOG_PHY_ADDR_H
:
2277 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_PHY_ADDR_H
);
2278 case DRAM_LOG_PHY_ADDR_L
:
2279 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_PHY_ADDR_L
);
2280 case DRAM_LOG_BUFF_SIZE
:
2281 return offsetof(SMU74_SoftRegisters
, DRAM_LOG_BUFF_SIZE
);
2283 case SMU_Discrete_DpmTable
:
2286 return offsetof(SMU74_Discrete_DpmTable
, UvdBootLevel
);
2288 return offsetof(SMU74_Discrete_DpmTable
, VceBootLevel
);
2289 case LowSclkInterruptThreshold
:
2290 return offsetof(SMU74_Discrete_DpmTable
, LowSclkInterruptThreshold
);
2293 pr_warn("can't get the offset of type %x member %x\n", type
, member
);
2297 static uint32_t polaris10_get_mac_definition(uint32_t value
)
2300 case SMU_MAX_LEVELS_GRAPHICS
:
2301 return SMU74_MAX_LEVELS_GRAPHICS
;
2302 case SMU_MAX_LEVELS_MEMORY
:
2303 return SMU74_MAX_LEVELS_MEMORY
;
2304 case SMU_MAX_LEVELS_LINK
:
2305 return SMU74_MAX_LEVELS_LINK
;
2306 case SMU_MAX_ENTRIES_SMIO
:
2307 return SMU74_MAX_ENTRIES_SMIO
;
2308 case SMU_MAX_LEVELS_VDDC
:
2309 return SMU74_MAX_LEVELS_VDDC
;
2310 case SMU_MAX_LEVELS_VDDGFX
:
2311 return SMU74_MAX_LEVELS_VDDGFX
;
2312 case SMU_MAX_LEVELS_VDDCI
:
2313 return SMU74_MAX_LEVELS_VDDCI
;
2314 case SMU_MAX_LEVELS_MVDD
:
2315 return SMU74_MAX_LEVELS_MVDD
;
2316 case SMU_UVD_MCLK_HANDSHAKE_DISABLE
:
2317 return SMU7_UVD_MCLK_HANDSHAKE_DISABLE
;
2320 pr_warn("can't get the mac of %x\n", value
);
2324 static int polaris10_process_firmware_header(struct pp_hwmgr
*hwmgr
)
2326 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)(hwmgr
->smu_backend
);
2327 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
2332 result
= smu7_read_smc_sram_dword(hwmgr
,
2333 SMU7_FIRMWARE_HEADER_LOCATION
+
2334 offsetof(SMU74_Firmware_Header
, DpmTable
),
2338 smu_data
->smu7_data
.dpm_table_start
= tmp
;
2340 error
|= (0 != result
);
2342 result
= smu7_read_smc_sram_dword(hwmgr
,
2343 SMU7_FIRMWARE_HEADER_LOCATION
+
2344 offsetof(SMU74_Firmware_Header
, SoftRegisters
),
2348 data
->soft_regs_start
= tmp
;
2349 smu_data
->smu7_data
.soft_regs_start
= tmp
;
2352 error
|= (0 != result
);
2354 result
= smu7_read_smc_sram_dword(hwmgr
,
2355 SMU7_FIRMWARE_HEADER_LOCATION
+
2356 offsetof(SMU74_Firmware_Header
, mcRegisterTable
),
2360 smu_data
->smu7_data
.mc_reg_table_start
= tmp
;
2362 result
= smu7_read_smc_sram_dword(hwmgr
,
2363 SMU7_FIRMWARE_HEADER_LOCATION
+
2364 offsetof(SMU74_Firmware_Header
, FanTable
),
2368 smu_data
->smu7_data
.fan_table_start
= tmp
;
2370 error
|= (0 != result
);
2372 result
= smu7_read_smc_sram_dword(hwmgr
,
2373 SMU7_FIRMWARE_HEADER_LOCATION
+
2374 offsetof(SMU74_Firmware_Header
, mcArbDramTimingTable
),
2378 smu_data
->smu7_data
.arb_table_start
= tmp
;
2380 error
|= (0 != result
);
2382 result
= smu7_read_smc_sram_dword(hwmgr
,
2383 SMU7_FIRMWARE_HEADER_LOCATION
+
2384 offsetof(SMU74_Firmware_Header
, Version
),
2388 hwmgr
->microcode_version_info
.SMC
= tmp
;
2390 error
|= (0 != result
);
2392 return error
? -1 : 0;
2395 static bool polaris10_is_dpm_running(struct pp_hwmgr
*hwmgr
)
2397 return (1 == PHM_READ_INDIRECT_FIELD(hwmgr
->device
,
2398 CGS_IND_REG__SMC
, FEATURE_STATUS
, VOLTAGE_CONTROLLER_ON
))
2402 static int polaris10_update_dpm_settings(struct pp_hwmgr
*hwmgr
,
2403 void *profile_setting
)
2405 struct smu7_hwmgr
*data
= (struct smu7_hwmgr
*)(hwmgr
->backend
);
2406 struct polaris10_smumgr
*smu_data
= (struct polaris10_smumgr
*)
2407 (hwmgr
->smu_backend
);
2408 struct profile_mode_setting
*setting
;
2409 struct SMU74_Discrete_GraphicsLevel
*levels
=
2410 smu_data
->smc_state_table
.GraphicsLevel
;
2411 uint32_t array
= smu_data
->smu7_data
.dpm_table_start
+
2412 offsetof(SMU74_Discrete_DpmTable
, GraphicsLevel
);
2414 uint32_t mclk_array
= smu_data
->smu7_data
.dpm_table_start
+
2415 offsetof(SMU74_Discrete_DpmTable
, MemoryLevel
);
2416 struct SMU74_Discrete_MemoryLevel
*mclk_levels
=
2417 smu_data
->smc_state_table
.MemoryLevel
;
2419 uint32_t offset
, up_hyst_offset
, down_hyst_offset
, clk_activity_offset
, tmp
;
2421 if (profile_setting
== NULL
)
2424 setting
= (struct profile_mode_setting
*)profile_setting
;
2426 if (setting
->bupdate_sclk
) {
2427 if (!data
->sclk_dpm_key_disabled
)
2428 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_SCLKDPM_FreezeLevel
);
2429 for (i
= 0; i
< smu_data
->smc_state_table
.GraphicsDpmLevelCount
; i
++) {
2430 if (levels
[i
].ActivityLevel
!=
2431 cpu_to_be16(setting
->sclk_activity
)) {
2432 levels
[i
].ActivityLevel
= cpu_to_be16(setting
->sclk_activity
);
2434 clk_activity_offset
= array
+ (sizeof(SMU74_Discrete_GraphicsLevel
) * i
)
2435 + offsetof(SMU74_Discrete_GraphicsLevel
, ActivityLevel
);
2436 offset
= clk_activity_offset
& ~0x3;
2437 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2438 tmp
= phm_set_field_to_u32(clk_activity_offset
, tmp
, levels
[i
].ActivityLevel
, sizeof(uint16_t));
2439 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2442 if (levels
[i
].UpHyst
!= setting
->sclk_up_hyst
||
2443 levels
[i
].DownHyst
!= setting
->sclk_down_hyst
) {
2444 levels
[i
].UpHyst
= setting
->sclk_up_hyst
;
2445 levels
[i
].DownHyst
= setting
->sclk_down_hyst
;
2446 up_hyst_offset
= array
+ (sizeof(SMU74_Discrete_GraphicsLevel
) * i
)
2447 + offsetof(SMU74_Discrete_GraphicsLevel
, UpHyst
);
2448 down_hyst_offset
= array
+ (sizeof(SMU74_Discrete_GraphicsLevel
) * i
)
2449 + offsetof(SMU74_Discrete_GraphicsLevel
, DownHyst
);
2450 offset
= up_hyst_offset
& ~0x3;
2451 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2452 tmp
= phm_set_field_to_u32(up_hyst_offset
, tmp
, levels
[i
].UpHyst
, sizeof(uint8_t));
2453 tmp
= phm_set_field_to_u32(down_hyst_offset
, tmp
, levels
[i
].DownHyst
, sizeof(uint8_t));
2454 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2457 if (!data
->sclk_dpm_key_disabled
)
2458 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_SCLKDPM_UnfreezeLevel
);
2461 if (setting
->bupdate_mclk
) {
2462 if (!data
->mclk_dpm_key_disabled
)
2463 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_MCLKDPM_FreezeLevel
);
2464 for (i
= 0; i
< smu_data
->smc_state_table
.MemoryDpmLevelCount
; i
++) {
2465 if (mclk_levels
[i
].ActivityLevel
!=
2466 cpu_to_be16(setting
->mclk_activity
)) {
2467 mclk_levels
[i
].ActivityLevel
= cpu_to_be16(setting
->mclk_activity
);
2469 clk_activity_offset
= mclk_array
+ (sizeof(SMU74_Discrete_MemoryLevel
) * i
)
2470 + offsetof(SMU74_Discrete_MemoryLevel
, ActivityLevel
);
2471 offset
= clk_activity_offset
& ~0x3;
2472 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2473 tmp
= phm_set_field_to_u32(clk_activity_offset
, tmp
, mclk_levels
[i
].ActivityLevel
, sizeof(uint16_t));
2474 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2477 if (mclk_levels
[i
].UpHyst
!= setting
->mclk_up_hyst
||
2478 mclk_levels
[i
].DownHyst
!= setting
->mclk_down_hyst
) {
2479 mclk_levels
[i
].UpHyst
= setting
->mclk_up_hyst
;
2480 mclk_levels
[i
].DownHyst
= setting
->mclk_down_hyst
;
2481 up_hyst_offset
= mclk_array
+ (sizeof(SMU74_Discrete_MemoryLevel
) * i
)
2482 + offsetof(SMU74_Discrete_MemoryLevel
, UpHyst
);
2483 down_hyst_offset
= mclk_array
+ (sizeof(SMU74_Discrete_MemoryLevel
) * i
)
2484 + offsetof(SMU74_Discrete_MemoryLevel
, DownHyst
);
2485 offset
= up_hyst_offset
& ~0x3;
2486 tmp
= PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
));
2487 tmp
= phm_set_field_to_u32(up_hyst_offset
, tmp
, mclk_levels
[i
].UpHyst
, sizeof(uint8_t));
2488 tmp
= phm_set_field_to_u32(down_hyst_offset
, tmp
, mclk_levels
[i
].DownHyst
, sizeof(uint8_t));
2489 cgs_write_ind_register(hwmgr
->device
, CGS_IND_REG__SMC
, offset
, PP_HOST_TO_SMC_UL(tmp
));
2492 if (!data
->mclk_dpm_key_disabled
)
2493 smum_send_msg_to_smc(hwmgr
, PPSMC_MSG_MCLKDPM_UnfreezeLevel
);
2498 const struct pp_smumgr_func polaris10_smu_funcs
= {
2499 .smu_init
= polaris10_smu_init
,
2500 .smu_fini
= smu7_smu_fini
,
2501 .start_smu
= polaris10_start_smu
,
2502 .check_fw_load_finish
= smu7_check_fw_load_finish
,
2503 .request_smu_load_fw
= smu7_reload_firmware
,
2504 .request_smu_load_specific_fw
= NULL
,
2505 .send_msg_to_smc
= smu7_send_msg_to_smc
,
2506 .send_msg_to_smc_with_parameter
= smu7_send_msg_to_smc_with_parameter
,
2507 .download_pptable_settings
= NULL
,
2508 .upload_pptable_settings
= NULL
,
2509 .update_smc_table
= polaris10_update_smc_table
,
2510 .get_offsetof
= polaris10_get_offsetof
,
2511 .process_firmware_header
= polaris10_process_firmware_header
,
2512 .init_smc_table
= polaris10_init_smc_table
,
2513 .update_sclk_threshold
= polaris10_update_sclk_threshold
,
2514 .thermal_avfs_enable
= polaris10_thermal_avfs_enable
,
2515 .thermal_setup_fan_table
= polaris10_thermal_setup_fan_table
,
2516 .populate_all_graphic_levels
= polaris10_populate_all_graphic_levels
,
2517 .populate_all_memory_levels
= polaris10_populate_all_memory_levels
,
2518 .get_mac_definition
= polaris10_get_mac_definition
,
2519 .is_dpm_running
= polaris10_is_dpm_running
,
2520 .is_hw_avfs_present
= polaris10_is_hw_avfs_present
,
2521 .update_dpm_settings
= polaris10_update_dpm_settings
,