Merge tag 'gfs2-4.16.rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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 /* Reset GuC providing us with fresh state for both GuC and HuC.
31  */
32 static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
33 {
34         int ret;
35         u32 guc_status;
36
37         ret = intel_reset_guc(dev_priv);
38         if (ret) {
39                 DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
40                 return ret;
41         }
42
43         guc_status = I915_READ(GUC_STATUS);
44         WARN(!(guc_status & GS_MIA_IN_RESET),
45              "GuC status: 0x%x, MIA core expected to be in reset\n",
46              guc_status);
47
48         return ret;
49 }
50
51 static int __get_platform_enable_guc(struct drm_i915_private *dev_priv)
52 {
53         struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
54         struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
55         int enable_guc = 0;
56
57         /* Default is to enable GuC/HuC if we know their firmwares */
58         if (intel_uc_fw_is_selected(guc_fw))
59                 enable_guc |= ENABLE_GUC_SUBMISSION;
60         if (intel_uc_fw_is_selected(huc_fw))
61                 enable_guc |= ENABLE_GUC_LOAD_HUC;
62
63         /* Any platform specific fine-tuning can be done here */
64
65         return enable_guc;
66 }
67
68 /**
69  * intel_uc_sanitize_options - sanitize uC related modparam options
70  * @dev_priv: device private
71  *
72  * In case of "enable_guc" option this function will attempt to modify
73  * it only if it was initially set to "auto(-1)". Default value for this
74  * modparam varies between platforms and it is hardcoded in driver code.
75  * Any other modparam value is only monitored against availability of the
76  * related hardware or firmware definitions.
77  */
78 void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
79 {
80         struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
81         struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
82
83         /* A negative value means "use platform default" */
84         if (i915_modparams.enable_guc < 0)
85                 i915_modparams.enable_guc = __get_platform_enable_guc(dev_priv);
86
87         DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n",
88                          i915_modparams.enable_guc,
89                          yesno(intel_uc_is_using_guc_submission()),
90                          yesno(intel_uc_is_using_huc()));
91
92         /* Verify GuC firmware availability */
93         if (intel_uc_is_using_guc() && !intel_uc_fw_is_selected(guc_fw)) {
94                 DRM_WARN("Incompatible option detected: enable_guc=%d, %s!\n",
95                          i915_modparams.enable_guc,
96                          !HAS_GUC(dev_priv) ? "no GuC hardware" :
97                                               "no GuC firmware");
98         }
99
100         /* Verify HuC firmware availability */
101         if (intel_uc_is_using_huc() && !intel_uc_fw_is_selected(huc_fw)) {
102                 DRM_WARN("Incompatible option detected: enable_guc=%d, %s!\n",
103                          i915_modparams.enable_guc,
104                          !HAS_HUC(dev_priv) ? "no HuC hardware" :
105                                               "no HuC firmware");
106         }
107
108         /* Make sure that sanitization was done */
109         GEM_BUG_ON(i915_modparams.enable_guc < 0);
110 }
111
112 void intel_uc_init_early(struct drm_i915_private *dev_priv)
113 {
114         intel_guc_init_early(&dev_priv->guc);
115         intel_huc_init_early(&dev_priv->huc);
116 }
117
118 void intel_uc_init_fw(struct drm_i915_private *dev_priv)
119 {
120         if (!USES_GUC(dev_priv))
121                 return;
122
123         if (USES_HUC(dev_priv))
124                 intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
125
126         intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw);
127 }
128
129 void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
130 {
131         if (!USES_GUC(dev_priv))
132                 return;
133
134         intel_uc_fw_fini(&dev_priv->guc.fw);
135
136         if (USES_HUC(dev_priv))
137                 intel_uc_fw_fini(&dev_priv->huc.fw);
138 }
139
140 /**
141  * intel_uc_init_mmio - setup uC MMIO access
142  *
143  * @dev_priv: device private
144  *
145  * Setup minimal state necessary for MMIO accesses later in the
146  * initialization sequence.
147  */
148 void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
149 {
150         intel_guc_init_send_regs(&dev_priv->guc);
151 }
152
153 static void guc_capture_load_err_log(struct intel_guc *guc)
154 {
155         if (!guc->log.vma || i915_modparams.guc_log_level < 0)
156                 return;
157
158         if (!guc->load_err_log)
159                 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
160
161         return;
162 }
163
164 static void guc_free_load_err_log(struct intel_guc *guc)
165 {
166         if (guc->load_err_log)
167                 i915_gem_object_put(guc->load_err_log);
168 }
169
170 static int guc_enable_communication(struct intel_guc *guc)
171 {
172         struct drm_i915_private *dev_priv = guc_to_i915(guc);
173
174         if (HAS_GUC_CT(dev_priv))
175                 return intel_guc_enable_ct(guc);
176
177         guc->send = intel_guc_send_mmio;
178         return 0;
179 }
180
181 static void guc_disable_communication(struct intel_guc *guc)
182 {
183         struct drm_i915_private *dev_priv = guc_to_i915(guc);
184
185         if (HAS_GUC_CT(dev_priv))
186                 intel_guc_disable_ct(guc);
187
188         guc->send = intel_guc_send_nop;
189 }
190
191 int intel_uc_init_wq(struct drm_i915_private *dev_priv)
192 {
193         int ret;
194
195         if (!USES_GUC(dev_priv))
196                 return 0;
197
198         ret = intel_guc_init_wq(&dev_priv->guc);
199         if (ret) {
200                 DRM_ERROR("Couldn't allocate workqueues for GuC\n");
201                 return ret;
202         }
203
204         return 0;
205 }
206
207 void intel_uc_fini_wq(struct drm_i915_private *dev_priv)
208 {
209         if (!USES_GUC(dev_priv))
210                 return;
211
212         intel_guc_fini_wq(&dev_priv->guc);
213 }
214
215 int intel_uc_init(struct drm_i915_private *dev_priv)
216 {
217         struct intel_guc *guc = &dev_priv->guc;
218         int ret;
219
220         if (!USES_GUC(dev_priv))
221                 return 0;
222
223         if (!HAS_GUC(dev_priv))
224                 return -ENODEV;
225
226         ret = intel_guc_init(guc);
227         if (ret)
228                 return ret;
229
230         if (USES_GUC_SUBMISSION(dev_priv)) {
231                 /*
232                  * This is stuff we need to have available at fw load time
233                  * if we are planning to enable submission later
234                  */
235                 ret = intel_guc_submission_init(guc);
236                 if (ret) {
237                         intel_guc_fini(guc);
238                         return ret;
239                 }
240         }
241
242         return 0;
243 }
244
245 void intel_uc_fini(struct drm_i915_private *dev_priv)
246 {
247         struct intel_guc *guc = &dev_priv->guc;
248
249         if (!USES_GUC(dev_priv))
250                 return;
251
252         GEM_BUG_ON(!HAS_GUC(dev_priv));
253
254         if (USES_GUC_SUBMISSION(dev_priv))
255                 intel_guc_submission_fini(guc);
256
257         intel_guc_fini(guc);
258 }
259
260 int intel_uc_init_hw(struct drm_i915_private *dev_priv)
261 {
262         struct intel_guc *guc = &dev_priv->guc;
263         struct intel_huc *huc = &dev_priv->huc;
264         int ret, attempts;
265
266         if (!USES_GUC(dev_priv))
267                 return 0;
268
269         GEM_BUG_ON(!HAS_GUC(dev_priv));
270
271         guc_disable_communication(guc);
272         gen9_reset_guc_interrupts(dev_priv);
273
274         /* init WOPCM */
275         I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
276         I915_WRITE(DMA_GUC_WOPCM_OFFSET,
277                    GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
278
279         /* WaEnableuKernelHeaderValidFix:skl */
280         /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
281         if (IS_GEN9(dev_priv))
282                 attempts = 3;
283         else
284                 attempts = 1;
285
286         while (attempts--) {
287                 /*
288                  * Always reset the GuC just before (re)loading, so
289                  * that the state and timing are fairly predictable
290                  */
291                 ret = __intel_uc_reset_hw(dev_priv);
292                 if (ret)
293                         goto err_out;
294
295                 if (USES_HUC(dev_priv)) {
296                         ret = intel_huc_init_hw(huc);
297                         if (ret)
298                                 goto err_out;
299                 }
300
301                 intel_guc_init_params(guc);
302                 ret = intel_guc_fw_upload(guc);
303                 if (ret == 0 || ret != -EAGAIN)
304                         break;
305
306                 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
307                                  "retry %d more time(s)\n", ret, attempts);
308         }
309
310         /* Did we succeded or run out of retries? */
311         if (ret)
312                 goto err_log_capture;
313
314         ret = guc_enable_communication(guc);
315         if (ret)
316                 goto err_log_capture;
317
318         if (USES_HUC(dev_priv)) {
319                 ret = intel_huc_auth(huc);
320                 if (ret)
321                         goto err_communication;
322         }
323
324         if (USES_GUC_SUBMISSION(dev_priv)) {
325                 if (i915_modparams.guc_log_level >= 0)
326                         gen9_enable_guc_interrupts(dev_priv);
327
328                 ret = intel_guc_submission_enable(guc);
329                 if (ret)
330                         goto err_interrupts;
331         }
332
333         dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
334                  guc->fw.major_ver_found, guc->fw.minor_ver_found);
335         dev_info(dev_priv->drm.dev, "GuC submission %s\n",
336                  enableddisabled(USES_GUC_SUBMISSION(dev_priv)));
337         dev_info(dev_priv->drm.dev, "HuC %s\n",
338                  enableddisabled(USES_HUC(dev_priv)));
339
340         return 0;
341
342         /*
343          * We've failed to load the firmware :(
344          */
345 err_interrupts:
346         gen9_disable_guc_interrupts(dev_priv);
347 err_communication:
348         guc_disable_communication(guc);
349 err_log_capture:
350         guc_capture_load_err_log(guc);
351 err_out:
352         /*
353          * Note that there is no fallback as either user explicitly asked for
354          * the GuC or driver default option was to run with the GuC enabled.
355          */
356         if (GEM_WARN_ON(ret == -EIO))
357                 ret = -EINVAL;
358
359         dev_err(dev_priv->drm.dev, "GuC initialization failed %d\n", ret);
360         return ret;
361 }
362
363 void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
364 {
365         struct intel_guc *guc = &dev_priv->guc;
366
367         guc_free_load_err_log(guc);
368
369         if (!USES_GUC(dev_priv))
370                 return;
371
372         GEM_BUG_ON(!HAS_GUC(dev_priv));
373
374         if (USES_GUC_SUBMISSION(dev_priv))
375                 intel_guc_submission_disable(guc);
376
377         guc_disable_communication(guc);
378
379         if (USES_GUC_SUBMISSION(dev_priv))
380                 gen9_disable_guc_interrupts(dev_priv);
381 }