104c03ae27425a43580d92fdd7be4a46d3fcf367
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / intel_uc.c
1 /*
2  * Copyright © 2016 Intel Corporation
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 (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  */
24
25 #include "intel_uc.h"
26 #include "intel_guc_submission.h"
27 #include "intel_guc.h"
28 #include "i915_drv.h"
29
30 static void guc_free_load_err_log(struct intel_guc *guc);
31
32 /* Reset GuC providing us with fresh state for both GuC and HuC.
33  */
34 static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
35 {
36         int ret;
37         u32 guc_status;
38
39         ret = intel_reset_guc(dev_priv);
40         if (ret) {
41                 DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
42                 return ret;
43         }
44
45         guc_status = I915_READ(GUC_STATUS);
46         WARN(!(guc_status & GS_MIA_IN_RESET),
47              "GuC status: 0x%x, MIA core expected to be in reset\n",
48              guc_status);
49
50         return ret;
51 }
52
53 static int __get_platform_enable_guc(struct drm_i915_private *dev_priv)
54 {
55         struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
56         struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
57         int enable_guc = 0;
58
59         /* Default is to enable GuC/HuC if we know their firmwares */
60         if (intel_uc_fw_is_selected(guc_fw))
61                 enable_guc |= ENABLE_GUC_SUBMISSION;
62         if (intel_uc_fw_is_selected(huc_fw))
63                 enable_guc |= ENABLE_GUC_LOAD_HUC;
64
65         /* Any platform specific fine-tuning can be done here */
66
67         return enable_guc;
68 }
69
70 static int __get_default_guc_log_level(struct drm_i915_private *dev_priv)
71 {
72         int guc_log_level = 0; /* disabled */
73
74         /* Enable if we're running on platform with GuC and debug config */
75         if (HAS_GUC(dev_priv) && intel_uc_is_using_guc() &&
76             (IS_ENABLED(CONFIG_DRM_I915_DEBUG) ||
77              IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)))
78                 guc_log_level = 1 + GUC_LOG_VERBOSITY_MAX;
79
80         /* Any platform specific fine-tuning can be done here */
81
82         return guc_log_level;
83 }
84
85 /**
86  * sanitize_options_early - sanitize uC related modparam options
87  * @dev_priv: device private
88  *
89  * In case of "enable_guc" option this function will attempt to modify
90  * it only if it was initially set to "auto(-1)". Default value for this
91  * modparam varies between platforms and it is hardcoded in driver code.
92  * Any other modparam value is only monitored against availability of the
93  * related hardware or firmware definitions.
94  *
95  * In case of "guc_log_level" option this function will attempt to modify
96  * it only if it was initially set to "auto(-1)" or if initial value was
97  * "enable(1..4)" on platforms without the GuC. Default value for this
98  * modparam varies between platforms and is usually set to "disable(0)"
99  * unless GuC is enabled on given platform and the driver is compiled with
100  * debug config when this modparam will default to "enable(1..4)".
101  */
102 static void sanitize_options_early(struct drm_i915_private *dev_priv)
103 {
104         struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
105         struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
106
107         /* A negative value means "use platform default" */
108         if (i915_modparams.enable_guc < 0)
109                 i915_modparams.enable_guc = __get_platform_enable_guc(dev_priv);
110
111         DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n",
112                          i915_modparams.enable_guc,
113                          yesno(intel_uc_is_using_guc_submission()),
114                          yesno(intel_uc_is_using_huc()));
115
116         /* Verify GuC firmware availability */
117         if (intel_uc_is_using_guc() && !intel_uc_fw_is_selected(guc_fw)) {
118                 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
119                          "enable_guc", i915_modparams.enable_guc,
120                          !HAS_GUC(dev_priv) ? "no GuC hardware" :
121                                               "no GuC firmware");
122         }
123
124         /* Verify HuC firmware availability */
125         if (intel_uc_is_using_huc() && !intel_uc_fw_is_selected(huc_fw)) {
126                 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
127                          "enable_guc", i915_modparams.enable_guc,
128                          !HAS_HUC(dev_priv) ? "no HuC hardware" :
129                                               "no HuC firmware");
130         }
131
132         /* A negative value means "use platform/config default" */
133         if (i915_modparams.guc_log_level < 0)
134                 i915_modparams.guc_log_level =
135                         __get_default_guc_log_level(dev_priv);
136
137         if (i915_modparams.guc_log_level > 0 && !intel_uc_is_using_guc()) {
138                 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
139                          "guc_log_level", i915_modparams.guc_log_level,
140                          !HAS_GUC(dev_priv) ? "no GuC hardware" :
141                                               "GuC not enabled");
142                 i915_modparams.guc_log_level = 0;
143         }
144
145         if (i915_modparams.guc_log_level > 1 + GUC_LOG_VERBOSITY_MAX) {
146                 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
147                          "guc_log_level", i915_modparams.guc_log_level,
148                          "verbosity too high");
149                 i915_modparams.guc_log_level = 1 + GUC_LOG_VERBOSITY_MAX;
150         }
151
152         DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s verbosity:%d)\n",
153                          i915_modparams.guc_log_level,
154                          yesno(i915_modparams.guc_log_level),
155                          i915_modparams.guc_log_level - 1);
156
157         /* Make sure that sanitization was done */
158         GEM_BUG_ON(i915_modparams.enable_guc < 0);
159         GEM_BUG_ON(i915_modparams.guc_log_level < 0);
160 }
161
162 void intel_uc_init_early(struct drm_i915_private *dev_priv)
163 {
164         intel_guc_init_early(&dev_priv->guc);
165         intel_huc_init_early(&dev_priv->huc);
166
167         sanitize_options_early(dev_priv);
168 }
169
170 void intel_uc_init_fw(struct drm_i915_private *dev_priv)
171 {
172         if (!USES_GUC(dev_priv))
173                 return;
174
175         if (USES_HUC(dev_priv))
176                 intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
177
178         intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw);
179 }
180
181 void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
182 {
183         if (!USES_GUC(dev_priv))
184                 return;
185
186         intel_uc_fw_fini(&dev_priv->guc.fw);
187
188         if (USES_HUC(dev_priv))
189                 intel_uc_fw_fini(&dev_priv->huc.fw);
190
191         guc_free_load_err_log(&dev_priv->guc);
192 }
193
194 /**
195  * intel_uc_init_mmio - setup uC MMIO access
196  *
197  * @dev_priv: device private
198  *
199  * Setup minimal state necessary for MMIO accesses later in the
200  * initialization sequence.
201  */
202 void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
203 {
204         intel_guc_init_send_regs(&dev_priv->guc);
205 }
206
207 static void guc_capture_load_err_log(struct intel_guc *guc)
208 {
209         if (!guc->log.vma || !i915_modparams.guc_log_level)
210                 return;
211
212         if (!guc->load_err_log)
213                 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
214
215         return;
216 }
217
218 static void guc_free_load_err_log(struct intel_guc *guc)
219 {
220         if (guc->load_err_log)
221                 i915_gem_object_put(guc->load_err_log);
222 }
223
224 int intel_uc_register(struct drm_i915_private *i915)
225 {
226         int ret = 0;
227
228         if (!USES_GUC(i915))
229                 return 0;
230
231         if (i915_modparams.guc_log_level)
232                 ret = intel_guc_log_register(&i915->guc.log);
233
234         return ret;
235 }
236
237 void intel_uc_unregister(struct drm_i915_private *i915)
238 {
239         if (!USES_GUC(i915))
240                 return;
241
242         if (i915_modparams.guc_log_level)
243                 intel_guc_log_unregister(&i915->guc.log);
244 }
245
246 static int guc_enable_communication(struct intel_guc *guc)
247 {
248         struct drm_i915_private *dev_priv = guc_to_i915(guc);
249
250         if (HAS_GUC_CT(dev_priv))
251                 return intel_guc_enable_ct(guc);
252
253         guc->send = intel_guc_send_mmio;
254         return 0;
255 }
256
257 static void guc_disable_communication(struct intel_guc *guc)
258 {
259         struct drm_i915_private *dev_priv = guc_to_i915(guc);
260
261         if (HAS_GUC_CT(dev_priv))
262                 intel_guc_disable_ct(guc);
263
264         guc->send = intel_guc_send_nop;
265 }
266
267 int intel_uc_init_misc(struct drm_i915_private *dev_priv)
268 {
269         struct intel_guc *guc = &dev_priv->guc;
270         int ret;
271
272         if (!USES_GUC(dev_priv))
273                 return 0;
274
275         intel_guc_init_ggtt_pin_bias(guc);
276
277         ret = intel_guc_init_wq(guc);
278         if (ret)
279                 return ret;
280
281         return 0;
282 }
283
284 void intel_uc_fini_misc(struct drm_i915_private *dev_priv)
285 {
286         struct intel_guc *guc = &dev_priv->guc;
287
288         if (!USES_GUC(dev_priv))
289                 return;
290
291         intel_guc_fini_wq(guc);
292 }
293
294 int intel_uc_init(struct drm_i915_private *dev_priv)
295 {
296         struct intel_guc *guc = &dev_priv->guc;
297         int ret;
298
299         if (!USES_GUC(dev_priv))
300                 return 0;
301
302         if (!HAS_GUC(dev_priv))
303                 return -ENODEV;
304
305         ret = intel_guc_init(guc);
306         if (ret)
307                 return ret;
308
309         if (USES_GUC_SUBMISSION(dev_priv)) {
310                 /*
311                  * This is stuff we need to have available at fw load time
312                  * if we are planning to enable submission later
313                  */
314                 ret = intel_guc_submission_init(guc);
315                 if (ret) {
316                         intel_guc_fini(guc);
317                         return ret;
318                 }
319         }
320
321         return 0;
322 }
323
324 void intel_uc_fini(struct drm_i915_private *dev_priv)
325 {
326         struct intel_guc *guc = &dev_priv->guc;
327
328         if (!USES_GUC(dev_priv))
329                 return;
330
331         GEM_BUG_ON(!HAS_GUC(dev_priv));
332
333         if (USES_GUC_SUBMISSION(dev_priv))
334                 intel_guc_submission_fini(guc);
335
336         intel_guc_fini(guc);
337 }
338
339 void intel_uc_sanitize(struct drm_i915_private *i915)
340 {
341         struct intel_guc *guc = &i915->guc;
342         struct intel_huc *huc = &i915->huc;
343
344         if (!USES_GUC(i915))
345                 return;
346
347         GEM_BUG_ON(!HAS_GUC(i915));
348
349         guc_disable_communication(guc);
350
351         intel_huc_sanitize(huc);
352         intel_guc_sanitize(guc);
353
354         __intel_uc_reset_hw(i915);
355 }
356
357 int intel_uc_init_hw(struct drm_i915_private *dev_priv)
358 {
359         struct intel_guc *guc = &dev_priv->guc;
360         struct intel_huc *huc = &dev_priv->huc;
361         int ret, attempts;
362
363         if (!USES_GUC(dev_priv))
364                 return 0;
365
366         GEM_BUG_ON(!HAS_GUC(dev_priv));
367
368         gen9_reset_guc_interrupts(dev_priv);
369
370         /* WaEnableuKernelHeaderValidFix:skl */
371         /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
372         if (IS_GEN9(dev_priv))
373                 attempts = 3;
374         else
375                 attempts = 1;
376
377         while (attempts--) {
378                 /*
379                  * Always reset the GuC just before (re)loading, so
380                  * that the state and timing are fairly predictable
381                  */
382                 ret = __intel_uc_reset_hw(dev_priv);
383                 if (ret)
384                         goto err_out;
385
386                 if (USES_HUC(dev_priv)) {
387                         ret = intel_huc_fw_upload(huc);
388                         if (ret)
389                                 goto err_out;
390                 }
391
392                 intel_guc_init_params(guc);
393                 ret = intel_guc_fw_upload(guc);
394                 if (ret == 0 || ret != -EAGAIN)
395                         break;
396
397                 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
398                                  "retry %d more time(s)\n", ret, attempts);
399         }
400
401         /* Did we succeded or run out of retries? */
402         if (ret)
403                 goto err_log_capture;
404
405         ret = guc_enable_communication(guc);
406         if (ret)
407                 goto err_log_capture;
408
409         if (USES_HUC(dev_priv)) {
410                 ret = intel_huc_auth(huc);
411                 if (ret)
412                         goto err_communication;
413         }
414
415         if (USES_GUC_SUBMISSION(dev_priv)) {
416                 if (i915_modparams.guc_log_level)
417                         gen9_enable_guc_interrupts(dev_priv);
418
419                 ret = intel_guc_submission_enable(guc);
420                 if (ret)
421                         goto err_interrupts;
422         }
423
424         dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
425                  guc->fw.major_ver_found, guc->fw.minor_ver_found);
426         dev_info(dev_priv->drm.dev, "GuC submission %s\n",
427                  enableddisabled(USES_GUC_SUBMISSION(dev_priv)));
428         dev_info(dev_priv->drm.dev, "HuC %s\n",
429                  enableddisabled(USES_HUC(dev_priv)));
430
431         return 0;
432
433         /*
434          * We've failed to load the firmware :(
435          */
436 err_interrupts:
437         gen9_disable_guc_interrupts(dev_priv);
438 err_communication:
439         guc_disable_communication(guc);
440 err_log_capture:
441         guc_capture_load_err_log(guc);
442 err_out:
443         /*
444          * Note that there is no fallback as either user explicitly asked for
445          * the GuC or driver default option was to run with the GuC enabled.
446          */
447         if (GEM_WARN_ON(ret == -EIO))
448                 ret = -EINVAL;
449
450         dev_err(dev_priv->drm.dev, "GuC initialization failed %d\n", ret);
451         return ret;
452 }
453
454 void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
455 {
456         struct intel_guc *guc = &dev_priv->guc;
457
458         if (!USES_GUC(dev_priv))
459                 return;
460
461         GEM_BUG_ON(!HAS_GUC(dev_priv));
462
463         if (USES_GUC_SUBMISSION(dev_priv))
464                 intel_guc_submission_disable(guc);
465
466         guc_disable_communication(guc);
467
468         if (USES_GUC_SUBMISSION(dev_priv))
469                 gen9_disable_guc_interrupts(dev_priv);
470 }
471
472 int intel_uc_suspend(struct drm_i915_private *i915)
473 {
474         struct intel_guc *guc = &i915->guc;
475         int err;
476
477         if (!USES_GUC(i915))
478                 return 0;
479
480         if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
481                 return 0;
482
483         err = intel_guc_suspend(guc);
484         if (err) {
485                 DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
486                 return err;
487         }
488
489         gen9_disable_guc_interrupts(i915);
490
491         return 0;
492 }
493
494 int intel_uc_resume(struct drm_i915_private *i915)
495 {
496         struct intel_guc *guc = &i915->guc;
497         int err;
498
499         if (!USES_GUC(i915))
500                 return 0;
501
502         if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
503                 return 0;
504
505         if (i915_modparams.guc_log_level)
506                 gen9_enable_guc_interrupts(i915);
507
508         err = intel_guc_resume(guc);
509         if (err) {
510                 DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
511                 return err;
512         }
513
514         return 0;
515 }