diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c | 498 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h | 22 |
5 files changed, 548 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile index c264cb66b020..abbcbc9f6eca 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ | 5 | HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ |
6 | hardwaremanager.o pp_acpi.o cz_hwmgr.o \ | 6 | hardwaremanager.o pp_acpi.o cz_hwmgr.o \ |
7 | cz_clockpowergating.o \ | 7 | cz_clockpowergating.o tonga_powertune.o\ |
8 | tonga_processpptables.o ppatomctrl.o \ | 8 | tonga_processpptables.o ppatomctrl.o \ |
9 | tonga_hwmgr.o pppcielanes.o tonga_thermal.o\ | 9 | tonga_hwmgr.o pppcielanes.o tonga_thermal.o\ |
10 | fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \ | 10 | fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \ |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index c7dc111221c2..e7c281f6dbc7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | |||
@@ -302,6 +302,8 @@ void tonga_initialize_dpm_defaults(struct pp_hwmgr *hwmgr) | |||
302 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 302 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
303 | PHM_PlatformCaps_DisableMemoryTransition); | 303 | PHM_PlatformCaps_DisableMemoryTransition); |
304 | 304 | ||
305 | tonga_initialize_power_tune_defaults(hwmgr); | ||
306 | |||
305 | data->mclk_strobe_mode_threshold = 40000; | 307 | data->mclk_strobe_mode_threshold = 40000; |
306 | data->mclk_stutter_mode_threshold = 30000; | 308 | data->mclk_stutter_mode_threshold = 30000; |
307 | data->mclk_edc_enable_threshold = 40000; | 309 | data->mclk_edc_enable_threshold = 40000; |
@@ -2479,7 +2481,7 @@ static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, uint32_t | |||
2479 | graphic_level->VoltageDownHyst = 0; | 2481 | graphic_level->VoltageDownHyst = 0; |
2480 | graphic_level->PowerThrottle = 0; | 2482 | graphic_level->PowerThrottle = 0; |
2481 | 2483 | ||
2482 | threshold = engine_clock * data->fast_watemark_threshold / 100; | 2484 | threshold = engine_clock * data->fast_watermark_threshold / 100; |
2483 | /* | 2485 | /* |
2484 | *get the DAL clock. do it in funture. | 2486 | *get the DAL clock. do it in funture. |
2485 | PECI_GetMinClockSettings(hwmgr->peci, &minClocks); | 2487 | PECI_GetMinClockSettings(hwmgr->peci, &minClocks); |
@@ -2982,6 +2984,10 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2982 | PP_ASSERT_WITH_CODE(0 == result, | 2984 | PP_ASSERT_WITH_CODE(0 == result, |
2983 | "Failed to initialize Boot Level!", return result;); | 2985 | "Failed to initialize Boot Level!", return result;); |
2984 | 2986 | ||
2987 | result = tonga_populate_bapm_parameters_in_dpm_table(hwmgr); | ||
2988 | PP_ASSERT_WITH_CODE(result == 0, | ||
2989 | "Failed to populate BAPM Parameters!", return result); | ||
2990 | |||
2985 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 2991 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
2986 | PHM_PlatformCaps_ClockStretcher)) { | 2992 | PHM_PlatformCaps_ClockStretcher)) { |
2987 | result = tonga_populate_clock_stretcher_data_table(hwmgr); | 2993 | result = tonga_populate_clock_stretcher_data_table(hwmgr); |
@@ -4370,6 +4376,10 @@ int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
4370 | PP_ASSERT_WITH_CODE((0 == tmp_result), | 4376 | PP_ASSERT_WITH_CODE((0 == tmp_result), |
4371 | "Failed to initialize ARB table index!", result = tmp_result); | 4377 | "Failed to initialize ARB table index!", result = tmp_result); |
4372 | 4378 | ||
4379 | tmp_result = tonga_populate_pm_fuses(hwmgr); | ||
4380 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
4381 | "Failed to populate PM fuses!", result = tmp_result); | ||
4382 | |||
4373 | tmp_result = tonga_populate_initial_mc_reg_table(hwmgr); | 4383 | tmp_result = tonga_populate_initial_mc_reg_table(hwmgr); |
4374 | PP_ASSERT_WITH_CODE((0 == tmp_result), | 4384 | PP_ASSERT_WITH_CODE((0 == tmp_result), |
4375 | "Failed to populate initialize MC Reg table!", result = tmp_result); | 4385 | "Failed to populate initialize MC Reg table!", result = tmp_result); |
@@ -4388,6 +4398,18 @@ int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
4388 | PP_ASSERT_WITH_CODE((0 == tmp_result), | 4398 | PP_ASSERT_WITH_CODE((0 == tmp_result), |
4389 | "Failed to start DPM!", result = tmp_result); | 4399 | "Failed to start DPM!", result = tmp_result); |
4390 | 4400 | ||
4401 | tmp_result = tonga_enable_smc_cac(hwmgr); | ||
4402 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
4403 | "Failed to enable SMC CAC!", result = tmp_result); | ||
4404 | |||
4405 | tmp_result = tonga_enable_power_containment(hwmgr); | ||
4406 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
4407 | "Failed to enable power containment!", result = tmp_result); | ||
4408 | |||
4409 | tmp_result = tonga_power_control_set_level(hwmgr); | ||
4410 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
4411 | "Failed to power control set level!", result = tmp_result); | ||
4412 | |||
4391 | return result; | 4413 | return result; |
4392 | } | 4414 | } |
4393 | 4415 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h index 3961884bfa9b..fcad9426d3c1 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h | |||
@@ -300,6 +300,7 @@ struct tonga_hwmgr { | |||
300 | bool dll_defaule_on; | 300 | bool dll_defaule_on; |
301 | bool performance_request_registered; | 301 | bool performance_request_registered; |
302 | 302 | ||
303 | |||
303 | /* ----------------- Low Power Features ---------------------*/ | 304 | /* ----------------- Low Power Features ---------------------*/ |
304 | phw_tonga_bacos bacos; | 305 | phw_tonga_bacos bacos; |
305 | phw_tonga_ulv_parm ulv; | 306 | phw_tonga_ulv_parm ulv; |
@@ -314,10 +315,14 @@ struct tonga_hwmgr { | |||
314 | bool enable_tdc_limit_feature; | 315 | bool enable_tdc_limit_feature; |
315 | bool enable_pkg_pwr_tracking_feature; | 316 | bool enable_pkg_pwr_tracking_feature; |
316 | bool disable_uvd_power_tune_feature; | 317 | bool disable_uvd_power_tune_feature; |
317 | phw_tonga_pt_defaults *power_tune_defaults; | 318 | struct tonga_pt_defaults *power_tune_defaults; |
318 | SMU72_Discrete_PmFuses power_tune_table; | 319 | SMU72_Discrete_PmFuses power_tune_table; |
319 | uint32_t ul_dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */ | 320 | uint32_t dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */ |
320 | uint32_t fast_watemark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */ | 321 | uint32_t fast_watermark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */ |
322 | |||
323 | |||
324 | bool enable_dte_feature; | ||
325 | |||
321 | 326 | ||
322 | /* ----------------- Phase Shedding ---------------------*/ | 327 | /* ----------------- Phase Shedding ---------------------*/ |
323 | bool vddc_phase_shed_control; | 328 | bool vddc_phase_shed_control; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c new file mode 100644 index 000000000000..9496ade3247e --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c | |||
@@ -0,0 +1,498 @@ | |||
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 "hwmgr.h" | ||
25 | #include "smumgr.h" | ||
26 | #include "tonga_hwmgr.h" | ||
27 | #include "tonga_powertune.h" | ||
28 | #include "tonga_smumgr.h" | ||
29 | #include "smu72_discrete.h" | ||
30 | #include "pp_debug.h" | ||
31 | #include "tonga_ppsmc.h" | ||
32 | |||
33 | #define VOLTAGE_SCALE 4 | ||
34 | #define POWERTUNE_DEFAULT_SET_MAX 1 | ||
35 | |||
36 | struct tonga_pt_defaults tonga_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { | ||
37 | /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */ | ||
38 | {1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, | ||
39 | {0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, | ||
40 | {0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } }, | ||
41 | }; | ||
42 | |||
43 | void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) | ||
44 | { | ||
45 | struct tonga_hwmgr *tonga_hwmgr = (struct tonga_hwmgr *)(hwmgr->backend); | ||
46 | struct phm_ppt_v1_information *table_info = | ||
47 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
48 | uint32_t tmp = 0; | ||
49 | |||
50 | if (table_info && | ||
51 | table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && | ||
52 | table_info->cac_dtp_table->usPowerTuneDataSetID) | ||
53 | tonga_hwmgr->power_tune_defaults = | ||
54 | &tonga_power_tune_data_set_array | ||
55 | [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; | ||
56 | else | ||
57 | tonga_hwmgr->power_tune_defaults = &tonga_power_tune_data_set_array[0]; | ||
58 | |||
59 | /* Assume disabled */ | ||
60 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
61 | PHM_PlatformCaps_PowerContainment); | ||
62 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
63 | PHM_PlatformCaps_CAC); | ||
64 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
65 | PHM_PlatformCaps_SQRamping); | ||
66 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
67 | PHM_PlatformCaps_DBRamping); | ||
68 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
69 | PHM_PlatformCaps_TDRamping); | ||
70 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
71 | PHM_PlatformCaps_TCPRamping); | ||
72 | |||
73 | tonga_hwmgr->dte_tj_offset = tmp; | ||
74 | |||
75 | if (!tmp) { | ||
76 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | ||
77 | PHM_PlatformCaps_CAC); | ||
78 | |||
79 | tonga_hwmgr->fast_watermark_threshold = 100; | ||
80 | |||
81 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
82 | PHM_PlatformCaps_PowerContainment)) { | ||
83 | tmp = 1; | ||
84 | tonga_hwmgr->enable_dte_feature = tmp ? false : true; | ||
85 | tonga_hwmgr->enable_tdc_limit_feature = tmp ? true : false; | ||
86 | tonga_hwmgr->enable_pkg_pwr_tracking_feature = tmp ? true : false; | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | |||
91 | |||
92 | int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) | ||
93 | { | ||
94 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
95 | struct tonga_pt_defaults *defaults = data->power_tune_defaults; | ||
96 | SMU72_Discrete_DpmTable *dpm_table = &(data->smc_state_table); | ||
97 | struct phm_ppt_v1_information *table_info = | ||
98 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
99 | struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; | ||
100 | int i, j, k; | ||
101 | uint16_t *pdef1; | ||
102 | uint16_t *pdef2; | ||
103 | |||
104 | |||
105 | /* TDP number of fraction bits are changed from 8 to 7 for Fiji | ||
106 | * as requested by SMC team | ||
107 | */ | ||
108 | dpm_table->DefaultTdp = PP_HOST_TO_SMC_US( | ||
109 | (uint16_t)(cac_dtp_table->usTDP * 256)); | ||
110 | dpm_table->TargetTdp = PP_HOST_TO_SMC_US( | ||
111 | (uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); | ||
112 | |||
113 | PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, | ||
114 | "Target Operating Temp is out of Range!", | ||
115 | ); | ||
116 | |||
117 | dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp); | ||
118 | dpm_table->GpuTjHyst = 8; | ||
119 | |||
120 | dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; | ||
121 | |||
122 | dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bamp_temp_gradient); | ||
123 | pdef1 = defaults->bapmti_r; | ||
124 | pdef2 = defaults->bapmti_rc; | ||
125 | |||
126 | for (i = 0; i < SMU72_DTE_ITERATIONS; i++) { | ||
127 | for (j = 0; j < SMU72_DTE_SOURCES; j++) { | ||
128 | for (k = 0; k < SMU72_DTE_SINKS; k++) { | ||
129 | dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1); | ||
130 | dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2); | ||
131 | pdef1++; | ||
132 | pdef2++; | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int tonga_populate_svi_load_line(struct pp_hwmgr *hwmgr) | ||
141 | { | ||
142 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
143 | const struct tonga_pt_defaults *defaults = data->power_tune_defaults; | ||
144 | |||
145 | data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; | ||
146 | data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddC; | ||
147 | data->power_tune_table.SviLoadLineTrimVddC = 3; | ||
148 | data->power_tune_table.SviLoadLineOffsetVddC = 0; | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int tonga_populate_tdc_limit(struct pp_hwmgr *hwmgr) | ||
154 | { | ||
155 | uint16_t tdc_limit; | ||
156 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
157 | struct phm_ppt_v1_information *table_info = | ||
158 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
159 | const struct tonga_pt_defaults *defaults = data->power_tune_defaults; | ||
160 | |||
161 | /* TDC number of fraction bits are changed from 8 to 7 | ||
162 | * for Fiji as requested by SMC team | ||
163 | */ | ||
164 | tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 256); | ||
165 | data->power_tune_table.TDC_VDDC_PkgLimit = | ||
166 | CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); | ||
167 | data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = | ||
168 | defaults->tdc_vddc_throttle_release_limit_perc; | ||
169 | data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int tonga_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) | ||
175 | { | ||
176 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
177 | const struct tonga_pt_defaults *defaults = data->power_tune_defaults; | ||
178 | uint32_t temp; | ||
179 | |||
180 | if (tonga_read_smc_sram_dword(hwmgr->smumgr, | ||
181 | fuse_table_offset + | ||
182 | offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl), | ||
183 | (uint32_t *)&temp, data->sram_end)) | ||
184 | PP_ASSERT_WITH_CODE(false, | ||
185 | "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", | ||
186 | return -EINVAL); | ||
187 | else | ||
188 | data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int tonga_populate_temperature_scaler(struct pp_hwmgr *hwmgr) | ||
194 | { | ||
195 | int i; | ||
196 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
197 | |||
198 | /* Currently not used. Set all to zero. */ | ||
199 | for (i = 0; i < 16; i++) | ||
200 | data->power_tune_table.LPMLTemperatureScaler[i] = 0; | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int tonga_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) | ||
206 | { | ||
207 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
208 | |||
209 | if ((hwmgr->thermal_controller.advanceFanControlParameters. | ||
210 | usFanOutputSensitivity & (1 << 15)) || | ||
211 | (hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity == 0)) | ||
212 | hwmgr->thermal_controller.advanceFanControlParameters. | ||
213 | usFanOutputSensitivity = hwmgr->thermal_controller. | ||
214 | advanceFanControlParameters.usDefaultFanOutputSensitivity; | ||
215 | |||
216 | data->power_tune_table.FuzzyFan_PwmSetDelta = | ||
217 | PP_HOST_TO_SMC_US(hwmgr->thermal_controller. | ||
218 | advanceFanControlParameters.usFanOutputSensitivity); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static int tonga_populate_gnb_lpml(struct pp_hwmgr *hwmgr) | ||
223 | { | ||
224 | int i; | ||
225 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
226 | |||
227 | /* Currently not used. Set all to zero. */ | ||
228 | for (i = 0; i < 16; i++) | ||
229 | data->power_tune_table.GnbLPML[i] = 0; | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int tonga_min_max_vgnb_lpml_id_from_bapm_vddc(struct pp_hwmgr *hwmgr) | ||
235 | { | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int tonga_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) | ||
240 | { | ||
241 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
242 | struct phm_ppt_v1_information *table_info = | ||
243 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
244 | uint16_t hi_sidd = data->power_tune_table.BapmVddCBaseLeakageHiSidd; | ||
245 | uint16_t lo_sidd = data->power_tune_table.BapmVddCBaseLeakageLoSidd; | ||
246 | struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; | ||
247 | |||
248 | hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); | ||
249 | lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); | ||
250 | |||
251 | data->power_tune_table.BapmVddCBaseLeakageHiSidd = | ||
252 | CONVERT_FROM_HOST_TO_SMC_US(hi_sidd); | ||
253 | data->power_tune_table.BapmVddCBaseLeakageLoSidd = | ||
254 | CONVERT_FROM_HOST_TO_SMC_US(lo_sidd); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr) | ||
260 | { | ||
261 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
262 | uint32_t pm_fuse_table_offset; | ||
263 | |||
264 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
265 | PHM_PlatformCaps_PowerContainment)) { | ||
266 | if (tonga_read_smc_sram_dword(hwmgr->smumgr, | ||
267 | SMU72_FIRMWARE_HEADER_LOCATION + | ||
268 | offsetof(SMU72_Firmware_Header, PmFuseTable), | ||
269 | &pm_fuse_table_offset, data->sram_end)) | ||
270 | PP_ASSERT_WITH_CODE(false, | ||
271 | "Attempt to get pm_fuse_table_offset Failed!", | ||
272 | return -EINVAL); | ||
273 | |||
274 | /* DW6 */ | ||
275 | if (tonga_populate_svi_load_line(hwmgr)) | ||
276 | PP_ASSERT_WITH_CODE(false, | ||
277 | "Attempt to populate SviLoadLine Failed!", | ||
278 | return -EINVAL); | ||
279 | /* DW7 */ | ||
280 | if (tonga_populate_tdc_limit(hwmgr)) | ||
281 | PP_ASSERT_WITH_CODE(false, | ||
282 | "Attempt to populate TDCLimit Failed!", return -EINVAL); | ||
283 | /* DW8 */ | ||
284 | if (tonga_populate_dw8(hwmgr, pm_fuse_table_offset)) | ||
285 | PP_ASSERT_WITH_CODE(false, | ||
286 | "Attempt to populate TdcWaterfallCtl Failed !", | ||
287 | return -EINVAL); | ||
288 | |||
289 | /* DW9-DW12 */ | ||
290 | if (tonga_populate_temperature_scaler(hwmgr) != 0) | ||
291 | PP_ASSERT_WITH_CODE(false, | ||
292 | "Attempt to populate LPMLTemperatureScaler Failed!", | ||
293 | return -EINVAL); | ||
294 | |||
295 | /* DW13-DW14 */ | ||
296 | if (tonga_populate_fuzzy_fan(hwmgr)) | ||
297 | PP_ASSERT_WITH_CODE(false, | ||
298 | "Attempt to populate Fuzzy Fan Control parameters Failed!", | ||
299 | return -EINVAL); | ||
300 | |||
301 | /* DW15-DW18 */ | ||
302 | if (tonga_populate_gnb_lpml(hwmgr)) | ||
303 | PP_ASSERT_WITH_CODE(false, | ||
304 | "Attempt to populate GnbLPML Failed!", | ||
305 | return -EINVAL); | ||
306 | |||
307 | /* DW19 */ | ||
308 | if (tonga_min_max_vgnb_lpml_id_from_bapm_vddc(hwmgr)) | ||
309 | PP_ASSERT_WITH_CODE(false, | ||
310 | "Attempt to populate GnbLPML Min and Max Vid Failed!", | ||
311 | return -EINVAL); | ||
312 | |||
313 | /* DW20 */ | ||
314 | if (tonga_populate_bapm_vddc_base_leakage_sidd(hwmgr)) | ||
315 | PP_ASSERT_WITH_CODE(false, | ||
316 | "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!", | ||
317 | return -EINVAL); | ||
318 | |||
319 | if (tonga_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, | ||
320 | (uint8_t *)&data->power_tune_table, | ||
321 | sizeof(struct SMU72_Discrete_PmFuses), data->sram_end)) | ||
322 | PP_ASSERT_WITH_CODE(false, | ||
323 | "Attempt to download PmFuseTable Failed!", | ||
324 | return -EINVAL); | ||
325 | } | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | int tonga_enable_smc_cac(struct pp_hwmgr *hwmgr) | ||
330 | { | ||
331 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
332 | int result = 0; | ||
333 | |||
334 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
335 | PHM_PlatformCaps_CAC)) { | ||
336 | int smc_result; | ||
337 | |||
338 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
339 | (uint16_t)(PPSMC_MSG_EnableCac)); | ||
340 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
341 | "Failed to enable CAC in SMC.", result = -1); | ||
342 | |||
343 | data->cac_enabled = (smc_result == 0) ? true : false; | ||
344 | } | ||
345 | return result; | ||
346 | } | ||
347 | |||
348 | int tonga_disable_smc_cac(struct pp_hwmgr *hwmgr) | ||
349 | { | ||
350 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
351 | int result = 0; | ||
352 | |||
353 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
354 | PHM_PlatformCaps_CAC) && data->cac_enabled) { | ||
355 | int smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
356 | (uint16_t)(PPSMC_MSG_DisableCac)); | ||
357 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
358 | "Failed to disable CAC in SMC.", result = -1); | ||
359 | |||
360 | data->cac_enabled = false; | ||
361 | } | ||
362 | return result; | ||
363 | } | ||
364 | |||
365 | int tonga_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) | ||
366 | { | ||
367 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
368 | |||
369 | if (data->power_containment_features & | ||
370 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) | ||
371 | return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | ||
372 | PPSMC_MSG_PkgPwrSetLimit, n); | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int tonga_set_overdriver_target_tdp(struct pp_hwmgr *pHwMgr, uint32_t target_tdp) | ||
377 | { | ||
378 | return smum_send_msg_to_smc_with_parameter(pHwMgr->smumgr, | ||
379 | PPSMC_MSG_OverDriveSetTargetTdp, target_tdp); | ||
380 | } | ||
381 | |||
382 | int tonga_enable_power_containment(struct pp_hwmgr *hwmgr) | ||
383 | { | ||
384 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
385 | struct phm_ppt_v1_information *table_info = | ||
386 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
387 | int smc_result; | ||
388 | int result = 0; | ||
389 | |||
390 | data->power_containment_features = 0; | ||
391 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
392 | PHM_PlatformCaps_PowerContainment)) { | ||
393 | if (data->enable_dte_feature) { | ||
394 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
395 | (uint16_t)(PPSMC_MSG_EnableDTE)); | ||
396 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
397 | "Failed to enable DTE in SMC.", result = -1;); | ||
398 | if (smc_result == 0) | ||
399 | data->power_containment_features |= POWERCONTAINMENT_FEATURE_DTE; | ||
400 | } | ||
401 | |||
402 | if (data->enable_tdc_limit_feature) { | ||
403 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
404 | (uint16_t)(PPSMC_MSG_TDCLimitEnable)); | ||
405 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
406 | "Failed to enable TDCLimit in SMC.", result = -1;); | ||
407 | if (smc_result == 0) | ||
408 | data->power_containment_features |= | ||
409 | POWERCONTAINMENT_FEATURE_TDCLimit; | ||
410 | } | ||
411 | |||
412 | if (data->enable_pkg_pwr_tracking_feature) { | ||
413 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
414 | (uint16_t)(PPSMC_MSG_PkgPwrLimitEnable)); | ||
415 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
416 | "Failed to enable PkgPwrTracking in SMC.", result = -1;); | ||
417 | if (smc_result == 0) { | ||
418 | struct phm_cac_tdp_table *cac_table = | ||
419 | table_info->cac_dtp_table; | ||
420 | uint32_t default_limit = | ||
421 | (uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256); | ||
422 | |||
423 | data->power_containment_features |= | ||
424 | POWERCONTAINMENT_FEATURE_PkgPwrLimit; | ||
425 | |||
426 | if (tonga_set_power_limit(hwmgr, default_limit)) | ||
427 | printk(KERN_ERR "Failed to set Default Power Limit in SMC!"); | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | return result; | ||
432 | } | ||
433 | |||
434 | int tonga_disable_power_containment(struct pp_hwmgr *hwmgr) | ||
435 | { | ||
436 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
437 | int result = 0; | ||
438 | |||
439 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
440 | PHM_PlatformCaps_PowerContainment) && | ||
441 | data->power_containment_features) { | ||
442 | int smc_result; | ||
443 | |||
444 | if (data->power_containment_features & | ||
445 | POWERCONTAINMENT_FEATURE_TDCLimit) { | ||
446 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
447 | (uint16_t)(PPSMC_MSG_TDCLimitDisable)); | ||
448 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
449 | "Failed to disable TDCLimit in SMC.", | ||
450 | result = smc_result); | ||
451 | } | ||
452 | |||
453 | if (data->power_containment_features & | ||
454 | POWERCONTAINMENT_FEATURE_DTE) { | ||
455 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
456 | (uint16_t)(PPSMC_MSG_DisableDTE)); | ||
457 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
458 | "Failed to disable DTE in SMC.", | ||
459 | result = smc_result); | ||
460 | } | ||
461 | |||
462 | if (data->power_containment_features & | ||
463 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) { | ||
464 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
465 | (uint16_t)(PPSMC_MSG_PkgPwrLimitDisable)); | ||
466 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
467 | "Failed to disable PkgPwrTracking in SMC.", | ||
468 | result = smc_result); | ||
469 | } | ||
470 | data->power_containment_features = 0; | ||
471 | } | ||
472 | |||
473 | return result; | ||
474 | } | ||
475 | |||
476 | int tonga_power_control_set_level(struct pp_hwmgr *hwmgr) | ||
477 | { | ||
478 | struct phm_ppt_v1_information *table_info = | ||
479 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
480 | struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; | ||
481 | int adjust_percent, target_tdp; | ||
482 | int result = 0; | ||
483 | |||
484 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
485 | PHM_PlatformCaps_PowerContainment)) { | ||
486 | /* adjustment percentage has already been validated */ | ||
487 | adjust_percent = hwmgr->platform_descriptor.TDPAdjustmentPolarity ? | ||
488 | hwmgr->platform_descriptor.TDPAdjustment : | ||
489 | (-1 * hwmgr->platform_descriptor.TDPAdjustment); | ||
490 | /* SMC requested that target_tdp to be 7 bit fraction in DPM table | ||
491 | * but message to be 8 bit fraction for messages | ||
492 | */ | ||
493 | target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100; | ||
494 | result = tonga_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp); | ||
495 | } | ||
496 | |||
497 | return result; | ||
498 | } | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h index 8e6670b3cb67..c8bdb92d81f4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h | |||
@@ -35,20 +35,23 @@ enum _phw_tonga_ptc_config_reg_type { | |||
35 | typedef enum _phw_tonga_ptc_config_reg_type phw_tonga_ptc_config_reg_type; | 35 | typedef enum _phw_tonga_ptc_config_reg_type phw_tonga_ptc_config_reg_type; |
36 | 36 | ||
37 | /* PowerContainment Features */ | 37 | /* PowerContainment Features */ |
38 | #define POWERCONTAINMENT_FEATURE_DTE 0x00000001 | ||
39 | |||
40 | |||
41 | /* PowerContainment Features */ | ||
38 | #define POWERCONTAINMENT_FEATURE_BAPM 0x00000001 | 42 | #define POWERCONTAINMENT_FEATURE_BAPM 0x00000001 |
39 | #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 | 43 | #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 |
40 | #define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004 | 44 | #define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004 |
41 | 45 | ||
42 | struct _phw_tonga_pt_config_reg { | 46 | struct tonga_pt_config_reg { |
43 | uint32_t Offset; | 47 | uint32_t Offset; |
44 | uint32_t Mask; | 48 | uint32_t Mask; |
45 | uint32_t Shift; | 49 | uint32_t Shift; |
46 | uint32_t Value; | 50 | uint32_t Value; |
47 | phw_tonga_ptc_config_reg_type Type; | 51 | phw_tonga_ptc_config_reg_type Type; |
48 | }; | 52 | }; |
49 | typedef struct _phw_tonga_pt_config_reg phw_tonga_pt_config_reg; | ||
50 | 53 | ||
51 | struct _phw_tonga_pt_defaults { | 54 | struct tonga_pt_defaults { |
52 | uint8_t svi_load_line_en; | 55 | uint8_t svi_load_line_en; |
53 | uint8_t svi_load_line_vddC; | 56 | uint8_t svi_load_line_vddC; |
54 | uint8_t tdc_vddc_throttle_release_limit_perc; | 57 | uint8_t tdc_vddc_throttle_release_limit_perc; |
@@ -60,7 +63,18 @@ struct _phw_tonga_pt_defaults { | |||
60 | uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; | 63 | uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; |
61 | uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; | 64 | uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; |
62 | }; | 65 | }; |
63 | typedef struct _phw_tonga_pt_defaults phw_tonga_pt_defaults; | 66 | |
67 | |||
68 | |||
69 | void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr); | ||
70 | int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); | ||
71 | int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr); | ||
72 | int tonga_enable_smc_cac(struct pp_hwmgr *hwmgr); | ||
73 | int tonga_disable_smc_cac(struct pp_hwmgr *hwmgr); | ||
74 | int tonga_enable_power_containment(struct pp_hwmgr *hwmgr); | ||
75 | int tonga_disable_power_containment(struct pp_hwmgr *hwmgr); | ||
76 | int tonga_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n); | ||
77 | int tonga_power_control_set_level(struct pp_hwmgr *hwmgr); | ||
64 | 78 | ||
65 | #endif | 79 | #endif |
66 | 80 | ||