1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "pp_debug.h"
25#include "smumgr.h"
26#include "smu74.h"
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"
42
43#include "smu7_dyn_defaults.h"
44
45#include "smu7_hwmgr.h"
46#include "hardwaremanager.h"
47#include "atombios.h"
48#include "pppcielanes.h"
49
50#include "dce/dce_10_0_d.h"
51#include "dce/dce_10_0_sh_mask.h"
52
53#define POLARIS10_SMC_SIZE 0x20000
54#define POWERTUNE_DEFAULT_SET_MAX 1
55#define VDDC_VDDCI_DELTA 200
56#define MC_CG_ARB_FREQ_F1 0x0b
57
58static const struct polaris10_pt_defaults polaris10_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = {
59 /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt,
60 * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */
61 { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
62 { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61},
63 { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } },
64};
65
66static const sclkFcwRange_t Range_Table[NUM_SCLK_RANGE] = {
67 {VCO_2_4, POSTDIV_DIV_BY_16, 75, 160, 112},
68 {VCO_3_6, POSTDIV_DIV_BY_16, 112, 224, 160},
69 {VCO_2_4, POSTDIV_DIV_BY_8, 75, 160, 112},
70 {VCO_3_6, POSTDIV_DIV_BY_8, 112, 224, 160},
71 {VCO_2_4, POSTDIV_DIV_BY_4, 75, 160, 112},
72 {VCO_3_6, POSTDIV_DIV_BY_4, 112, 216, 160},
73 {VCO_2_4, POSTDIV_DIV_BY_2, 75, 160, 108},
74 {VCO_3_6, POSTDIV_DIV_BY_2, 112, 216, 160} };
75
76#define PPPOLARIS10_TARGETACTIVITY_DFLT 50
77
78static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = {
79 /* Min pcie DeepSleep Activity CgSpll CgSpll CcPwr CcPwr Sclk Enabled Enabled Voltage Power */
80 /* Voltage, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, DynRm, DynRm1 Did, Padding,ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */
81 { 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 } },
82 { 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 } },
83 { 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 } },
84 { 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 } },
85 { 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 } },
86 { 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 } },
87 { 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 } },
88 { 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 } }
89};
90
91static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = {
92 0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00};
93
94static int polaris10_perform_btc(struct pp_hwmgr *hwmgr)
95{
96 int result = 0;
97 struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend);
98
99 if (0 != smu_data->avfs_btc_param) {
100 if (0 != smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_PerformBtc, smu_data->avfs_btc_param)) {
101 pr_info("[AVFS][SmuPolaris10_PerformBtc] PerformBTC SMU msg failed");
102 result = -1;
103 }
104 }
105 if (smu_data->avfs_btc_param > 1) {
106 /* Soft-Reset to reset the engine before loading uCode */
107 /* halt */
108 cgs_write_register(hwmgr->device, mmCP_MEC_CNTL, 0x50000000);
109 /* reset everything */
110 cgs_write_register(hwmgr->device, mmGRBM_SOFT_RESET, 0xffffffff);
111 cgs_write_register(hwmgr->device, mmGRBM_SOFT_RESET, 0);
112 }
113 return result;
114}
115
116
117static int polaris10_setup_graphics_level_structure(struct pp_hwmgr *hwmgr)
118{
119 uint32_t vr_config;
120 uint32_t dpm_table_start;
121
122 uint16_t u16_boot_mvdd;
123 uint32_t graphics_level_address, vr_config_address, graphics_level_size;
124
125 graphics_level_size = sizeof(avfs_graphics_level_polaris10);
126 u16_boot_mvdd = PP_HOST_TO_SMC_US(1300 * VOLTAGE_SCALE);
127
128 PP_ASSERT_WITH_CODE(0 == smu7_read_smc_sram_dword(hwmgr,
129 SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, DpmTable),
130 &dpm_table_start, 0x40000),
131 "[AVFS][Polaris10_SetupGfxLvlStruct] SMU could not communicate starting address of DPM table",
132 return -1);
133
134 /* Default value for VRConfig = VR_MERGED_WITH_VDDC + VR_STATIC_VOLTAGE(VDDCI) */
135 vr_config = 0x01000500; /* Real value:0x50001 */
136
137 vr_config_address = dpm_table_start + offsetof(SMU74_Discrete_DpmTable, VRConfig);
138
139 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr, vr_config_address,
140 (uint8_t *)&vr_config, sizeof(uint32_t), 0x40000),
141 "[AVFS][Polaris10_SetupGfxLvlStruct] Problems copying VRConfig value over to SMC",
142 return -1);
143
144 graphics_level_address = dpm_table_start + offsetof(SMU74_Discrete_DpmTable, GraphicsLevel);
145
146 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr, graphics_level_address,
147 (uint8_t *)(&avfs_graphics_level_polaris10),
148 graphics_level_size, 0x40000),
149 "[AVFS][Polaris10_SetupGfxLvlStruct] Copying of SCLK DPM table failed!",
150 return -1);
151
152 graphics_level_address = dpm_table_start + offsetof(SMU74_Discrete_DpmTable, MemoryLevel);
153
154 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr, graphics_level_address,
155 (uint8_t *)(&avfs_memory_level_polaris10), sizeof(avfs_memory_level_polaris10), 0x40000),
156 "[AVFS][Polaris10_SetupGfxLvlStruct] Copying of MCLK DPM table failed!",
157 return -1);
158
159 /* MVDD Boot value - neccessary for getting rid of the hang that occurs during Mclk DPM enablement */
160
161 graphics_level_address = dpm_table_start + offsetof(SMU74_Discrete_DpmTable, BootMVdd);
162
163 PP_ASSERT_WITH_CODE(0 == smu7_copy_bytes_to_smc(hwmgr, graphics_level_address,
164 (uint8_t *)(&u16_boot_mvdd), sizeof(u16_boot_mvdd), 0x40000),
165 "[AVFS][Polaris10_SetupGfxLvlStruct] Copying of DPM table failed!",
166 return -1);
167
168 return 0;
169}
170
171
172static int polaris10_avfs_event_mgr(struct pp_hwmgr *hwmgr)
173{
174 struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend);
175
176 if (!hwmgr->avfs_supported)
177 return 0;
178
179 PP_ASSERT_WITH_CODE(0 == polaris10_setup_graphics_level_structure(hwmgr),
180 "[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
181 return -EINVAL);
182
183 if (smu_data->avfs_btc_param > 1) {
184 pr_info("[AVFS][Polaris10_AVFSEventMgr] AC BTC has not been successfully verified on Fiji. There may be in this setting.");
185 PP_ASSERT_WITH_CODE(0 == smu7_setup_pwr_virus(hwmgr),
186 "[AVFS][Polaris10_AVFSEventMgr] Could not setup Pwr Virus for AVFS ",
187 return -EINVAL);
188 }
189
190 PP_ASSERT_WITH_CODE(0 == polaris10_perform_btc(hwmgr),
191 "[AVFS][Polaris10_AVFSEventMgr] Failure at SmuPolaris10_PerformBTC. AVFS Disabled",
192 return -EINVAL);
193
194 return 0;
195}
196
197static int polaris10_start_smu_in_protection_mode(struct pp_hwmgr *hwmgr)
198{
199 int result = 0;
200
201 /* Wait for smc boot up */
202 /* PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0) */
203
204 /* Assert reset */
205 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
206 SMC_SYSCON_RESET_CNTL, rst_reg, 1);
207
208 result = smu7_upload_smu_firmware_image(hwmgr);
209 if (result != 0)
210 return result;
211
212 /* Clear status */
213 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMU_STATUS, 0);
214
215 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
216 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
217
218 /* De-assert reset */
219 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
220 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
221
222
223 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
224
225
226 /* Call Test SMU message with 0x20000 offset to trigger SMU start */
227 smu7_send_msg_to_smc_offset(hwmgr);
228
229 /* Wait done bit to be set */
230 /* Check pass/failed indicator */
231
232 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, SMU_STATUS, SMU_DONE, 0);
233
234 if (1 != PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
235 SMU_STATUS, SMU_PASS))
236 PP_ASSERT_WITH_CODE(false, "SMU Firmware start failed!", return -1);
237
238 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixFIRMWARE_FLAGS, 0);
239
240 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
241 SMC_SYSCON_RESET_CNTL, rst_reg, 1);
242
243 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
244 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
245
246 /* Wait for firmware to initialize */
247 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
248
249 return result;
250}
251
252static int polaris10_start_smu_in_non_protection_mode(struct pp_hwmgr *hwmgr)
253{
254 int result = 0;
255
256 /* wait for smc boot up */
257 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0);
258
259 /* Clear firmware interrupt enable flag */
260 /* PHM_WRITE_VFPF_INDIRECT_FIELD(pSmuMgr, SMC_IND, SMC_SYSCON_MISC_CNTL, pre_fetcher_en, 1); */
261 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
262 ixFIRMWARE_FLAGS, 0);
263
264 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
265 SMC_SYSCON_RESET_CNTL,
266 rst_reg, 1);
267
268 result = smu7_upload_smu_firmware_image(hwmgr);
269 if (result != 0)
270 return result;
271
272 /* Set smc instruct start point at 0x0 */
273 smu7_program_jump_on_start(hwmgr);
274
275 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
276 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
277
278 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
279 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
280
281 /* Wait for firmware to initialize */
282
283 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
284 FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
285
286 return result;
287}
288
289static int polaris10_start_smu(struct pp_hwmgr *hwmgr)
290{
291 int result = 0;
292 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
293
294 /* Only start SMC if SMC RAM is not running */
295 if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) {
296 smu_data->protected_mode = (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE));
297 smu_data->smu7_data.security_hard_key = (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL));
298
299 /* Check if SMU is running in protected mode */
300 if (smu_data->protected_mode == 0)
301 result = polaris10_start_smu_in_non_protection_mode(hwmgr);
302 else
303 result = polaris10_start_smu_in_protection_mode(hwmgr);
304
305 if (result != 0)
306 PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result);
307
308 polaris10_avfs_event_mgr(hwmgr);
309 }
310
311 /* Setup SoftRegsStart here for register lookup in case DummyBackEnd is used and ProcessFirmwareHeader is not executed */
312 smu7_read_smc_sram_dword(hwmgr, SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, SoftRegisters),
313 &(smu_data->smu7_data.soft_regs_start), 0x40000);
314
315 result = smu7_request_smu_load_fw(hwmgr);
316
317 return result;
318}
319
320static bool polaris10_is_hw_avfs_present(struct pp_hwmgr *hwmgr)
321{
322 uint32_t efuse;
323
324 efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMU_EFUSE_0 + (49*4));
325 efuse &= 0x00000001;
326 if (efuse)
327 return true;
328
329 return false;
330}
331
332static int polaris10_smu_init(struct pp_hwmgr *hwmgr)
333{
334 struct polaris10_smumgr *smu_data;
335
336 smu_data = kzalloc(sizeof(struct polaris10_smumgr), GFP_KERNEL);
337 if (smu_data == NULL)
338 return -ENOMEM;
339
340 hwmgr->smu_backend = smu_data;
341
342 if (smu7_init(hwmgr)) {
343 kfree(smu_data);
344 return -EINVAL;
345 }
346
347 return 0;
348}
349
350static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr,
351 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table,
352 uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd)
353{
354 uint32_t i;
355 uint16_t vddci;
356 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
357
358 *voltage = *mvdd = 0;
359
360 /* clock - voltage dependency table is empty table */
361 if (dep_table->count == 0)
362 return -EINVAL;
363
364 for (i = 0; i < dep_table->count; i++) {
365 /* find first sclk bigger than request */
366 if (dep_table->entries[i].clk >= clock) {
367 *voltage |= (dep_table->entries[i].vddc *
368 VOLTAGE_SCALE) << VDDC_SHIFT;
369 if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control)
370 *voltage |= (data->vbios_boot_state.vddci_bootup_value *
371 VOLTAGE_SCALE) << VDDCI_SHIFT;
372 else if (dep_table->entries[i].vddci)
373 *voltage |= (dep_table->entries[i].vddci *
374 VOLTAGE_SCALE) << VDDCI_SHIFT;
375 else {
376 vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
377 (dep_table->entries[i].vddc -
378 (uint16_t)VDDC_VDDCI_DELTA));
379 *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
380 }
381
382 if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control)
383 *mvdd = data->vbios_boot_state.mvdd_bootup_value *
384 VOLTAGE_SCALE;
385 else if (dep_table->entries[i].mvdd)
386 *mvdd = (uint32_t) dep_table->entries[i].mvdd *
387 VOLTAGE_SCALE;
388
389 *voltage |= 1 << PHASES_SHIFT;
390 return 0;
391 }
392 }
393
394 /* sclk is bigger than max sclk in the dependence table */
395 *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
396
397 if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control)
398 *voltage |= (data->vbios_boot_state.vddci_bootup_value *
399 VOLTAGE_SCALE) << VDDCI_SHIFT;
400 else if (dep_table->entries[i-1].vddci) {
401 vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
402 (dep_table->entries[i].vddc -
403 (uint16_t)VDDC_VDDCI_DELTA));
404 *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
405 }
406
407 if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control)
408 *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE;
409 else if (dep_table->entries[i].mvdd)
410 *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE;
411
412 return 0;
413}
414
415static uint16_t scale_fan_gain_settings(uint16_t raw_setting)
416{
417 uint32_t tmp;
418 tmp = raw_setting * 4096 / 100;
419 return (uint16_t)tmp;
420}
421
422static int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr)
423{
424 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
425
426 const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults;
427 SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table);
428 struct phm_ppt_v1_information *table_info =
429 (struct phm_ppt_v1_information *)(hwmgr->pptable);
430 struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table;
431 struct pp_advance_fan_control_parameters *fan_table =
432 &hwmgr->thermal_controller.advanceFanControlParameters;
433 int i, j, k;
434 const uint16_t *pdef1;
435 const uint16_t *pdef2;
436
437 table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128));
438 table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128));
439
440 PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255,
441 "Target Operating Temp is out of Range!",
442 );
443
444 table->TemperatureLimitEdge = PP_HOST_TO_SMC_US(
445 cac_dtp_table->usTargetOperatingTemp * 256);
446 table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US(
447 cac_dtp_table->usTemperatureLimitHotspot * 256);
448 table->FanGainEdge = PP_HOST_TO_SMC_US(
449 scale_fan_gain_settings(fan_table->usFanGainEdge));
450 table->FanGainHotspot = PP_HOST_TO_SMC_US(
451 scale_fan_gain_settings(fan_table->usFanGainHotspot));
452
453 pdef1 = defaults->BAPMTI_R;
454 pdef2 = defaults->BAPMTI_RC;
455
456 for (i = 0; i < SMU74_DTE_ITERATIONS; i++) {
457 for (j = 0; j < SMU74_DTE_SOURCES; j++) {
458 for (k = 0; k < SMU74_DTE_SINKS; k++) {
459 table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1);
460 table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2);
461 pdef1++;
462 pdef2++;
463 }
464 }
465 }
466
467 return 0;
468}
469
470static int polaris10_populate_svi_load_line(struct pp_hwmgr *hwmgr)
471{
472 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
473 const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults;
474
475 smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn;
476 smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC;
477 smu_data->power_tune_table.SviLoadLineTrimVddC = 3;
478 smu_data->power_tune_table.SviLoadLineOffsetVddC = 0;
479
480 return 0;
481}
482
483static int polaris10_populate_tdc_limit(struct pp_hwmgr *hwmgr)
484{
485 uint16_t tdc_limit;
486 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
487 struct phm_ppt_v1_information *table_info =
488 (struct phm_ppt_v1_information *)(hwmgr->pptable);
489 const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults;
490
491 tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128);
492 smu_data->power_tune_table.TDC_VDDC_PkgLimit =
493 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit);
494 smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc =
495 defaults->TDC_VDDC_ThrottleReleaseLimitPerc;
496 smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt;
497
498 return 0;
499}
500
501static int polaris10_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset)
502{
503 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
504 const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults;
505 uint32_t temp;
506
507 if (smu7_read_smc_sram_dword(hwmgr,
508 fuse_table_offset +
509 offsetof(SMU74_Discrete_PmFuses, TdcWaterfallCtl),
510 (uint32_t *)&temp, SMC_RAM_END))
511 PP_ASSERT_WITH_CODE(false,
512 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
513 return -EINVAL);
514 else {
515 smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl;
516 smu_data->power_tune_table.LPMLTemperatureMin =
517 (uint8_t)((temp >> 16) & 0xff);
518 smu_data->power_tune_table.LPMLTemperatureMax =
519 (uint8_t)((temp >> 8) & 0xff);
520 smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff);
521 }
522 return 0;
523}
524
525static int polaris10_populate_temperature_scaler(struct pp_hwmgr *hwmgr)
526{
527 int i;
528 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
529
530 /* Currently not used. Set all to zero. */
531 for (i = 0; i < 16; i++)
532 smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0;
533
534 return 0;
535}
536
537static int polaris10_populate_fuzzy_fan(struct pp_hwmgr *hwmgr)
538{
539 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
540
541/* TO DO move to hwmgr */
542 if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15))
543 || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity)
544 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
545 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity;
546
547 smu_data->power_tune_table.FuzzyFan_PwmSetDelta = PP_HOST_TO_SMC_US(
548 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity);
549 return 0;
550}
551
552static int polaris10_populate_gnb_lpml(struct pp_hwmgr *hwmgr)
553{
554 int i;
555 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
556
557 /* Currently not used. Set all to zero. */
558 for (i = 0; i < 16; i++)
559 smu_data->power_tune_table.GnbLPML[i] = 0;
560
561 return 0;
562}
563
564static int polaris10_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
565{
566 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
567 struct phm_ppt_v1_information *table_info =
568 (struct phm_ppt_v1_information *)(hwmgr->pptable);
569 uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd;
570 uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd;
571 struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
572
573 hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
574 lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256);
575
576 smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd =
577 CONVERT_FROM_HOST_TO_SMC_US(hi_sidd);
578 smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd =
579 CONVERT_FROM_HOST_TO_SMC_US(lo_sidd);
580
581 return 0;
582}
583
584static int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr)
585{
586 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
587 uint32_t pm_fuse_table_offset;
588
589 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
590 PHM_PlatformCaps_PowerContainment)) {
591 if (smu7_read_smc_sram_dword(hwmgr,
592 SMU7_FIRMWARE_HEADER_LOCATION +
593 offsetof(SMU74_Firmware_Header, PmFuseTable),
594 &pm_fuse_table_offset, SMC_RAM_END))
595 PP_ASSERT_WITH_CODE(false,
596 "Attempt to get pm_fuse_table_offset Failed!",
597 return -EINVAL);
598
599 if (polaris10_populate_svi_load_line(hwmgr))
600 PP_ASSERT_WITH_CODE(false,
601 "Attempt to populate SviLoadLine Failed!",
602 return -EINVAL);
603
604 if (polaris10_populate_tdc_limit(hwmgr))
605 PP_ASSERT_WITH_CODE(false,
606 "Attempt to populate TDCLimit Failed!", return -EINVAL);
607
608 if (polaris10_populate_dw8(hwmgr, pm_fuse_table_offset))
609 PP_ASSERT_WITH_CODE(false,
610 "Attempt to populate TdcWaterfallCtl, "
611 "LPMLTemperature Min and Max Failed!",
612 return -EINVAL);
613
614 if (0 != polaris10_populate_temperature_scaler(hwmgr))
615 PP_ASSERT_WITH_CODE(false,
616 "Attempt to populate LPMLTemperatureScaler Failed!",
617 return -EINVAL);
618
619 if (polaris10_populate_fuzzy_fan(hwmgr))
620 PP_ASSERT_WITH_CODE(false,
621 "Attempt to populate Fuzzy Fan Control parameters Failed!",
622 return -EINVAL);
623
624 if (polaris10_populate_gnb_lpml(hwmgr))
625 PP_ASSERT_WITH_CODE(false,
626 "Attempt to populate GnbLPML Failed!",
627 return -EINVAL);
628
629 if (polaris10_populate_bapm_vddc_base_leakage_sidd(hwmgr))
630 PP_ASSERT_WITH_CODE(false,
631 "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
632 "Sidd Failed!", return -EINVAL);
633
634 if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset,
635 (uint8_t *)&smu_data->power_tune_table,
636 (sizeof(struct SMU74_Discrete_PmFuses) - 92), SMC_RAM_END))
637 PP_ASSERT_WITH_CODE(false,
638 "Attempt to download PmFuseTable Failed!",
639 return -EINVAL);
640 }
641 return 0;
642}
643
644static int polaris10_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
645 SMU74_Discrete_DpmTable *table)
646{
647 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
648 uint32_t count, level;
649
650 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
651 count = data->mvdd_voltage_table.count;
652 if (count > SMU_MAX_SMIO_LEVELS)
653 count = SMU_MAX_SMIO_LEVELS;
654 for (level = 0; level < count; level++) {
655 table->SmioTable2.Pattern[level].Voltage =
656 PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE);
657 /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/
658 table->SmioTable2.Pattern[level].Smio =
659 (uint8_t) level;
660 table->Smio[level] |=
661 data->mvdd_voltage_table.entries[level].smio_low;
662 }
663 table->SmioMask2 = data->mvdd_voltage_table.mask_low;
664
665 table->MvddLevelCount = (uint32_t) PP_HOST_TO_SMC_UL(count);
666 }
667
668 return 0;
669}
670
671static int polaris10_populate_smc_vddci_table(struct pp_hwmgr *hwmgr,
672 struct SMU74_Discrete_DpmTable *table)
673{
674 uint32_t count, level;
675 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
676
677 count = data->vddci_voltage_table.count;
678
679 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) {
680 if (count > SMU_MAX_SMIO_LEVELS)
681 count = SMU_MAX_SMIO_LEVELS;
682 for (level = 0; level < count; ++level) {
683 table->SmioTable1.Pattern[level].Voltage =
684 PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[level].value * VOLTAGE_SCALE);
685 table->SmioTable1.Pattern[level].Smio = (uint8_t) level;
686
687 table->Smio[level] |= data->vddci_voltage_table.entries[level].smio_low;
688 }
689 }
690
691 table->SmioMask1 = data->vddci_voltage_table.mask_low;
692
693 return 0;
694}
695
696static int polaris10_populate_cac_table(struct pp_hwmgr *hwmgr,
697 struct SMU74_Discrete_DpmTable *table)
698{
699 uint32_t count;
700 uint8_t index;
701 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
702 struct phm_ppt_v1_information *table_info =
703 (struct phm_ppt_v1_information *)(hwmgr->pptable);
704 struct phm_ppt_v1_voltage_lookup_table *lookup_table =
705 table_info->vddc_lookup_table;
706 /* tables is already swapped, so in order to use the value from it,
707 * we need to swap it back.
708 * We are populating vddc CAC data to BapmVddc table
709 * in split and merged mode
710 */
711 for (count = 0; count < lookup_table->count; count++) {
712 index = phm_get_voltage_index(lookup_table,
713 data->vddc_voltage_table.entries[count].value);
714 table->BapmVddcVidLoSidd[count] = convert_to_vid(lookup_table->entries[index].us_cac_low);
715 table->BapmVddcVidHiSidd[count] = convert_to_vid(lookup_table->entries[index].us_cac_mid);
716 table->BapmVddcVidHiSidd2[count] = convert_to_vid(lookup_table->entries[index].us_cac_high);
717 }
718
719 return 0;
720}
721
722static int polaris10_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr,
723 struct SMU74_Discrete_DpmTable *table)
724{
725 polaris10_populate_smc_vddci_table(hwmgr, table);
726 polaris10_populate_smc_mvdd_table(hwmgr, table);
727 polaris10_populate_cac_table(hwmgr, table);
728
729 return 0;
730}
731
732static int polaris10_populate_ulv_level(struct pp_hwmgr *hwmgr,
733 struct SMU74_Discrete_Ulv *state)
734{
735 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
736 struct phm_ppt_v1_information *table_info =
737 (struct phm_ppt_v1_information *)(hwmgr->pptable);
738
739 state->CcPwrDynRm = 0;
740 state->CcPwrDynRm1 = 0;
741
742 state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset;
743 state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset *
744 VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1);
745
746 if (hwmgr->chip_id == CHIP_POLARIS12 || hwmgr->is_kicker)
747 state->VddcPhase = data->vddc_phase_shed_control ^ 0x3;
748 else
749 state->VddcPhase = (data->vddc_phase_shed_control) ? 0 : 1;
750
751 CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm);
752 CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1);
753 CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset);
754
755 return 0;
756}
757
758static int polaris10_populate_ulv_state(struct pp_hwmgr *hwmgr,
759 struct SMU74_Discrete_DpmTable *table)
760{
761 return polaris10_populate_ulv_level(hwmgr, &table->Ulv);
762}
763
764static int polaris10_populate_smc_link_level(struct pp_hwmgr *hwmgr,
765 struct SMU74_Discrete_DpmTable *table)
766{
767 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
768 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
769 struct smu7_dpm_table *dpm_table = &data->dpm_table;
770 int i;
771
772 /* Index (dpm_table->pcie_speed_table.count)
773 * is reserved for PCIE boot level. */
774 for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) {
775 table->LinkLevel[i].PcieGenSpeed =
776 (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value;
777 table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width(
778 dpm_table->pcie_speed_table.dpm_levels[i].param1);
779 table->LinkLevel[i].EnabledForActivity = 1;
780 table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff);
781 table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5);
782 table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30);
783 }
784
785 smu_data->smc_state_table.LinkLevelCount =
786 (uint8_t)dpm_table->pcie_speed_table.count;
787
788/* To Do move to hwmgr */
789 data->dpm_level_enable_mask.pcie_dpm_enable_mask =
790 phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table);
791
792 return 0;
793}
794
795
796static void polaris10_get_sclk_range_table(struct pp_hwmgr *hwmgr,
797 SMU74_Discrete_DpmTable *table)
798{
799 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
800 uint32_t i, ref_clk;
801
802 struct pp_atom_ctrl_sclk_range_table range_table_from_vbios = { { {0} } };
803
804 ref_clk = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
805
806 if (0 == atomctrl_get_smc_sclk_range_table(hwmgr, &range_table_from_vbios)) {
807 for (i = 0; i < NUM_SCLK_RANGE; i++) {
808 table->SclkFcwRangeTable[i].vco_setting = range_table_from_vbios.entry[i].ucVco_setting;
809 table->SclkFcwRangeTable[i].postdiv = range_table_from_vbios.entry[i].ucPostdiv;
810 table->SclkFcwRangeTable[i].fcw_pcc = range_table_from_vbios.entry[i].usFcw_pcc;
811
812 table->SclkFcwRangeTable[i].fcw_trans_upper = range_table_from_vbios.entry[i].usFcw_trans_upper;
813 table->SclkFcwRangeTable[i].fcw_trans_lower = range_table_from_vbios.entry[i].usRcw_trans_lower;
814
815 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc);
816 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper);
817 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower);
818 }
819 return;
820 }
821
822 for (i = 0; i < NUM_SCLK_RANGE; i++) {
823 smu_data->range_table[i].trans_lower_frequency = (ref_clk * Range_Table[i].fcw_trans_lower) >> Range_Table[i].postdiv;
824 smu_data->range_table[i].trans_upper_frequency = (ref_clk * Range_Table[i].fcw_trans_upper) >> Range_Table[i].postdiv;
825
826 table->SclkFcwRangeTable[i].vco_setting = Range_Table[i].vco_setting;
827 table->SclkFcwRangeTable[i].postdiv = Range_Table[i].postdiv;
828 table->SclkFcwRangeTable[i].fcw_pcc = Range_Table[i].fcw_pcc;
829
830 table->SclkFcwRangeTable[i].fcw_trans_upper = Range_Table[i].fcw_trans_upper;
831 table->SclkFcwRangeTable[i].fcw_trans_lower = Range_Table[i].fcw_trans_lower;
832
833 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc);
834 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper);
835 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower);
836 }
837}
838
839static int polaris10_calculate_sclk_params(struct pp_hwmgr *hwmgr,
840 uint32_t clock, SMU_SclkSetting *sclk_setting)
841{
842 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
843 const SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table);
844 struct pp_atomctrl_clock_dividers_ai dividers;
845 uint32_t ref_clock;
846 uint32_t pcc_target_percent, pcc_target_freq, ss_target_percent, ss_target_freq;
847 uint8_t i;
848 int result;
849 uint64_t temp;
850
851 sclk_setting->SclkFrequency = clock;
852 /* get the engine clock dividers for this clock value */
853 result = atomctrl_get_engine_pll_dividers_ai(hwmgr, clock, &dividers);
854 if (result == 0) {
855 sclk_setting->Fcw_int = dividers.usSclk_fcw_int;
856 sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac;
857 sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int;
858 sclk_setting->PllRange = dividers.ucSclkPllRange;
859 sclk_setting->Sclk_slew_rate = 0x400;
860 sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac;
861 sclk_setting->Pcc_down_slew_rate = 0xffff;
862 sclk_setting->SSc_En = dividers.ucSscEnable;
863 sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int;
864 sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac;
865 sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac;
866 return result;
867 }
868
869 ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
870
871 for (i = 0; i < NUM_SCLK_RANGE; i++) {
872 if (clock > smu_data->range_table[i].trans_lower_frequency
873 && clock <= smu_data->range_table[i].trans_upper_frequency) {
874 sclk_setting->PllRange = i;
875 break;
876 }
877 }
878
879 sclk_setting->Fcw_int = (uint16_t)((clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock);
880 temp = clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv;
881 temp <<= 0x10;
882 do_div(temp, ref_clock);
883 sclk_setting->Fcw_frac = temp & 0xffff;
884
885 pcc_target_percent = 10; /* Hardcode 10% for now. */
886 pcc_target_freq = clock - (clock * pcc_target_percent / 100);
887 sclk_setting->Pcc_fcw_int = (uint16_t)((pcc_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock);
888
889 ss_target_percent = 2; /* Hardcode 2% for now. */
890 sclk_setting->SSc_En = 0;
891 if (ss_target_percent) {
892 sclk_setting->SSc_En = 1;
893 ss_target_freq = clock - (clock * ss_target_percent / 100);
894 sclk_setting->Fcw1_int = (uint16_t)((ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock);
895 temp = ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv;
896 temp <<= 0x10;
897 do_div(temp, ref_clock);
898 sclk_setting->Fcw1_frac = temp & 0xffff;
899 }
900
901 return 0;
902}
903
904static int polaris10_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
905 uint32_t clock, struct SMU74_Discrete_GraphicsLevel *level)
906{
907 int result;
908 /* PP_Clocks minClocks; */
909 uint32_t mvdd;
910 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
911 struct phm_ppt_v1_information *table_info =
912 (struct phm_ppt_v1_information *)(hwmgr->pptable);
913 SMU_SclkSetting curr_sclk_setting = { 0 };
914 phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table = NULL;
915
916 result = polaris10_calculate_sclk_params(hwmgr, clock, &curr_sclk_setting);
917
918 if (hwmgr->od_enabled)
919 vdd_dep_table = (phm_ppt_v1_clock_voltage_dependency_table *)&data->odn_dpm_table.vdd_dependency_on_sclk;
920 else
921 vdd_dep_table = table_info->vdd_dep_on_sclk;
922
923 /* populate graphics levels */
924 result = polaris10_get_dependency_volt_by_clk(hwmgr,
925 vdd_dep_table, clock,
926 &level->MinVoltage, &mvdd);
927
928 PP_ASSERT_WITH_CODE((0 == result),
929 "can not find VDDC voltage value for "
930 "VDDC engine clock dependency table",
931 return result);
932 level->ActivityLevel = data->current_profile_setting.sclk_activity;
933
934 level->CcPwrDynRm = 0;
935 level->CcPwrDynRm1 = 0;
936 level->EnabledForActivity = 0;
937 level->EnabledForThrottle = 1;
938 level->UpHyst = data->current_profile_setting.sclk_up_hyst;
939 level->DownHyst = data->current_profile_setting.sclk_down_hyst;
940 level->VoltageDownHyst = 0;
941 level->PowerThrottle = 0;
942 data->display_timing.min_clock_in_sr = hwmgr->display_config->min_core_set_clock_in_sr;
943
944 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
945 level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock,
946 hwmgr->display_config->min_core_set_clock_in_sr);
947
948 /* Default to slow, highest DPM level will be
949 * set to PPSMC_DISPLAY_WATERMARK_LOW later.
950 */
951 if (data->update_up_hyst)
952 level->UpHyst = (uint8_t)data->up_hyst;
953 if (data->update_down_hyst)
954 level->DownHyst = (uint8_t)data->down_hyst;
955
956 level->SclkSetting = curr_sclk_setting;
957
958 CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage);
959 CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm);
960 CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1);
961 CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel);
962 CONVERT_FROM_HOST_TO_SMC_UL(level->SclkSetting.SclkFrequency);
963 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int);
964 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac);
965 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int);
966 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate);
967 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate);
968 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate);
969 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int);
970 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac);
971 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate);
972 return 0;
973}
974
975static int polaris10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
976{
977 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
978 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
979 struct smu7_dpm_table *dpm_table = &hw_data->dpm_table;
980 struct phm_ppt_v1_information *table_info =
981 (struct phm_ppt_v1_information *)(hwmgr->pptable);
982 struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
983 uint8_t pcie_entry_cnt = (uint8_t) hw_data->dpm_table.pcie_speed_table.count;
984 int result = 0;
985 uint32_t array = smu_data->smu7_data.dpm_table_start +
986 offsetof(SMU74_Discrete_DpmTable, GraphicsLevel);
987 uint32_t array_size = sizeof(struct SMU74_Discrete_GraphicsLevel) *
988 SMU74_MAX_LEVELS_GRAPHICS;
989 struct SMU74_Discrete_GraphicsLevel *levels =
990 smu_data->smc_state_table.GraphicsLevel;
991 uint32_t i, max_entry;
992 uint8_t hightest_pcie_level_enabled = 0,
993 lowest_pcie_level_enabled = 0,
994 mid_pcie_level_enabled = 0,
995 count = 0;
996
997 polaris10_get_sclk_range_table(hwmgr, &(smu_data->smc_state_table));
998
999 for (i = 0; i < dpm_table->sclk_table.count; i++) {
1000
1001 result = polaris10_populate_single_graphic_level(hwmgr,
1002 dpm_table->sclk_table.dpm_levels[i].value,
1003 &(smu_data->smc_state_table.GraphicsLevel[i]));
1004 if (result)
1005 return result;
1006
1007 /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
1008 if (i > 1)
1009 levels[i].DeepSleepDivId = 0;
1010 }
1011 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1012 PHM_PlatformCaps_SPLLShutdownSupport))
1013 smu_data->smc_state_table.GraphicsLevel[0].SclkSetting.SSc_En = 0;
1014
1015 smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1;
1016 smu_data->smc_state_table.GraphicsDpmLevelCount =
1017 (uint8_t)dpm_table->sclk_table.count;
1018 hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask =
1019 phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
1020
1021
1022 if (pcie_table != NULL) {
1023 PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt),
1024 "There must be 1 or more PCIE levels defined in PPTable.",
1025 return -EINVAL);
1026 max_entry = pcie_entry_cnt - 1;
1027 for (i = 0; i < dpm_table->sclk_table.count; i++)
1028 levels[i].pcieDpmLevel =
1029 (uint8_t) ((i < max_entry) ? i : max_entry);
1030 } else {
1031 while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
1032 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
1033 (1 << (hightest_pcie_level_enabled + 1))) != 0))
1034 hightest_pcie_level_enabled++;
1035
1036 while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
1037 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
1038 (1 << lowest_pcie_level_enabled)) == 0))
1039 lowest_pcie_level_enabled++;
1040
1041 while ((count < hightest_pcie_level_enabled) &&
1042 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
1043 (1 << (lowest_pcie_level_enabled + 1 + count))) == 0))
1044 count++;
1045
1046 mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) <
1047 hightest_pcie_level_enabled ?
1048 (lowest_pcie_level_enabled + 1 + count) :
1049 hightest_pcie_level_enabled;
1050
1051 /* set pcieDpmLevel to hightest_pcie_level_enabled */
1052 for (i = 2; i < dpm_table->sclk_table.count; i++)
1053 levels[i].pcieDpmLevel = hightest_pcie_level_enabled;
1054
1055 /* set pcieDpmLevel to lowest_pcie_level_enabled */
1056 levels[0].pcieDpmLevel = lowest_pcie_level_enabled;
1057
1058 /* set pcieDpmLevel to mid_pcie_level_enabled */
1059 levels[1].pcieDpmLevel = mid_pcie_level_enabled;
1060 }
1061 /* level count will send to smc once at init smc table and never change */
1062 result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels,
1063 (uint32_t)array_size, SMC_RAM_END);
1064
1065 return result;
1066}
1067
1068
1069static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
1070 uint32_t clock, struct SMU74_Discrete_MemoryLevel *mem_level)
1071{
1072 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1073 struct phm_ppt_v1_information *table_info =
1074 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1075 int result = 0;
1076 uint32_t mclk_stutter_mode_threshold = 40000;
1077 phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table = NULL;
1078
1079
1080 if (hwmgr->od_enabled)
1081 vdd_dep_table = (phm_ppt_v1_clock_voltage_dependency_table *)&data->odn_dpm_table.vdd_dependency_on_mclk;
1082 else
1083 vdd_dep_table = table_info->vdd_dep_on_mclk;
1084
1085 if (vdd_dep_table) {
1086 result = polaris10_get_dependency_volt_by_clk(hwmgr,
1087 vdd_dep_table, clock,
1088 &mem_level->MinVoltage, &mem_level->MinMvdd);
1089 PP_ASSERT_WITH_CODE((0 == result),
1090 "can not find MinVddc voltage value from memory "
1091 "VDDC voltage dependency table", return result);
1092 }
1093
1094 mem_level->MclkFrequency = clock;
1095 mem_level->EnabledForThrottle = 1;
1096 mem_level->EnabledForActivity = 0;
1097 mem_level->UpHyst = data->current_profile_setting.mclk_up_hyst;
1098 mem_level->DownHyst = data->current_profile_setting.mclk_down_hyst;
1099 mem_level->VoltageDownHyst = 0;
1100 mem_level->ActivityLevel = data->current_profile_setting.mclk_activity;
1101 mem_level->StutterEnable = false;
1102 mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1103
1104 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1105 data->display_timing.vrefresh = hwmgr->display_config->vrefresh;
1106
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;
1112
1113 if (!result) {
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);
1118 }
1119 return result;
1120}
1121
1122static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
1123{
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;
1127 int result;
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;
1135 uint32_t i;
1136
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",
1140 return -EINVAL);
1141 result = polaris10_populate_single_memory_level(hwmgr,
1142 dpm_table->mclk_table.dpm_levels[i].value,
1143 &levels[i]);
1144 if (i == dpm_table->mclk_table.count - 1) {
1145 levels[i].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH;
1146 levels[i].EnabledForActivity = 1;
1147 }
1148 if (result)
1149 return result;
1150 }
1151
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.
1156 */
1157 levels[0].ActivityLevel = 0x1f;
1158 CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel);
1159
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);
1164
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);
1168
1169 return result;
1170}
1171
1172static int polaris10_populate_mvdd_value(struct pp_hwmgr *hwmgr,
1173 uint32_t mclk, SMIO_Pattern *smio_pat)
1174{
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);
1178 uint32_t i = 0;
1179
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;
1185 break;
1186 }
1187 }
1188 PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count,
1189 "MVDD Voltage is outside the supported range.",
1190 return -EINVAL);
1191 } else
1192 return -EINVAL;
1193
1194 return 0;
1195}
1196
1197static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
1198 SMU74_Discrete_DpmTable *table)
1199{
1200 int result = 0;
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;
1206 uint32_t mvdd;
1207
1208 table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
1209
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,
1215 sclk_frequency,
1216 &table->ACPILevel.MinVoltage, &mvdd);
1217 PP_ASSERT_WITH_CODE((0 == result),
1218 "Cannot find ACPI VDDC voltage value "
1219 "in Clock Dependency Table",
1220 );
1221
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);
1224
1225 table->ACPILevel.DeepSleepDivId = 0;
1226 table->ACPILevel.CcPwrDynRm = 0;
1227 table->ACPILevel.CcPwrDynRm1 = 0;
1228
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);
1233
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);
1244
1245
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",
1255 );
1256
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,
1261 &vol_level);
1262
1263 if (0 == polaris10_populate_mvdd_value(hwmgr, 0, &vol_level))
1264 table->MemoryACPILevel.MinMvdd = PP_HOST_TO_SMC_UL(vol_level.Voltage);
1265 else
1266 table->MemoryACPILevel.MinMvdd = 0;
1267
1268 table->MemoryACPILevel.StutterEnable = false;
1269
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);
1277
1278 CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency);
1279 CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);
1280
1281 return result;
1282}
1283
1284static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
1285 SMU74_Discrete_DpmTable *table)
1286{
1287 int result = -EINVAL;
1288 uint8_t count;
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);
1295 uint32_t vddci;
1296
1297 table->VceLevelCount = (uint8_t)(mm_table->count);
1298 table->VceBootLevel = 0;
1299
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;
1305
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;
1311 else
1312 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
1313
1314
1315 table->VceLevel[count].MinVoltage |=
1316 (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
1317 table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
1318
1319 /*retrieve divider value for VBIOS */
1320 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1321 table->VceLevel[count].Frequency, &dividers);
1322 PP_ASSERT_WITH_CODE((0 == result),
1323 "can not find divide id for VCE engine clock",
1324 return result);
1325
1326 table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
1327
1328 CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency);
1329 CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage);
1330 }
1331 return result;
1332}
1333
1334static 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)
1337{
1338 uint32_t dram_timing;
1339 uint32_t dram_timing2;
1340 uint32_t burst_time;
1341 int result;
1342
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);
1347
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);
1351
1352
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;
1356
1357 return 0;
1358}
1359
1360static int polaris10_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
1361{
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;
1365 uint32_t i, j;
1366 int result = 0;
1367
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]);
1374 if (result == 0)
1375 result = atomctrl_set_ac_timing_ai(hwmgr, hw_data->dpm_table.mclk_table.dpm_levels[j].value, j);
1376 if (result != 0)
1377 return result;
1378 }
1379 }
1380
1381 result = smu7_copy_bytes_to_smc(
1382 hwmgr,
1383 smu_data->smu7_data.arb_table_start,
1384 (uint8_t *)&arb_regs,
1385 sizeof(SMU74_Discrete_MCArbDramTimingTable),
1386 SMC_RAM_END);
1387 return result;
1388}
1389
1390static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
1391 struct SMU74_Discrete_DpmTable *table)
1392{
1393 int result = -EINVAL;
1394 uint8_t count;
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);
1401 uint32_t vddci;
1402
1403 table->UvdLevelCount = (uint8_t)(mm_table->count);
1404 table->UvdBootLevel = 0;
1405
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;
1412
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;
1418 else
1419 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
1420
1421 table->UvdLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
1422 table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
1423
1424 /* retrieve divider value for VBIOS */
1425 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1426 table->UvdLevel[count].VclkFrequency, &dividers);
1427 PP_ASSERT_WITH_CODE((0 == result),
1428 "can not find divide id for Vclk clock", return result);
1429
1430 table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider;
1431
1432 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1433 table->UvdLevel[count].DclkFrequency, &dividers);
1434 PP_ASSERT_WITH_CODE((0 == result),
1435 "can not find divide id for Dclk clock", return result);
1436
1437 table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider;
1438
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);
1442 }
1443
1444 return result;
1445}
1446
1447static int polaris10_populate_smc_boot_level(struct pp_hwmgr *hwmgr,
1448 struct SMU74_Discrete_DpmTable *table)
1449{
1450 int result = 0;
1451 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1452
1453 table->GraphicsBootLevel = 0;
1454 table->MemoryBootLevel = 0;
1455
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));
1460
1461 result = phm_find_boot_level(&(data->dpm_table.mclk_table),
1462 data->vbios_boot_state.mclk_bootup_value,
1463 (uint32_t *)&(table->MemoryBootLevel));
1464
1465 table->BootVddc = data->vbios_boot_state.vddc_bootup_value *
1466 VOLTAGE_SCALE;
1467 table->BootVddci = data->vbios_boot_state.vddci_bootup_value *
1468 VOLTAGE_SCALE;
1469 table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value *
1470 VOLTAGE_SCALE;
1471
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);
1475
1476 return 0;
1477}
1478
1479static int polaris10_populate_smc_initailial_state(struct pp_hwmgr *hwmgr)
1480{
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;
1486
1487 count = (uint8_t)(table_info->vdd_dep_on_sclk->count);
1488
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;
1493 break;
1494 }
1495 }
1496
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;
1502 break;
1503 }
1504 }
1505
1506 return 0;
1507}
1508
1509static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
1510{
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);
1513
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;
1519
1520 stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount;
1521
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.
1524 */
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;
1529
1530 if (hwmgr->chip_id == CHIP_POLARIS10) {
1531 if (hwmgr->is_kicker) {
1532 min = 1200;
1533 max = 2500;
1534 } else {
1535 min = 1000;
1536 max = 2300;
1537 }
1538 } else if (hwmgr->chip_id == CHIP_POLARIS11) {
1539 if (hwmgr->is_kicker) {
1540 min = 900;
1541 max = 2100;
1542 } else {
1543 min = 1100;
1544 max = 2100;
1545 }
1546 } else {
1547 min = 1100;
1548 max = 2100;
1549 }
1550
1551 ro = efuse * (max - min) / 255 + min;
1552
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));
1562 } else {
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)));
1567 }
1568
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);
1572
1573 smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
1574 }
1575
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",
1583 return -EINVAL);
1584 }
1585
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);
1589
1590 return 0;
1591}
1592
1593static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr,
1594 struct SMU74_Discrete_DpmTable *table)
1595{
1596 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1597 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
1598 uint16_t config;
1599
1600 config = VR_MERGED_WITH_VDDC;
1601 table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT);
1602
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;
1607 } else {
1608 PP_ASSERT_WITH_CODE(false,
1609 "VDDC should be on SVI2 control in merged mode!",
1610 );
1611 }
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);
1619 } else {
1620 config = VR_STATIC_VOLTAGE;
1621 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
1622 }
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);
1629 } else {
1630 config = VR_STATIC_VOLTAGE;
1631 table->VRConfig |= (config << VRCONF_MVDD_SHIFT);
1632 }
1633
1634 return 0;
1635}
1636
1637
1638static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
1639{
1640 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1641 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
1642 struct amdgpu_device *adev = hwmgr->adev;
1643
1644 SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1645 int result = 0;
1646 struct pp_atom_ctrl__avfs_parameters avfs_params = {0};
1647 AVFS_meanNsigma_t AVFS_meanNsigma = { {0} };
1648 AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} };
1649 uint32_t tmp, i;
1650
1651 struct phm_ppt_v1_information *table_info =
1652 (struct phm_ppt_v1_information *)hwmgr->pptable;
1653 struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
1654 table_info->vdd_dep_on_sclk;
1655
1656
1657 if (!hwmgr->avfs_supported)
1658 return 0;
1659
1660 result = atomctrl_get_avfs_information(hwmgr, &avfs_params);
1661
1662 if (0 == result) {
1663 if (((adev->pdev->device == 0x67ef) &&
1664 ((adev->pdev->revision == 0xe0) ||
1665 (adev->pdev->revision == 0xe5))) ||
1666 ((adev->pdev->device == 0x67ff) &&
1667 ((adev->pdev->revision == 0xcf) ||
1668 (adev->pdev->revision == 0xef) ||
1669 (adev->pdev->revision == 0xff)))) {
1670 avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage = 1;
1671 if ((adev->pdev->device == 0x67ef && adev->pdev->revision == 0xe5) ||
1672 (adev->pdev->device == 0x67ff && adev->pdev->revision == 0xef)) {
1673 if ((avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0 == 0xEA522DD3) &&
1674 (avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1 == 0x5645A) &&
1675 (avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2 == 0x33F9E) &&
1676 (avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1 == 0xFFFFC5CC) &&
1677 (avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2 == 0x1B1A) &&
1678 (avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b == 0xFFFFFCED)) {
1679 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0 = 0xF718F1D4;
1680 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1 = 0x323FD;
1681 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2 = 0x1E455;
1682 avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1 = 0;
1683 avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2 = 0;
1684 avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b = 0x23;
1685 }
1686 }
1687 } else if (hwmgr->chip_id == CHIP_POLARIS12 && !hwmgr->is_kicker) {
1688 avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage = 1;
1689 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0 = 0xF6B024DD;
1690 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1 = 0x3005E;
1691 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2 = 0x18A5F;
1692 avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1 = 0x315;
1693 avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2 = 0xFED1;
1694 avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b = 0x3B;
1695 } else if (((adev->pdev->device == 0x67df) &&
1696 ((adev->pdev->revision == 0xe0) ||
1697 (adev->pdev->revision == 0xe3) ||
1698 (adev->pdev->revision == 0xe4) ||
1699 (adev->pdev->revision == 0xe5) ||
1700 (adev->pdev->revision == 0xe7) ||
1701 (adev->pdev->revision == 0xef))) ||
1702 ((adev->pdev->device == 0x6fdf) &&
1703 ((adev->pdev->revision == 0xef) ||
1704 (adev->pdev->revision == 0xff)))) {
1705 avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage = 1;
1706 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0 = 0xF843B66B;
1707 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1 = 0x59CB5;
1708 avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2 = 0xFFFF287F;
1709 avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1 = 0;
1710 avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2 = 0xFF23;
1711 avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b = 0x58;
1712 }
1713 }
1714
1715 if (0 == result) {
1716 table->BTCGB_VDROOP_TABLE[0].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0);
1717 table->BTCGB_VDROOP_TABLE[0].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1);
1718 table->BTCGB_VDROOP_TABLE[0].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2);
1719 table->BTCGB_VDROOP_TABLE[1].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0);
1720 table->BTCGB_VDROOP_TABLE[1].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1);
1721 table->BTCGB_VDROOP_TABLE[1].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2);
1722 table->AVFSGB_VDROOP_TABLE[0].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1);
1723 table->AVFSGB_VDROOP_TABLE[0].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2);
1724 table->AVFSGB_VDROOP_TABLE[0].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b);
1725 table->AVFSGB_VDROOP_TABLE[0].m1_shift = 24;
1726 table->AVFSGB_VDROOP_TABLE[0].m2_shift = 12;
1727 table->AVFSGB_VDROOP_TABLE[1].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1);
1728 table->AVFSGB_VDROOP_TABLE[1].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2);
1729 table->AVFSGB_VDROOP_TABLE[1].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b);
1730 table->AVFSGB_VDROOP_TABLE[1].m1_shift = 24;
1731 table->AVFSGB_VDROOP_TABLE[1].m2_shift = 12;
1732 table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv);
1733 AVFS_meanNsigma.Aconstant[0] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0);
1734 AVFS_meanNsigma.Aconstant[1] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1);
1735 AVFS_meanNsigma.Aconstant[2] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2);
1736 AVFS_meanNsigma.DC_tol_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma);
1737 AVFS_meanNsigma.Platform_mean = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean);
1738 AVFS_meanNsigma.PSM_Age_CompFactor = PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor);
1739 AVFS_meanNsigma.Platform_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma);
1740
1741 for (i = 0; i < NUM_VFT_COLUMNS; i++) {
1742 AVFS_meanNsigma.Static_Voltage_Offset[i] = (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625);
1743 AVFS_SclkOffset.Sclk_Offset[i] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table->entries[i].sclk_offset) / 100);
1744 }
1745
1746 result = smu7_read_smc_sram_dword(hwmgr,
1747 SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsMeanNSigma),
1748 &tmp, SMC_RAM_END);
1749
1750 smu7_copy_bytes_to_smc(hwmgr,
1751 tmp,
1752 (uint8_t *)&AVFS_meanNsigma,
1753 sizeof(AVFS_meanNsigma_t),
1754 SMC_RAM_END);
1755
1756 result = smu7_read_smc_sram_dword(hwmgr,
1757 SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsSclkOffsetTable),
1758 &tmp, SMC_RAM_END);
1759 smu7_copy_bytes_to_smc(hwmgr,
1760 tmp,
1761 (uint8_t *)&AVFS_SclkOffset,
1762 sizeof(AVFS_Sclk_Offset_t),
1763 SMC_RAM_END);
1764
1765 data->avfs_vdroop_override_setting = (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) |
1766 (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) |
1767 (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) |
1768 (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT);
1769 data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false;
1770 }
1771 return result;
1772}
1773
1774static int polaris10_init_arb_table_index(struct pp_hwmgr *hwmgr)
1775{
1776 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
1777 uint32_t tmp;
1778 int result;
1779
1780 /* This is a read-modify-write on the first byte of the ARB table.
1781 * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure
1782 * is the field 'current'.
1783 * This solution is ugly, but we never write the whole table only
1784 * individual fields in it.
1785 * In reality this field should not be in that structure
1786 * but in a soft register.
1787 */
1788 result = smu7_read_smc_sram_dword(hwmgr,
1789 smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END);
1790
1791 if (result)
1792 return result;
1793
1794 tmp &= 0x00FFFFFF;
1795 tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24;
1796
1797 return smu7_write_smc_sram_dword(hwmgr,
1798 smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END);
1799}
1800
1801static void polaris10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
1802{
1803 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
1804 struct phm_ppt_v1_information *table_info =
1805 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1806
1807 if (table_info &&
1808 table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX &&
1809 table_info->cac_dtp_table->usPowerTuneDataSetID)
1810 smu_data->power_tune_defaults =
1811 &polaris10_power_tune_data_set_array
1812 [table_info->cac_dtp_table->usPowerTuneDataSetID - 1];
1813 else
1814 smu_data->power_tune_defaults = &polaris10_power_tune_data_set_array[0];
1815
1816}
1817
1818static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr)
1819{
1820 int result;
1821 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1822 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
1823
1824 struct phm_ppt_v1_information *table_info =
1825 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1826 struct SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1827 uint8_t i;
1828 struct pp_atomctrl_gpio_pin_assignment gpio_pin;
1829 pp_atomctrl_clock_dividers_vi dividers;
1830
1831 polaris10_initialize_power_tune_defaults(hwmgr);
1832
1833 if (SMU7_VOLTAGE_CONTROL_NONE != hw_data->voltage_control)
1834 polaris10_populate_smc_voltage_tables(hwmgr, table);
1835
1836 table->SystemFlags = 0;
1837 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1838 PHM_PlatformCaps_AutomaticDCTransition))
1839 table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1840
1841 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1842 PHM_PlatformCaps_StepVddc))
1843 table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1844
1845 if (hw_data->is_memory_gddr5)
1846 table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1847
1848 if (hw_data->ulv_supported && table_info->us_ulv_voltage_offset) {
1849 result = polaris10_populate_ulv_state(hwmgr, table);
1850 PP_ASSERT_WITH_CODE(0 == result,
1851 "Failed to initialize ULV state!", return result);
1852 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1853 ixCG_ULV_PARAMETER, SMU7_CGULVPARAMETER_DFLT);
1854 }
1855
1856 result = polaris10_populate_smc_link_level(hwmgr, table);
1857 PP_ASSERT_WITH_CODE(0 == result,
1858 "Failed to initialize Link Level!", return result);
1859
1860 result = polaris10_populate_all_graphic_levels(hwmgr);
1861 PP_ASSERT_WITH_CODE(0 == result,
1862 "Failed to initialize Graphics Level!", return result);
1863
1864 result = polaris10_populate_all_memory_levels(hwmgr);
1865 PP_ASSERT_WITH_CODE(0 == result,
1866 "Failed to initialize Memory Level!", return result);
1867
1868 result = polaris10_populate_smc_acpi_level(hwmgr, table);
1869 PP_ASSERT_WITH_CODE(0 == result,
1870 "Failed to initialize ACPI Level!", return result);
1871
1872 result = polaris10_populate_smc_vce_level(hwmgr, table);
1873 PP_ASSERT_WITH_CODE(0 == result,
1874 "Failed to initialize VCE Level!", return result);
1875
1876 /* Since only the initial state is completely set up at this point
1877 * (the other states are just copies of the boot state) we only
1878 * need to populate the ARB settings for the initial state.
1879 */
1880 result = polaris10_program_memory_timing_parameters(hwmgr);
1881 PP_ASSERT_WITH_CODE(0 == result,
1882 "Failed to Write ARB settings for the initial state.", return result);
1883
1884 result = polaris10_populate_smc_uvd_level(hwmgr, table);
1885 PP_ASSERT_WITH_CODE(0 == result,
1886 "Failed to initialize UVD Level!", return result);
1887
1888 result = polaris10_populate_smc_boot_level(hwmgr, table);
1889 PP_ASSERT_WITH_CODE(0 == result,
1890 "Failed to initialize Boot Level!", return result);
1891
1892 result = polaris10_populate_smc_initailial_state(hwmgr);
1893 PP_ASSERT_WITH_CODE(0 == result,
1894 "Failed to initialize Boot State!", return result);
1895
1896 result = polaris10_populate_bapm_parameters_in_dpm_table(hwmgr);
1897 PP_ASSERT_WITH_CODE(0 == result,
1898 "Failed to populate BAPM Parameters!", return result);
1899
1900 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1901 PHM_PlatformCaps_ClockStretcher)) {
1902 result = polaris10_populate_clock_stretcher_data_table(hwmgr);
1903 PP_ASSERT_WITH_CODE(0 == result,
1904 "Failed to populate Clock Stretcher Data Table!",
1905 return result);
1906 }
1907
1908 result = polaris10_populate_avfs_parameters(hwmgr);
1909 PP_ASSERT_WITH_CODE(0 == result, "Failed to populate AVFS Parameters!", return result;);
1910
1911 table->CurrSclkPllRange = 0xff;
1912 table->GraphicsVoltageChangeEnable = 1;
1913 table->GraphicsThermThrottleEnable = 1;
1914 table->GraphicsInterval = 1;
1915 table->VoltageInterval = 1;
1916 table->ThermalInterval = 1;
1917 table->TemperatureLimitHigh =
1918 table_info->cac_dtp_table->usTargetOperatingTemp *
1919 SMU7_Q88_FORMAT_CONVERSION_UNIT;
1920 table->TemperatureLimitLow =
1921 (table_info->cac_dtp_table->usTargetOperatingTemp - 1) *
1922 SMU7_Q88_FORMAT_CONVERSION_UNIT;
1923 table->MemoryVoltageChangeEnable = 1;
1924 table->MemoryInterval = 1;
1925 table->VoltageResponseTime = 0;
1926 table->PhaseResponseTime = 0;
1927 table->MemoryThermThrottleEnable = 1;
1928 table->PCIeBootLinkLevel = 0;
1929 table->PCIeGenInterval = 1;
1930 table->VRConfig = 0;
1931
1932 result = polaris10_populate_vr_config(hwmgr, table);
1933 PP_ASSERT_WITH_CODE(0 == result,
1934 "Failed to populate VRConfig setting!", return result);
1935 hw_data->vr_config = table->VRConfig;
1936 table->ThermGpio = 17;
1937 table->SclkStepSize = 0x4000;
1938
1939 if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) {
1940 table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift;
1941 } else {
1942 table->VRHotGpio = SMU7_UNUSED_GPIO_PIN;
1943 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
1944 PHM_PlatformCaps_RegulatorHot);
1945 }
1946
1947 if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID,
1948 &gpio_pin)) {
1949 table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift;
1950 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
1951 PHM_PlatformCaps_AutomaticDCTransition);
1952 } else {
1953 table->AcDcGpio = SMU7_UNUSED_GPIO_PIN;
1954 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
1955 PHM_PlatformCaps_AutomaticDCTransition);
1956 }
1957
1958 /* Thermal Output GPIO */
1959 if (atomctrl_get_pp_assign_pin(hwmgr, THERMAL_INT_OUTPUT_GPIO_PINID,
1960 &gpio_pin)) {
1961 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
1962 PHM_PlatformCaps_ThermalOutGPIO);
1963
1964 table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift;
1965
1966 /* For porlarity read GPIOPAD_A with assigned Gpio pin
1967 * since VBIOS will program this register to set 'inactive state',
1968 * driver can then determine 'active state' from this and
1969 * program SMU with correct polarity
1970 */
1971 table->ThermOutPolarity = (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A)
1972 & (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0;
1973 table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY;
1974
1975 /* if required, combine VRHot/PCC with thermal out GPIO */
1976 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_RegulatorHot)
1977 && phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_CombinePCCWithThermalSignal))
1978 table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT;
1979 } else {
1980 table->ThermOutGpio = 17;
1981 table->ThermOutPolarity = 1;
1982 table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE;
1983 }
1984
1985 /* Populate BIF_SCLK levels into SMC DPM table */
1986 for (i = 0; i <= hw_data->dpm_table.pcie_speed_table.count; i++) {
1987 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, smu_data->bif_sclk_table[i], &dividers);
1988 PP_ASSERT_WITH_CODE((result == 0), "Can not find DFS divide id for Sclk", return result);
1989
1990 if (i == 0)
1991 table->Ulv.BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider));
1992 else
1993 table->LinkLevel[i-1].BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider));
1994 }
1995
1996 for (i = 0; i < SMU74_MAX_ENTRIES_SMIO; i++)
1997 table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]);
1998
1999 CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags);
2000 CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig);
2001 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1);
2002 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2);
2003 CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize);
2004 CONVERT_FROM_HOST_TO_SMC_UL(table->CurrSclkPllRange);
2005 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh);
2006 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow);
2007 CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime);
2008 CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime);
2009
2010 /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
2011 result = smu7_copy_bytes_to_smc(hwmgr,
2012 smu_data->smu7_data.dpm_table_start +
2013 offsetof(SMU74_Discrete_DpmTable, SystemFlags),
2014 (uint8_t *)&(table->SystemFlags),
2015 sizeof(SMU74_Discrete_DpmTable) - 3 * sizeof(SMU74_PIDController),
2016 SMC_RAM_END);
2017 PP_ASSERT_WITH_CODE(0 == result,
2018 "Failed to upload dpm data to SMC memory!", return result);
2019
2020 result = polaris10_init_arb_table_index(hwmgr);
2021 PP_ASSERT_WITH_CODE(0 == result,
2022 "Failed to upload arb data to SMC memory!", return result);
2023
2024 result = polaris10_populate_pm_fuses(hwmgr);
2025 PP_ASSERT_WITH_CODE(0 == result,
2026 "Failed to populate PM fuses to SMC memory!", return result);
2027
2028 return 0;
2029}
2030
2031static int polaris10_program_mem_timing_parameters(struct pp_hwmgr *hwmgr)
2032{
2033 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2034
2035 if (data->need_update_smu7_dpm_table &
2036 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK))
2037 return polaris10_program_memory_timing_parameters(hwmgr);
2038
2039 return 0;
2040}
2041
2042int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
2043{
2044 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2045
2046 if (!hwmgr->avfs_supported)
2047 return 0;
2048
2049 smum_send_msg_to_smc_with_parameter(hwmgr,
2050 PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting);
2051
2052 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs);
2053
2054 /* Apply avfs cks-off voltages to avoid the overshoot
2055 * when switching to the highest sclk frequency
2056 */
2057 if (data->apply_avfs_cks_off_voltage)
2058 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage);
2059
2060 return 0;
2061}
2062
2063static int polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
2064{
2065 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
2066 SMU74_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
2067 uint32_t duty100;
2068 uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2;
2069 uint16_t fdo_min, slope1, slope2;
2070 uint32_t reference_clock;
2071 int res;
2072 uint64_t tmp64;
2073
2074 if (hwmgr->thermal_controller.fanInfo.bNoFan) {
2075 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2076 PHM_PlatformCaps_MicrocodeFanControl);
2077 return 0;
2078 }
2079
2080 if (smu_data->smu7_data.fan_table_start == 0) {
2081 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2082 PHM_PlatformCaps_MicrocodeFanControl);
2083 return 0;
2084 }
2085
2086 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
2087 CG_FDO_CTRL1, FMAX_DUTY100);
2088
2089 if (duty100 == 0) {
2090 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2091 PHM_PlatformCaps_MicrocodeFanControl);
2092 return 0;
2093 }
2094
2095 tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.
2096 usPWMMin * duty100;
2097 do_div(tmp64, 10000);
2098 fdo_min = (uint16_t)tmp64;
2099
2100 t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed -
2101 hwmgr->thermal_controller.advanceFanControlParameters.usTMin;
2102 t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh -
2103 hwmgr->thermal_controller.advanceFanControlParameters.usTMed;
2104
2105 pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed -
2106 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin;
2107 pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh -
2108 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed;
2109
2110 slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
2111 slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
2112
2113 fan_table.TempMin = cpu_to_be16((50 + hwmgr->
2114 thermal_controller.advanceFanControlParameters.usTMin) / 100);
2115 fan_table.TempMed = cpu_to_be16((50 + hwmgr->
2116 thermal_controller.advanceFanControlParameters.usTMed) / 100);
2117 fan_table.TempMax = cpu_to_be16((50 + hwmgr->
2118 thermal_controller.advanceFanControlParameters.usTMax) / 100);
2119
2120 fan_table.Slope1 = cpu_to_be16(slope1);
2121 fan_table.Slope2 = cpu_to_be16(slope2);
2122
2123 fan_table.FdoMin = cpu_to_be16(fdo_min);
2124
2125 fan_table.HystDown = cpu_to_be16(hwmgr->
2126 thermal_controller.advanceFanControlParameters.ucTHyst);
2127
2128 fan_table.HystUp = cpu_to_be16(1);
2129
2130 fan_table.HystSlope = cpu_to_be16(1);
2131
2132 fan_table.TempRespLim = cpu_to_be16(5);
2133
2134 reference_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
2135
2136 fan_table.RefreshPeriod = cpu_to_be32((hwmgr->
2137 thermal_controller.advanceFanControlParameters.ulCycleDelay *
2138 reference_clock) / 1600);
2139
2140 fan_table.FdoMax = cpu_to_be16((uint16_t)duty100);
2141
2142 fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(
2143 hwmgr->device, CGS_IND_REG__SMC,
2144 CG_MULT_THERMAL_CTRL, TEMP_SEL);
2145
2146 res = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.fan_table_start,
2147 (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table),
2148 SMC_RAM_END);
2149
2150 if (!res && hwmgr->thermal_controller.
2151 advanceFanControlParameters.ucMinimumPWMLimit)
2152 res = smum_send_msg_to_smc_with_parameter(hwmgr,
2153 PPSMC_MSG_SetFanMinPwm,
2154 hwmgr->thermal_controller.
2155 advanceFanControlParameters.ucMinimumPWMLimit);
2156
2157 if (!res && hwmgr->thermal_controller.
2158 advanceFanControlParameters.ulMinFanSCLKAcousticLimit)
2159 res = smum_send_msg_to_smc_with_parameter(hwmgr,
2160 PPSMC_MSG_SetFanSclkTarget,
2161 hwmgr->thermal_controller.
2162 advanceFanControlParameters.ulMinFanSCLKAcousticLimit);
2163
2164 if (res)
2165 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2166 PHM_PlatformCaps_MicrocodeFanControl);
2167
2168 return 0;
2169}
2170
2171static int polaris10_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
2172{
2173 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
2174 uint32_t mm_boot_level_offset, mm_boot_level_value;
2175 struct phm_ppt_v1_information *table_info =
2176 (struct phm_ppt_v1_information *)(hwmgr->pptable);
2177
2178 smu_data->smc_state_table.UvdBootLevel = 0;
2179 if (table_info->mm_dep_table->count > 0)
2180 smu_data->smc_state_table.UvdBootLevel =
2181 (uint8_t) (table_info->mm_dep_table->count - 1);
2182 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU74_Discrete_DpmTable,
2183 UvdBootLevel);
2184 mm_boot_level_offset /= 4;
2185 mm_boot_level_offset *= 4;
2186 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
2187 CGS_IND_REG__SMC, mm_boot_level_offset);
2188 mm_boot_level_value &= 0x00FFFFFF;
2189 mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24;
2190 cgs_write_ind_register(hwmgr->device,
2191 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
2192
2193 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2194 PHM_PlatformCaps_UVDDPM) ||
2195 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2196 PHM_PlatformCaps_StablePState))
2197 smum_send_msg_to_smc_with_parameter(hwmgr,
2198 PPSMC_MSG_UVDDPM_SetEnabledMask,
2199 (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel));
2200 return 0;
2201}
2202
2203static int polaris10_update_vce_smc_table(struct pp_hwmgr *hwmgr)
2204{
2205 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
2206 uint32_t mm_boot_level_offset, mm_boot_level_value;
2207 struct phm_ppt_v1_information *table_info =
2208 (struct phm_ppt_v1_information *)(hwmgr->pptable);
2209
2210 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2211 PHM_PlatformCaps_StablePState))
2212 smu_data->smc_state_table.VceBootLevel =
2213 (uint8_t) (table_info->mm_dep_table->count - 1);
2214 else
2215 smu_data->smc_state_table.VceBootLevel = 0;
2216
2217 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start +
2218 offsetof(SMU74_Discrete_DpmTable, VceBootLevel);
2219 mm_boot_level_offset /= 4;
2220 mm_boot_level_offset *= 4;
2221 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
2222 CGS_IND_REG__SMC, mm_boot_level_offset);
2223 mm_boot_level_value &= 0xFF00FFFF;
2224 mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16;
2225 cgs_write_ind_register(hwmgr->device,
2226 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
2227
2228 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
2229 smum_send_msg_to_smc_with_parameter(hwmgr,
2230 PPSMC_MSG_VCEDPM_SetEnabledMask,
2231 (uint32_t)1 << smu_data->smc_state_table.VceBootLevel);
2232 return 0;
2233}
2234
2235static int polaris10_update_bif_smc_table(struct pp_hwmgr *hwmgr)
2236{
2237 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
2238 struct phm_ppt_v1_information *table_info =
2239 (struct phm_ppt_v1_information *)(hwmgr->pptable);
2240 struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
2241 int max_entry, i;
2242
2243 max_entry = (SMU74_MAX_LEVELS_LINK < pcie_table->count) ?
2244 SMU74_MAX_LEVELS_LINK :
2245 pcie_table->count;
2246 /* Setup BIF_SCLK levels */
2247 for (i = 0; i < max_entry; i++)
2248 smu_data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk;
2249 return 0;
2250}
2251
2252static int polaris10_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
2253{
2254 switch (type) {
2255 case SMU_UVD_TABLE:
2256 polaris10_update_uvd_smc_table(hwmgr);
2257 break;
2258 case SMU_VCE_TABLE:
2259 polaris10_update_vce_smc_table(hwmgr);
2260 break;
2261 case SMU_BIF_TABLE:
2262 polaris10_update_bif_smc_table(hwmgr);
2263 default:
2264 break;
2265 }
2266 return 0;
2267}
2268
2269static int polaris10_update_sclk_threshold(struct pp_hwmgr *hwmgr)
2270{
2271 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2272 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
2273
2274 int result = 0;
2275 uint32_t low_sclk_interrupt_threshold = 0;
2276
2277 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2278 PHM_PlatformCaps_SclkThrottleLowNotification)
2279 && (data->low_sclk_interrupt_threshold != 0)) {
2280 low_sclk_interrupt_threshold =
2281 data->low_sclk_interrupt_threshold;
2282
2283 CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold);
2284
2285 result = smu7_copy_bytes_to_smc(
2286 hwmgr,
2287 smu_data->smu7_data.dpm_table_start +
2288 offsetof(SMU74_Discrete_DpmTable,
2289 LowSclkInterruptThreshold),
2290 (uint8_t *)&low_sclk_interrupt_threshold,
2291 sizeof(uint32_t),
2292 SMC_RAM_END);
2293 }
2294 PP_ASSERT_WITH_CODE((result == 0),
2295 "Failed to update SCLK threshold!", return result);
2296
2297 result = polaris10_program_mem_timing_parameters(hwmgr);
2298 PP_ASSERT_WITH_CODE((result == 0),
2299 "Failed to program memory timing parameters!",
2300 );
2301
2302 return result;
2303}
2304
2305static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)
2306{
2307 switch (type) {
2308 case SMU_SoftRegisters:
2309 switch (member) {
2310 case HandshakeDisables:
2311 return offsetof(SMU74_SoftRegisters, HandshakeDisables);
2312 case VoltageChangeTimeout:
2313 return offsetof(SMU74_SoftRegisters, VoltageChangeTimeout);
2314 case AverageGraphicsActivity:
2315 return offsetof(SMU74_SoftRegisters, AverageGraphicsActivity);
2316 case PreVBlankGap:
2317 return offsetof(SMU74_SoftRegisters, PreVBlankGap);
2318 case VBlankTimeout:
2319 return offsetof(SMU74_SoftRegisters, VBlankTimeout);
2320 case UcodeLoadStatus:
2321 return offsetof(SMU74_SoftRegisters, UcodeLoadStatus);
2322 case DRAM_LOG_ADDR_H:
2323 return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_H);
2324 case DRAM_LOG_ADDR_L:
2325 return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_L);
2326 case DRAM_LOG_PHY_ADDR_H:
2327 return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_H);
2328 case DRAM_LOG_PHY_ADDR_L:
2329 return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_L);
2330 case DRAM_LOG_BUFF_SIZE:
2331 return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE);
2332 }
2333 break;
2334 case SMU_Discrete_DpmTable:
2335 switch (member) {
2336 case UvdBootLevel:
2337 return offsetof(SMU74_Discrete_DpmTable, UvdBootLevel);
2338 case VceBootLevel:
2339 return offsetof(SMU74_Discrete_DpmTable, VceBootLevel);
2340 case LowSclkInterruptThreshold:
2341 return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold);
2342 }
2343 break;
2344 }
2345 pr_warn("can't get the offset of type %x member %x\n", type, member);
2346 return 0;
2347}
2348
2349static uint32_t polaris10_get_mac_definition(uint32_t value)
2350{
2351 switch (value) {
2352 case SMU_MAX_LEVELS_GRAPHICS:
2353 return SMU74_MAX_LEVELS_GRAPHICS;
2354 case SMU_MAX_LEVELS_MEMORY:
2355 return SMU74_MAX_LEVELS_MEMORY;
2356 case SMU_MAX_LEVELS_LINK:
2357 return SMU74_MAX_LEVELS_LINK;
2358 case SMU_MAX_ENTRIES_SMIO:
2359 return SMU74_MAX_ENTRIES_SMIO;
2360 case SMU_MAX_LEVELS_VDDC:
2361 return SMU74_MAX_LEVELS_VDDC;
2362 case SMU_MAX_LEVELS_VDDGFX:
2363 return SMU74_MAX_LEVELS_VDDGFX;
2364 case SMU_MAX_LEVELS_VDDCI:
2365 return SMU74_MAX_LEVELS_VDDCI;
2366 case SMU_MAX_LEVELS_MVDD:
2367 return SMU74_MAX_LEVELS_MVDD;
2368 case SMU_UVD_MCLK_HANDSHAKE_DISABLE:
2369 return SMU7_UVD_MCLK_HANDSHAKE_DISABLE;
2370 }
2371
2372 pr_warn("can't get the mac of %x\n", value);
2373 return 0;
2374}
2375
2376static int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr)
2377{
2378 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
2379 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2380 uint32_t tmp;
2381 int result;
2382 bool error = false;
2383
2384 result = smu7_read_smc_sram_dword(hwmgr,
2385 SMU7_FIRMWARE_HEADER_LOCATION +
2386 offsetof(SMU74_Firmware_Header, DpmTable),
2387 &tmp, SMC_RAM_END);
2388
2389 if (0 == result)
2390 smu_data->smu7_data.dpm_table_start = tmp;
2391
2392 error |= (0 != result);
2393
2394 result = smu7_read_smc_sram_dword(hwmgr,
2395 SMU7_FIRMWARE_HEADER_LOCATION +
2396 offsetof(SMU74_Firmware_Header, SoftRegisters),
2397 &tmp, SMC_RAM_END);
2398
2399 if (!result) {
2400 data->soft_regs_start = tmp;
2401 smu_data->smu7_data.soft_regs_start = tmp;
2402 }
2403
2404 error |= (0 != result);
2405
2406 result = smu7_read_smc_sram_dword(hwmgr,
2407 SMU7_FIRMWARE_HEADER_LOCATION +
2408 offsetof(SMU74_Firmware_Header, mcRegisterTable),
2409 &tmp, SMC_RAM_END);
2410
2411 if (!result)
2412 smu_data->smu7_data.mc_reg_table_start = tmp;
2413
2414 result = smu7_read_smc_sram_dword(hwmgr,
2415 SMU7_FIRMWARE_HEADER_LOCATION +
2416 offsetof(SMU74_Firmware_Header, FanTable),
2417 &tmp, SMC_RAM_END);
2418
2419 if (!result)
2420 smu_data->smu7_data.fan_table_start = tmp;
2421
2422 error |= (0 != result);
2423
2424 result = smu7_read_smc_sram_dword(hwmgr,
2425 SMU7_FIRMWARE_HEADER_LOCATION +
2426 offsetof(SMU74_Firmware_Header, mcArbDramTimingTable),
2427 &tmp, SMC_RAM_END);
2428
2429 if (!result)
2430 smu_data->smu7_data.arb_table_start = tmp;
2431
2432 error |= (0 != result);
2433
2434 result = smu7_read_smc_sram_dword(hwmgr,
2435 SMU7_FIRMWARE_HEADER_LOCATION +
2436 offsetof(SMU74_Firmware_Header, Version),
2437 &tmp, SMC_RAM_END);
2438
2439 if (!result)
2440 hwmgr->microcode_version_info.SMC = tmp;
2441
2442 error |= (0 != result);
2443
2444 return error ? -1 : 0;
2445}
2446
2447static bool polaris10_is_dpm_running(struct pp_hwmgr *