]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/i915/intel_uc.c
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
27 #include "i915_guc_submission.h"
29 /* Reset GuC providing us with fresh state for both GuC and HuC.
31 static int __intel_uc_reset_hw(struct drm_i915_private
*dev_priv
)
36 ret
= intel_guc_reset(dev_priv
);
38 DRM_ERROR("GuC reset failed, ret = %d\n", ret
);
42 guc_status
= I915_READ(GUC_STATUS
);
43 WARN(!(guc_status
& GS_MIA_IN_RESET
),
44 "GuC status: 0x%x, MIA core expected to be in reset\n",
50 void intel_uc_sanitize_options(struct drm_i915_private
*dev_priv
)
52 if (!HAS_GUC(dev_priv
)) {
53 if (i915_modparams
.enable_guc_loading
> 0 ||
54 i915_modparams
.enable_guc_submission
> 0)
55 DRM_INFO("Ignoring GuC options, no hardware\n");
57 i915_modparams
.enable_guc_loading
= 0;
58 i915_modparams
.enable_guc_submission
= 0;
62 /* A negative value means "use platform default" */
63 if (i915_modparams
.enable_guc_loading
< 0)
64 i915_modparams
.enable_guc_loading
= HAS_GUC_UCODE(dev_priv
);
66 /* Verify firmware version */
67 if (i915_modparams
.enable_guc_loading
) {
68 if (HAS_HUC_UCODE(dev_priv
))
69 intel_huc_select_fw(&dev_priv
->huc
);
71 if (intel_guc_select_fw(&dev_priv
->guc
))
72 i915_modparams
.enable_guc_loading
= 0;
75 /* Can't enable guc submission without guc loaded */
76 if (!i915_modparams
.enable_guc_loading
)
77 i915_modparams
.enable_guc_submission
= 0;
79 /* A negative value means "use platform default" */
80 if (i915_modparams
.enable_guc_submission
< 0)
81 i915_modparams
.enable_guc_submission
= HAS_GUC_SCHED(dev_priv
);
84 void intel_uc_init_early(struct drm_i915_private
*dev_priv
)
86 intel_guc_init_early(&dev_priv
->guc
);
89 void intel_uc_init_fw(struct drm_i915_private
*dev_priv
)
91 intel_uc_fw_fetch(dev_priv
, &dev_priv
->huc
.fw
);
92 intel_uc_fw_fetch(dev_priv
, &dev_priv
->guc
.fw
);
95 void intel_uc_fini_fw(struct drm_i915_private
*dev_priv
)
97 intel_uc_fw_fini(&dev_priv
->guc
.fw
);
98 intel_uc_fw_fini(&dev_priv
->huc
.fw
);
102 * intel_uc_init_mmio - setup uC MMIO access
104 * @dev_priv: device private
106 * Setup minimal state necessary for MMIO accesses later in the
107 * initialization sequence.
109 void intel_uc_init_mmio(struct drm_i915_private
*dev_priv
)
111 intel_guc_init_send_regs(&dev_priv
->guc
);
114 static void guc_capture_load_err_log(struct intel_guc
*guc
)
116 if (!guc
->log
.vma
|| i915_modparams
.guc_log_level
< 0)
119 if (!guc
->load_err_log
)
120 guc
->load_err_log
= i915_gem_object_get(guc
->log
.vma
->obj
);
125 static void guc_free_load_err_log(struct intel_guc
*guc
)
127 if (guc
->load_err_log
)
128 i915_gem_object_put(guc
->load_err_log
);
131 static int guc_enable_communication(struct intel_guc
*guc
)
133 struct drm_i915_private
*dev_priv
= guc_to_i915(guc
);
135 if (HAS_GUC_CT(dev_priv
))
136 return intel_guc_enable_ct(guc
);
138 guc
->send
= intel_guc_send_mmio
;
142 static void guc_disable_communication(struct intel_guc
*guc
)
144 struct drm_i915_private
*dev_priv
= guc_to_i915(guc
);
146 if (HAS_GUC_CT(dev_priv
))
147 intel_guc_disable_ct(guc
);
149 guc
->send
= intel_guc_send_nop
;
152 int intel_uc_init_hw(struct drm_i915_private
*dev_priv
)
154 struct intel_guc
*guc
= &dev_priv
->guc
;
157 if (!i915_modparams
.enable_guc_loading
)
160 guc_disable_communication(guc
);
161 gen9_reset_guc_interrupts(dev_priv
);
163 /* We need to notify the guc whenever we change the GGTT */
164 i915_ggtt_enable_guc(dev_priv
);
166 if (i915_modparams
.enable_guc_submission
) {
168 * This is stuff we need to have available at fw load time
169 * if we are planning to enable submission later
171 ret
= i915_guc_submission_init(dev_priv
);
177 I915_WRITE(GUC_WOPCM_SIZE
, intel_guc_wopcm_size(dev_priv
));
178 I915_WRITE(DMA_GUC_WOPCM_OFFSET
,
179 GUC_WOPCM_OFFSET_VALUE
| HUC_LOADING_AGENT_GUC
);
181 /* WaEnableuKernelHeaderValidFix:skl */
182 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
183 if (IS_GEN9(dev_priv
))
190 * Always reset the GuC just before (re)loading, so
191 * that the state and timing are fairly predictable
193 ret
= __intel_uc_reset_hw(dev_priv
);
197 intel_huc_init_hw(&dev_priv
->huc
);
198 ret
= intel_guc_init_hw(&dev_priv
->guc
);
199 if (ret
== 0 || ret
!= -EAGAIN
)
202 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
203 "retry %d more time(s)\n", ret
, attempts
);
206 /* Did we succeded or run out of retries? */
208 goto err_log_capture
;
210 ret
= guc_enable_communication(guc
);
212 goto err_log_capture
;
214 intel_huc_auth(&dev_priv
->huc
);
215 if (i915_modparams
.enable_guc_submission
) {
216 if (i915_modparams
.guc_log_level
>= 0)
217 gen9_enable_guc_interrupts(dev_priv
);
219 ret
= i915_guc_submission_enable(dev_priv
);
227 * We've failed to load the firmware :(
229 * Decide whether to disable GuC submission and fall back to
230 * execlist mode, and whether to hide the error by returning
231 * zero or to return -EIO, which the caller will treat as a
232 * nonfatal error (i.e. it doesn't prevent driver load, but
233 * marks the GPU as wedged until reset).
236 guc_disable_communication(guc
);
237 gen9_disable_guc_interrupts(dev_priv
);
239 guc_capture_load_err_log(guc
);
241 if (i915_modparams
.enable_guc_submission
)
242 i915_guc_submission_fini(dev_priv
);
244 i915_ggtt_disable_guc(dev_priv
);
246 DRM_ERROR("GuC init failed\n");
247 if (i915_modparams
.enable_guc_loading
> 1 ||
248 i915_modparams
.enable_guc_submission
> 1)
253 if (i915_modparams
.enable_guc_submission
) {
254 i915_modparams
.enable_guc_submission
= 0;
255 DRM_NOTE("Falling back from GuC submission to execlist mode\n");
258 i915_modparams
.enable_guc_loading
= 0;
259 DRM_NOTE("GuC firmware loading disabled\n");
264 void intel_uc_fini_hw(struct drm_i915_private
*dev_priv
)
266 guc_free_load_err_log(&dev_priv
->guc
);
268 if (!i915_modparams
.enable_guc_loading
)
271 if (i915_modparams
.enable_guc_submission
)
272 i915_guc_submission_disable(dev_priv
);
274 guc_disable_communication(&dev_priv
->guc
);
276 if (i915_modparams
.enable_guc_submission
) {
277 gen9_disable_guc_interrupts(dev_priv
);
278 i915_guc_submission_fini(dev_priv
);
281 i915_ggtt_disable_guc(dev_priv
);