2 * Copyright © 2016 Intel Corporation
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:
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
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
26 #include "intel_guc_submission.h"
27 #include "intel_guc.h"
30 /* Reset GuC providing us with fresh state for both GuC and HuC.
32 static int __intel_uc_reset_hw(struct drm_i915_private
*dev_priv
)
37 ret
= intel_reset_guc(dev_priv
);
39 DRM_ERROR("Failed to reset GuC, ret = %d\n", ret
);
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",
51 static int __get_platform_enable_guc(struct drm_i915_private
*dev_priv
)
53 struct intel_uc_fw
*guc_fw
= &dev_priv
->guc
.fw
;
54 struct intel_uc_fw
*huc_fw
= &dev_priv
->huc
.fw
;
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
;
63 /* Any platform specific fine-tuning can be done here */
69 * intel_uc_sanitize_options - sanitize uC related modparam options
70 * @dev_priv: device private
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.
78 void intel_uc_sanitize_options(struct drm_i915_private
*dev_priv
)
80 struct intel_uc_fw
*guc_fw
= &dev_priv
->guc
.fw
;
81 struct intel_uc_fw
*huc_fw
= &dev_priv
->huc
.fw
;
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
);
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()));
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" :
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" :
108 /* Make sure that sanitization was done */
109 GEM_BUG_ON(i915_modparams
.enable_guc
< 0);
112 void intel_uc_init_early(struct drm_i915_private
*dev_priv
)
114 intel_guc_init_early(&dev_priv
->guc
);
115 intel_huc_init_early(&dev_priv
->huc
);
118 void intel_uc_init_fw(struct drm_i915_private
*dev_priv
)
120 if (!USES_GUC(dev_priv
))
123 if (USES_HUC(dev_priv
))
124 intel_uc_fw_fetch(dev_priv
, &dev_priv
->huc
.fw
);
126 intel_uc_fw_fetch(dev_priv
, &dev_priv
->guc
.fw
);
129 void intel_uc_fini_fw(struct drm_i915_private
*dev_priv
)
131 if (!USES_GUC(dev_priv
))
134 intel_uc_fw_fini(&dev_priv
->guc
.fw
);
136 if (USES_HUC(dev_priv
))
137 intel_uc_fw_fini(&dev_priv
->huc
.fw
);
141 * intel_uc_init_mmio - setup uC MMIO access
143 * @dev_priv: device private
145 * Setup minimal state necessary for MMIO accesses later in the
146 * initialization sequence.
148 void intel_uc_init_mmio(struct drm_i915_private
*dev_priv
)
150 intel_guc_init_send_regs(&dev_priv
->guc
);
153 static void guc_capture_load_err_log(struct intel_guc
*guc
)
155 if (!guc
->log
.vma
|| i915_modparams
.guc_log_level
< 0)
158 if (!guc
->load_err_log
)
159 guc
->load_err_log
= i915_gem_object_get(guc
->log
.vma
->obj
);
164 static void guc_free_load_err_log(struct intel_guc
*guc
)
166 if (guc
->load_err_log
)
167 i915_gem_object_put(guc
->load_err_log
);
170 static int guc_enable_communication(struct intel_guc
*guc
)
172 struct drm_i915_private
*dev_priv
= guc_to_i915(guc
);
174 if (HAS_GUC_CT(dev_priv
))
175 return intel_guc_enable_ct(guc
);
177 guc
->send
= intel_guc_send_mmio
;
181 static void guc_disable_communication(struct intel_guc
*guc
)
183 struct drm_i915_private
*dev_priv
= guc_to_i915(guc
);
185 if (HAS_GUC_CT(dev_priv
))
186 intel_guc_disable_ct(guc
);
188 guc
->send
= intel_guc_send_nop
;
191 int intel_uc_init_wq(struct drm_i915_private
*dev_priv
)
195 if (!USES_GUC(dev_priv
))
198 ret
= intel_guc_init_wq(&dev_priv
->guc
);
200 DRM_ERROR("Couldn't allocate workqueues for GuC\n");
207 void intel_uc_fini_wq(struct drm_i915_private
*dev_priv
)
209 if (!USES_GUC(dev_priv
))
212 intel_guc_fini_wq(&dev_priv
->guc
);
215 int intel_uc_init(struct drm_i915_private
*dev_priv
)
217 struct intel_guc
*guc
= &dev_priv
->guc
;
220 if (!USES_GUC(dev_priv
))
223 if (!HAS_GUC(dev_priv
))
226 ret
= intel_guc_init(guc
);
230 if (USES_GUC_SUBMISSION(dev_priv
)) {
232 * This is stuff we need to have available at fw load time
233 * if we are planning to enable submission later
235 ret
= intel_guc_submission_init(guc
);
245 void intel_uc_fini(struct drm_i915_private
*dev_priv
)
247 struct intel_guc
*guc
= &dev_priv
->guc
;
249 if (!USES_GUC(dev_priv
))
252 GEM_BUG_ON(!HAS_GUC(dev_priv
));
254 if (USES_GUC_SUBMISSION(dev_priv
))
255 intel_guc_submission_fini(guc
);
260 int intel_uc_init_hw(struct drm_i915_private
*dev_priv
)
262 struct intel_guc
*guc
= &dev_priv
->guc
;
263 struct intel_huc
*huc
= &dev_priv
->huc
;
266 if (!USES_GUC(dev_priv
))
269 GEM_BUG_ON(!HAS_GUC(dev_priv
));
271 guc_disable_communication(guc
);
272 gen9_reset_guc_interrupts(dev_priv
);
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
);
279 /* WaEnableuKernelHeaderValidFix:skl */
280 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
281 if (IS_GEN9(dev_priv
))
288 * Always reset the GuC just before (re)loading, so
289 * that the state and timing are fairly predictable
291 ret
= __intel_uc_reset_hw(dev_priv
);
295 if (USES_HUC(dev_priv
)) {
296 ret
= intel_huc_init_hw(huc
);
301 intel_guc_init_params(guc
);
302 ret
= intel_guc_fw_upload(guc
);
303 if (ret
== 0 || ret
!= -EAGAIN
)
306 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
307 "retry %d more time(s)\n", ret
, attempts
);
310 /* Did we succeded or run out of retries? */
312 goto err_log_capture
;
314 ret
= guc_enable_communication(guc
);
316 goto err_log_capture
;
318 if (USES_HUC(dev_priv
)) {
319 ret
= intel_huc_auth(huc
);
321 goto err_communication
;
324 if (USES_GUC_SUBMISSION(dev_priv
)) {
325 if (i915_modparams
.guc_log_level
>= 0)
326 gen9_enable_guc_interrupts(dev_priv
);
328 ret
= intel_guc_submission_enable(guc
);
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
)));
343 * We've failed to load the firmware :(
346 gen9_disable_guc_interrupts(dev_priv
);
348 guc_disable_communication(guc
);
350 guc_capture_load_err_log(guc
);
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.
356 if (GEM_WARN_ON(ret
== -EIO
))
359 dev_err(dev_priv
->drm
.dev
, "GuC initialization failed %d\n", ret
);
363 void intel_uc_fini_hw(struct drm_i915_private
*dev_priv
)
365 struct intel_guc
*guc
= &dev_priv
->guc
;
367 guc_free_load_err_log(guc
);
369 if (!USES_GUC(dev_priv
))
372 GEM_BUG_ON(!HAS_GUC(dev_priv
));
374 if (USES_GUC_SUBMISSION(dev_priv
))
375 intel_guc_submission_disable(guc
);
377 guc_disable_communication(guc
);
379 if (USES_GUC_SUBMISSION(dev_priv
))
380 gen9_disable_guc_interrupts(dev_priv
);