Merge tag 'staging-4.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[deliverable/linux.git] / drivers / gpu / drm / amd / powerplay / hwmgr / tonga_clockpowergating.c
CommitLineData
0859ed3d
RZ
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 "tonga_clockpowergating.h"
26#include "tonga_ppsmc.h"
27#include "tonga_hwmgr.h"
28
29int tonga_phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
30{
31 if (phm_cf_want_uvd_power_gating(hwmgr))
32 return smum_send_msg_to_smc(hwmgr->smumgr,
33 PPSMC_MSG_UVDPowerOFF);
34 return 0;
35}
36
37int tonga_phm_powerup_uvd(struct pp_hwmgr *hwmgr)
38{
39 if (phm_cf_want_uvd_power_gating(hwmgr)) {
40 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
41 PHM_PlatformCaps_UVDDynamicPowerGating)) {
42 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
43 PPSMC_MSG_UVDPowerON, 1);
44 } else {
45 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
46 PPSMC_MSG_UVDPowerON, 0);
47 }
48 }
49
50 return 0;
51}
52
53int tonga_phm_powerdown_vce(struct pp_hwmgr *hwmgr)
54{
55 if (phm_cf_want_vce_power_gating(hwmgr))
56 return smum_send_msg_to_smc(hwmgr->smumgr,
57 PPSMC_MSG_VCEPowerOFF);
58 return 0;
59}
60
61int tonga_phm_powerup_vce(struct pp_hwmgr *hwmgr)
62{
63 if (phm_cf_want_vce_power_gating(hwmgr))
64 return smum_send_msg_to_smc(hwmgr->smumgr,
65 PPSMC_MSG_VCEPowerON);
66 return 0;
67}
68
69int tonga_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
70{
71 int ret = 0;
72
73 switch (block) {
74 case PHM_AsicBlock_UVD_MVC:
75 case PHM_AsicBlock_UVD:
76 case PHM_AsicBlock_UVD_HD:
77 case PHM_AsicBlock_UVD_SD:
78 if (gating == PHM_ClockGateSetting_StaticOff)
79 ret = tonga_phm_powerdown_uvd(hwmgr);
80 else
81 ret = tonga_phm_powerup_uvd(hwmgr);
82 break;
83 case PHM_AsicBlock_GFX:
84 default:
85 break;
86 }
87
88 return ret;
89}
90
91int tonga_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
92{
93 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
94
95 data->uvd_power_gated = false;
96 data->vce_power_gated = false;
97
98 tonga_phm_powerup_uvd(hwmgr);
99 tonga_phm_powerup_vce(hwmgr);
100
101 return 0;
102}
103
104int tonga_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
105{
106 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
107
108 if (data->uvd_power_gated == bgate)
109 return 0;
110
111 data->uvd_power_gated = bgate;
112
113 if (bgate) {
114 cgs_set_clockgating_state(hwmgr->device,
115 AMD_IP_BLOCK_TYPE_UVD,
116 AMD_CG_STATE_UNGATE);
117 cgs_set_powergating_state(hwmgr->device,
118 AMD_IP_BLOCK_TYPE_UVD,
119 AMD_PG_STATE_GATE);
120 tonga_update_uvd_dpm(hwmgr, true);
121 tonga_phm_powerdown_uvd(hwmgr);
122 } else {
123 tonga_phm_powerup_uvd(hwmgr);
124 cgs_set_powergating_state(hwmgr->device,
125 AMD_IP_BLOCK_TYPE_UVD,
126 AMD_PG_STATE_UNGATE);
127 cgs_set_clockgating_state(hwmgr->device,
128 AMD_IP_BLOCK_TYPE_UVD,
129 AMD_PG_STATE_GATE);
130
131 tonga_update_uvd_dpm(hwmgr, false);
132 }
133
134 return 0;
135}
136
137int tonga_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
138{
139 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
140 struct phm_set_power_state_input states;
141 const struct pp_power_state *pcurrent;
142 struct pp_power_state *requested;
143
144 pcurrent = hwmgr->current_ps;
145 requested = hwmgr->request_ps;
146
147 states.pcurrent_state = &(pcurrent->hardware);
148 states.pnew_state = &(requested->hardware);
149
150 if (phm_cf_want_vce_power_gating(hwmgr)) {
151 if (data->vce_power_gated != bgate) {
152 if (bgate) {
153 cgs_set_clockgating_state(
154 hwmgr->device,
155 AMD_IP_BLOCK_TYPE_VCE,
156 AMD_CG_STATE_UNGATE);
157 cgs_set_powergating_state(
158 hwmgr->device,
159 AMD_IP_BLOCK_TYPE_VCE,
160 AMD_PG_STATE_GATE);
161 tonga_enable_disable_vce_dpm(hwmgr, false);
162 data->vce_power_gated = true;
163 } else {
164 tonga_phm_powerup_vce(hwmgr);
165 data->vce_power_gated = false;
166 cgs_set_powergating_state(
167 hwmgr->device,
168 AMD_IP_BLOCK_TYPE_VCE,
169 AMD_PG_STATE_UNGATE);
170 cgs_set_clockgating_state(
171 hwmgr->device,
172 AMD_IP_BLOCK_TYPE_VCE,
173 AMD_PG_STATE_GATE);
174
175 tonga_update_vce_dpm(hwmgr, &states);
176 tonga_enable_disable_vce_dpm(hwmgr, true);
177 return 0;
178 }
179 }
180 } else {
181 tonga_update_vce_dpm(hwmgr, &states);
182 tonga_enable_disable_vce_dpm(hwmgr, true);
183 return 0;
184 }
185
186 if (!data->vce_power_gated)
187 tonga_update_vce_dpm(hwmgr, &states);
188
189 return 0;
190}
191
192int tonga_phm_update_clock_gatings(struct pp_hwmgr *hwmgr,
193 const uint32_t *msg_id)
194{
195 PPSMC_Msg msg;
196 uint32_t value;
197
198 switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
199 case PP_GROUP_GFX:
200 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
201 case PP_BLOCK_GFX_CG:
202 if (PP_STATE_SUPPORT_CG & *msg_id) {
203 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
204 ? PPSMC_MSG_EnableClockGatingFeature
205 : PPSMC_MSG_DisableClockGatingFeature;
206 value = CG_GFX_CGCG_MASK;
207
208 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
209 return -1;
210 }
211 if (PP_STATE_SUPPORT_LS & *msg_id) {
212 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
213 ? PPSMC_MSG_EnableClockGatingFeature
214 : PPSMC_MSG_DisableClockGatingFeature;
215 value = CG_GFX_CGLS_MASK;
216
217 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
218 return -1;
219 }
220 break;
221
222 case PP_BLOCK_GFX_MG:
223 /* For GFX MGCG, there are three different ones;
224 * CPF, RLC, and all others. CPF MGCG will not be used for Tonga.
225 * For GFX MGLS, Tonga will not support it.
226 * */
227 if (PP_STATE_SUPPORT_CG & *msg_id) {
228 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
229 ? PPSMC_MSG_EnableClockGatingFeature
230 : PPSMC_MSG_DisableClockGatingFeature;
231 value = (CG_RLC_MGCG_MASK | CG_GFX_OTHERS_MGCG_MASK);
232
233 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
234 return -1;
235 }
236 break;
237
238 default:
239 return -1;
240 }
241 break;
242
243 case PP_GROUP_SYS:
244 switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
245 case PP_BLOCK_SYS_BIF:
246 if (PP_STATE_SUPPORT_LS & *msg_id) {
247 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
248 ? PPSMC_MSG_EnableClockGatingFeature
249 : PPSMC_MSG_DisableClockGatingFeature;
250 value = CG_SYS_BIF_MGLS_MASK;
251
252 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
253 return -1;
254 }
255 break;
256
257 case PP_BLOCK_SYS_MC:
258 if (PP_STATE_SUPPORT_CG & *msg_id) {
259 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
260 ? PPSMC_MSG_EnableClockGatingFeature
261 : PPSMC_MSG_DisableClockGatingFeature;
262 value = CG_SYS_MC_MGCG_MASK;
263
264 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
265 return -1;
266 }
267
268 if (PP_STATE_SUPPORT_LS & *msg_id) {
269 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
270 ? PPSMC_MSG_EnableClockGatingFeature
271 : PPSMC_MSG_DisableClockGatingFeature;
272 value = CG_SYS_MC_MGLS_MASK;
273
274 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
275 return -1;
276
277 }
278 break;
279
280 case PP_BLOCK_SYS_HDP:
281 if (PP_STATE_SUPPORT_CG & *msg_id) {
282 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
283 ? PPSMC_MSG_EnableClockGatingFeature
284 : PPSMC_MSG_DisableClockGatingFeature;
285 value = CG_SYS_HDP_MGCG_MASK;
286
287 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
288 return -1;
289 }
290
291 if (PP_STATE_SUPPORT_LS & *msg_id) {
292 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
293 ? PPSMC_MSG_EnableClockGatingFeature
294 : PPSMC_MSG_DisableClockGatingFeature;
295
296 value = CG_SYS_HDP_MGLS_MASK;
297
298 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
299 return -1;
300 }
301 break;
302
303 case PP_BLOCK_SYS_SDMA:
304 if (PP_STATE_SUPPORT_CG & *msg_id) {
305 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
306 ? PPSMC_MSG_EnableClockGatingFeature
307 : PPSMC_MSG_DisableClockGatingFeature;
308 value = CG_SYS_SDMA_MGCG_MASK;
309
310 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
311 return -1;
312 }
313
314 if (PP_STATE_SUPPORT_LS & *msg_id) {
315 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
316 ? PPSMC_MSG_EnableClockGatingFeature
317 : PPSMC_MSG_DisableClockGatingFeature;
318
319 value = CG_SYS_SDMA_MGLS_MASK;
320
321 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
322 return -1;
323 }
324 break;
325
326 case PP_BLOCK_SYS_ROM:
327 if (PP_STATE_SUPPORT_CG & *msg_id) {
328 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
329 ? PPSMC_MSG_EnableClockGatingFeature
330 : PPSMC_MSG_DisableClockGatingFeature;
331 value = CG_SYS_ROM_MASK;
332
333 if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
334 return -1;
335 }
336 break;
337
338 default:
339 return -1;
340
341 }
342 break;
343
344 default:
345 return -1;
346
347 }
348
349 return 0;
350}
This page took 0.057201 seconds and 5 git commands to generate.