]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
Merge branch 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
[mirror_ubuntu-artful-kernel.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_powerplay.c
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 * Authors: AMD
23 *
24 */
25 #include "atom.h"
26 #include "amdgpu.h"
27 #include "amd_shared.h"
28 #include <linux/module.h>
29 #include <linux/moduleparam.h>
30 #include "amdgpu_pm.h"
31 #include <drm/amdgpu_drm.h>
32 #include "amdgpu_powerplay.h"
33 #include "si_dpm.h"
34 #include "cik_dpm.h"
35 #include "vi_dpm.h"
36
37 static int amdgpu_powerplay_init(struct amdgpu_device *adev)
38 {
39 int ret = 0;
40 struct amd_powerplay *amd_pp;
41
42 amd_pp = &(adev->powerplay);
43
44 if (adev->pp_enabled) {
45 struct amd_pp_init *pp_init;
46
47 pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL);
48
49 if (pp_init == NULL)
50 return -ENOMEM;
51
52 pp_init->chip_family = adev->family;
53 pp_init->chip_id = adev->asic_type;
54 pp_init->device = amdgpu_cgs_create_device(adev);
55 ret = amd_powerplay_init(pp_init, amd_pp);
56 kfree(pp_init);
57 } else {
58 amd_pp->pp_handle = (void *)adev;
59
60 switch (adev->asic_type) {
61 #ifdef CONFIG_DRM_AMDGPU_SI
62 case CHIP_TAHITI:
63 case CHIP_PITCAIRN:
64 case CHIP_VERDE:
65 case CHIP_OLAND:
66 case CHIP_HAINAN:
67 amd_pp->ip_funcs = &si_dpm_ip_funcs;
68 break;
69 #endif
70 #ifdef CONFIG_DRM_AMDGPU_CIK
71 case CHIP_BONAIRE:
72 case CHIP_HAWAII:
73 amd_pp->ip_funcs = &ci_dpm_ip_funcs;
74 break;
75 case CHIP_KABINI:
76 case CHIP_MULLINS:
77 case CHIP_KAVERI:
78 amd_pp->ip_funcs = &kv_dpm_ip_funcs;
79 break;
80 #endif
81 case CHIP_CARRIZO:
82 case CHIP_STONEY:
83 amd_pp->ip_funcs = &cz_dpm_ip_funcs;
84 break;
85 default:
86 ret = -EINVAL;
87 break;
88 }
89 }
90 return ret;
91 }
92
93 static int amdgpu_pp_early_init(void *handle)
94 {
95 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
96 int ret = 0;
97
98 switch (adev->asic_type) {
99 case CHIP_POLARIS11:
100 case CHIP_POLARIS10:
101 case CHIP_POLARIS12:
102 case CHIP_TONGA:
103 case CHIP_FIJI:
104 case CHIP_TOPAZ:
105 adev->pp_enabled = true;
106 break;
107 case CHIP_CARRIZO:
108 case CHIP_STONEY:
109 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true;
110 break;
111 /* These chips don't have powerplay implemenations */
112 case CHIP_BONAIRE:
113 case CHIP_HAWAII:
114 case CHIP_KABINI:
115 case CHIP_MULLINS:
116 case CHIP_KAVERI:
117 default:
118 adev->pp_enabled = false;
119 break;
120 }
121
122 ret = amdgpu_powerplay_init(adev);
123 if (ret)
124 return ret;
125
126 if (adev->powerplay.ip_funcs->early_init)
127 ret = adev->powerplay.ip_funcs->early_init(
128 adev->powerplay.pp_handle);
129 return ret;
130 }
131
132
133 static int amdgpu_pp_late_init(void *handle)
134 {
135 int ret = 0;
136 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
137
138 if (adev->powerplay.ip_funcs->late_init)
139 ret = adev->powerplay.ip_funcs->late_init(
140 adev->powerplay.pp_handle);
141
142 if (adev->pp_enabled && adev->pm.dpm_enabled) {
143 amdgpu_pm_sysfs_init(adev);
144 amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
145 }
146
147 return ret;
148 }
149
150 static int amdgpu_pp_sw_init(void *handle)
151 {
152 int ret = 0;
153 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
154
155 if (adev->powerplay.ip_funcs->sw_init)
156 ret = adev->powerplay.ip_funcs->sw_init(
157 adev->powerplay.pp_handle);
158
159 return ret;
160 }
161
162 static int amdgpu_pp_sw_fini(void *handle)
163 {
164 int ret = 0;
165 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
166
167 if (adev->powerplay.ip_funcs->sw_fini)
168 ret = adev->powerplay.ip_funcs->sw_fini(
169 adev->powerplay.pp_handle);
170 if (ret)
171 return ret;
172
173 return ret;
174 }
175
176 static int amdgpu_pp_hw_init(void *handle)
177 {
178 int ret = 0;
179 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
180
181 if (adev->pp_enabled && adev->firmware.smu_load)
182 amdgpu_ucode_init_bo(adev);
183
184 if (adev->powerplay.ip_funcs->hw_init)
185 ret = adev->powerplay.ip_funcs->hw_init(
186 adev->powerplay.pp_handle);
187
188 if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev))
189 adev->pm.dpm_enabled = true;
190
191 return ret;
192 }
193
194 static int amdgpu_pp_hw_fini(void *handle)
195 {
196 int ret = 0;
197 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
198
199 if (adev->powerplay.ip_funcs->hw_fini)
200 ret = adev->powerplay.ip_funcs->hw_fini(
201 adev->powerplay.pp_handle);
202
203 if (adev->pp_enabled && adev->firmware.smu_load)
204 amdgpu_ucode_fini_bo(adev);
205
206 return ret;
207 }
208
209 static void amdgpu_pp_late_fini(void *handle)
210 {
211 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
212
213 if (adev->pp_enabled) {
214 amdgpu_pm_sysfs_fini(adev);
215 amd_powerplay_fini(adev->powerplay.pp_handle);
216 }
217
218 if (adev->powerplay.ip_funcs->late_fini)
219 adev->powerplay.ip_funcs->late_fini(
220 adev->powerplay.pp_handle);
221 }
222
223 static int amdgpu_pp_suspend(void *handle)
224 {
225 int ret = 0;
226 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
227
228 if (adev->powerplay.ip_funcs->suspend)
229 ret = adev->powerplay.ip_funcs->suspend(
230 adev->powerplay.pp_handle);
231 return ret;
232 }
233
234 static int amdgpu_pp_resume(void *handle)
235 {
236 int ret = 0;
237 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
238
239 if (adev->powerplay.ip_funcs->resume)
240 ret = adev->powerplay.ip_funcs->resume(
241 adev->powerplay.pp_handle);
242 return ret;
243 }
244
245 static int amdgpu_pp_set_clockgating_state(void *handle,
246 enum amd_clockgating_state state)
247 {
248 int ret = 0;
249 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
250
251 if (adev->powerplay.ip_funcs->set_clockgating_state)
252 ret = adev->powerplay.ip_funcs->set_clockgating_state(
253 adev->powerplay.pp_handle, state);
254 return ret;
255 }
256
257 static int amdgpu_pp_set_powergating_state(void *handle,
258 enum amd_powergating_state state)
259 {
260 int ret = 0;
261 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
262
263 if (adev->powerplay.ip_funcs->set_powergating_state)
264 ret = adev->powerplay.ip_funcs->set_powergating_state(
265 adev->powerplay.pp_handle, state);
266 return ret;
267 }
268
269
270 static bool amdgpu_pp_is_idle(void *handle)
271 {
272 bool ret = true;
273 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
274
275 if (adev->powerplay.ip_funcs->is_idle)
276 ret = adev->powerplay.ip_funcs->is_idle(
277 adev->powerplay.pp_handle);
278 return ret;
279 }
280
281 static int amdgpu_pp_wait_for_idle(void *handle)
282 {
283 int ret = 0;
284 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
285
286 if (adev->powerplay.ip_funcs->wait_for_idle)
287 ret = adev->powerplay.ip_funcs->wait_for_idle(
288 adev->powerplay.pp_handle);
289 return ret;
290 }
291
292 static int amdgpu_pp_soft_reset(void *handle)
293 {
294 int ret = 0;
295 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
296
297 if (adev->powerplay.ip_funcs->soft_reset)
298 ret = adev->powerplay.ip_funcs->soft_reset(
299 adev->powerplay.pp_handle);
300 return ret;
301 }
302
303 static const struct amd_ip_funcs amdgpu_pp_ip_funcs = {
304 .name = "amdgpu_powerplay",
305 .early_init = amdgpu_pp_early_init,
306 .late_init = amdgpu_pp_late_init,
307 .sw_init = amdgpu_pp_sw_init,
308 .sw_fini = amdgpu_pp_sw_fini,
309 .hw_init = amdgpu_pp_hw_init,
310 .hw_fini = amdgpu_pp_hw_fini,
311 .late_fini = amdgpu_pp_late_fini,
312 .suspend = amdgpu_pp_suspend,
313 .resume = amdgpu_pp_resume,
314 .is_idle = amdgpu_pp_is_idle,
315 .wait_for_idle = amdgpu_pp_wait_for_idle,
316 .soft_reset = amdgpu_pp_soft_reset,
317 .set_clockgating_state = amdgpu_pp_set_clockgating_state,
318 .set_powergating_state = amdgpu_pp_set_powergating_state,
319 };
320
321 const struct amdgpu_ip_block_version amdgpu_pp_ip_block =
322 {
323 .type = AMD_IP_BLOCK_TYPE_SMC,
324 .major = 1,
325 .minor = 0,
326 .rev = 0,
327 .funcs = &amdgpu_pp_ip_funcs,
328 };