Merge airlied/drm-next into drm-misc-next
[sfrench/cifs-2.6.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  * intel_uc_sanitize_options - 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 void intel_uc_sanitize_options(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
168 void intel_uc_init_fw(struct drm_i915_private *dev_priv)
169 {
170         if (!USES_GUC(dev_priv))
171                 return;
172
173         if (USES_HUC(dev_priv))
174                 intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
175
176         intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw);
177 }
178
179 void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
180 {
181         if (!USES_GUC(dev_priv))
182                 return;
183
184         intel_uc_fw_fini(&dev_priv->guc.fw);
185
186         if (USES_HUC(dev_priv))
187                 intel_uc_fw_fini(&dev_priv->huc.fw);
188
189         guc_free_load_err_log(&dev_priv->guc);
190 }
191
192 /**
193  * intel_uc_init_mmio - setup uC MMIO access
194  *
195  * @dev_priv: device private
196  *
197  * Setup minimal state necessary for MMIO accesses later in the
198  * initialization sequence.
199  */
200 void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
201 {
202         intel_guc_init_send_regs(&dev_priv->guc);
203 }
204
205 static void guc_capture_load_err_log(struct intel_guc *guc)
206 {
207         if (!guc->log.vma || !i915_modparams.guc_log_level)
208                 return;
209
210         if (!guc->load_err_log)
211                 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
212
213         return;
214 }
215
216 static void guc_free_load_err_log(struct intel_guc *guc)
217 {
218         if (guc->load_err_log)
219                 i915_gem_object_put(guc->load_err_log);
220 }
221
222 static int guc_enable_communication(struct intel_guc *guc)
223 {
224         struct drm_i915_private *dev_priv = guc_to_i915(guc);
225
226         if (HAS_GUC_CT(dev_priv))
227                 return intel_guc_enable_ct(guc);
228
229         guc->send = intel_guc_send_mmio;
230         return 0;
231 }
232
233 static void guc_disable_communication(struct intel_guc *guc)
234 {
235         struct drm_i915_private *dev_priv = guc_to_i915(guc);
236
237         if (HAS_GUC_CT(dev_priv))
238                 intel_guc_disable_ct(guc);
239
240         guc->send = intel_guc_send_nop;
241 }
242
243 int intel_uc_init_misc(struct drm_i915_private *dev_priv)
244 {
245         struct intel_guc *guc = &dev_priv->guc;
246         int ret;
247
248         if (!USES_GUC(dev_priv))
249                 return 0;
250
251         ret = intel_guc_init_wq(guc);
252         if (ret) {
253                 DRM_ERROR("Couldn't allocate workqueues for GuC\n");
254                 goto err;
255         }
256
257         ret = intel_guc_log_relay_create(guc);
258         if (ret) {
259                 DRM_ERROR("Couldn't allocate relay for GuC log\n");
260                 goto err_relay;
261         }
262
263         return 0;
264
265 err_relay:
266         intel_guc_fini_wq(guc);
267 err:
268         return ret;
269 }
270
271 void intel_uc_fini_misc(struct drm_i915_private *dev_priv)
272 {
273         struct intel_guc *guc = &dev_priv->guc;
274
275         if (!USES_GUC(dev_priv))
276                 return;
277
278         intel_guc_fini_wq(guc);
279
280         intel_guc_log_relay_destroy(guc);
281 }
282
283 int intel_uc_init(struct drm_i915_private *dev_priv)
284 {
285         struct intel_guc *guc = &dev_priv->guc;
286         int ret;
287
288         if (!USES_GUC(dev_priv))
289                 return 0;
290
291         if (!HAS_GUC(dev_priv))
292                 return -ENODEV;
293
294         ret = intel_guc_init(guc);
295         if (ret)
296                 return ret;
297
298         if (USES_GUC_SUBMISSION(dev_priv)) {
299                 /*
300                  * This is stuff we need to have available at fw load time
301                  * if we are planning to enable submission later
302                  */
303                 ret = intel_guc_submission_init(guc);
304                 if (ret) {
305                         intel_guc_fini(guc);
306                         return ret;
307                 }
308         }
309
310         return 0;
311 }
312
313 void intel_uc_fini(struct drm_i915_private *dev_priv)
314 {
315         struct intel_guc *guc = &dev_priv->guc;
316
317         if (!USES_GUC(dev_priv))
318                 return;
319
320         GEM_BUG_ON(!HAS_GUC(dev_priv));
321
322         if (USES_GUC_SUBMISSION(dev_priv))
323                 intel_guc_submission_fini(guc);
324
325         intel_guc_fini(guc);
326 }
327
328 int intel_uc_init_hw(struct drm_i915_private *dev_priv)
329 {
330         struct intel_guc *guc = &dev_priv->guc;
331         struct intel_huc *huc = &dev_priv->huc;
332         int ret, attempts;
333
334         if (!USES_GUC(dev_priv))
335                 return 0;
336
337         GEM_BUG_ON(!HAS_GUC(dev_priv));
338
339         guc_disable_communication(guc);
340         gen9_reset_guc_interrupts(dev_priv);
341
342         /* init WOPCM */
343         I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
344         I915_WRITE(DMA_GUC_WOPCM_OFFSET,
345                    GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
346
347         /* WaEnableuKernelHeaderValidFix:skl */
348         /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
349         if (IS_GEN9(dev_priv))
350                 attempts = 3;
351         else
352                 attempts = 1;
353
354         while (attempts--) {
355                 /*
356                  * Always reset the GuC just before (re)loading, so
357                  * that the state and timing are fairly predictable
358                  */
359                 ret = __intel_uc_reset_hw(dev_priv);
360                 if (ret)
361                         goto err_out;
362
363                 if (USES_HUC(dev_priv)) {
364                         ret = intel_huc_init_hw(huc);
365                         if (ret)
366                                 goto err_out;
367                 }
368
369                 intel_guc_init_params(guc);
370                 ret = intel_guc_fw_upload(guc);
371                 if (ret == 0 || ret != -EAGAIN)
372                         break;
373
374                 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
375                                  "retry %d more time(s)\n", ret, attempts);
376         }
377
378         /* Did we succeded or run out of retries? */
379         if (ret)
380                 goto err_log_capture;
381
382         ret = guc_enable_communication(guc);
383         if (ret)
384                 goto err_log_capture;
385
386         if (USES_HUC(dev_priv)) {
387                 ret = intel_huc_auth(huc);
388                 if (ret)
389                         goto err_communication;
390         }
391
392         if (USES_GUC_SUBMISSION(dev_priv)) {
393                 if (i915_modparams.guc_log_level)
394                         gen9_enable_guc_interrupts(dev_priv);
395
396                 ret = intel_guc_submission_enable(guc);
397                 if (ret)
398                         goto err_interrupts;
399         }
400
401         dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
402                  guc->fw.major_ver_found, guc->fw.minor_ver_found);
403         dev_info(dev_priv->drm.dev, "GuC submission %s\n",
404                  enableddisabled(USES_GUC_SUBMISSION(dev_priv)));
405         dev_info(dev_priv->drm.dev, "HuC %s\n",
406                  enableddisabled(USES_HUC(dev_priv)));
407
408         return 0;
409
410         /*
411          * We've failed to load the firmware :(
412          */
413 err_interrupts:
414         gen9_disable_guc_interrupts(dev_priv);
415 err_communication:
416         guc_disable_communication(guc);
417 err_log_capture:
418         guc_capture_load_err_log(guc);
419 err_out:
420         /*
421          * Note that there is no fallback as either user explicitly asked for
422          * the GuC or driver default option was to run with the GuC enabled.
423          */
424         if (GEM_WARN_ON(ret == -EIO))
425                 ret = -EINVAL;
426
427         dev_err(dev_priv->drm.dev, "GuC initialization failed %d\n", ret);
428         return ret;
429 }
430
431 void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
432 {
433         struct intel_guc *guc = &dev_priv->guc;
434
435         if (!USES_GUC(dev_priv))
436                 return;
437
438         GEM_BUG_ON(!HAS_GUC(dev_priv));
439
440         if (USES_GUC_SUBMISSION(dev_priv))
441                 intel_guc_submission_disable(guc);
442
443         guc_disable_communication(guc);
444
445         if (USES_GUC_SUBMISSION(dev_priv))
446                 gen9_disable_guc_interrupts(dev_priv);
447 }