Merge branch 'x86-pti-for-linus' 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         GEM_BUG_ON(!HAS_GUC(dev_priv));
213
214         intel_guc_fini_wq(&dev_priv->guc);
215 }
216
217 int intel_uc_init(struct drm_i915_private *dev_priv)
218 {
219         struct intel_guc *guc = &dev_priv->guc;
220         int ret;
221
222         if (!USES_GUC(dev_priv))
223                 return 0;
224
225         if (!HAS_GUC(dev_priv))
226                 return -ENODEV;
227
228         ret = intel_guc_init(guc);
229         if (ret)
230                 return ret;
231
232         if (USES_GUC_SUBMISSION(dev_priv)) {
233                 /*
234                  * This is stuff we need to have available at fw load time
235                  * if we are planning to enable submission later
236                  */
237                 ret = intel_guc_submission_init(guc);
238                 if (ret) {
239                         intel_guc_fini(guc);
240                         return ret;
241                 }
242         }
243
244         return 0;
245 }
246
247 void intel_uc_fini(struct drm_i915_private *dev_priv)
248 {
249         struct intel_guc *guc = &dev_priv->guc;
250
251         if (!USES_GUC(dev_priv))
252                 return;
253
254         GEM_BUG_ON(!HAS_GUC(dev_priv));
255
256         if (USES_GUC_SUBMISSION(dev_priv))
257                 intel_guc_submission_fini(guc);
258
259         intel_guc_fini(guc);
260 }
261
262 int intel_uc_init_hw(struct drm_i915_private *dev_priv)
263 {
264         struct intel_guc *guc = &dev_priv->guc;
265         struct intel_huc *huc = &dev_priv->huc;
266         int ret, attempts;
267
268         if (!USES_GUC(dev_priv))
269                 return 0;
270
271         GEM_BUG_ON(!HAS_GUC(dev_priv));
272
273         guc_disable_communication(guc);
274         gen9_reset_guc_interrupts(dev_priv);
275
276         /* init WOPCM */
277         I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
278         I915_WRITE(DMA_GUC_WOPCM_OFFSET,
279                    GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
280
281         /* WaEnableuKernelHeaderValidFix:skl */
282         /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
283         if (IS_GEN9(dev_priv))
284                 attempts = 3;
285         else
286                 attempts = 1;
287
288         while (attempts--) {
289                 /*
290                  * Always reset the GuC just before (re)loading, so
291                  * that the state and timing are fairly predictable
292                  */
293                 ret = __intel_uc_reset_hw(dev_priv);
294                 if (ret)
295                         goto err_out;
296
297                 if (USES_HUC(dev_priv)) {
298                         ret = intel_huc_init_hw(huc);
299                         if (ret)
300                                 goto err_out;
301                 }
302
303                 intel_guc_init_params(guc);
304                 ret = intel_guc_fw_upload(guc);
305                 if (ret == 0 || ret != -EAGAIN)
306                         break;
307
308                 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
309                                  "retry %d more time(s)\n", ret, attempts);
310         }
311
312         /* Did we succeded or run out of retries? */
313         if (ret)
314                 goto err_log_capture;
315
316         ret = guc_enable_communication(guc);
317         if (ret)
318                 goto err_log_capture;
319
320         if (USES_HUC(dev_priv)) {
321                 ret = intel_huc_auth(huc);
322                 if (ret)
323                         goto err_communication;
324         }
325
326         if (USES_GUC_SUBMISSION(dev_priv)) {
327                 if (i915_modparams.guc_log_level >= 0)
328                         gen9_enable_guc_interrupts(dev_priv);
329
330                 ret = intel_guc_submission_enable(guc);
331                 if (ret)
332                         goto err_interrupts;
333         }
334
335         dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
336                  guc->fw.major_ver_found, guc->fw.minor_ver_found);
337         dev_info(dev_priv->drm.dev, "GuC submission %s\n",
338                  enableddisabled(USES_GUC_SUBMISSION(dev_priv)));
339         dev_info(dev_priv->drm.dev, "HuC %s\n",
340                  enableddisabled(USES_HUC(dev_priv)));
341
342         return 0;
343
344         /*
345          * We've failed to load the firmware :(
346          */
347 err_interrupts:
348         gen9_disable_guc_interrupts(dev_priv);
349 err_communication:
350         guc_disable_communication(guc);
351 err_log_capture:
352         guc_capture_load_err_log(guc);
353 err_out:
354         /*
355          * Note that there is no fallback as either user explicitly asked for
356          * the GuC or driver default option was to run with the GuC enabled.
357          */
358         if (GEM_WARN_ON(ret == -EIO))
359                 ret = -EINVAL;
360
361         dev_err(dev_priv->drm.dev, "GuC initialization failed %d\n", ret);
362         return ret;
363 }
364
365 void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
366 {
367         struct intel_guc *guc = &dev_priv->guc;
368
369         guc_free_load_err_log(guc);
370
371         if (!USES_GUC(dev_priv))
372                 return;
373
374         GEM_BUG_ON(!HAS_GUC(dev_priv));
375
376         if (USES_GUC_SUBMISSION(dev_priv))
377                 intel_guc_submission_disable(guc);
378
379         guc_disable_communication(guc);
380
381         if (USES_GUC_SUBMISSION(dev_priv))
382                 gen9_disable_guc_interrupts(dev_priv);
383 }