blob: cb9f13f54a80bfe9ffc1249ec6c6b5eda073c816 [file] [log] [blame]
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +01001/*
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 "i915_drv.h"
26#include "intel_uc.h"
Michal Wajdeczko9f436c42017-10-04 18:13:40 +000027#include "i915_guc_submission.h"
Arkadiusz Hiler4c0fed72017-03-14 15:28:08 +010028#include <linux/firmware.h>
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010029
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +010030/* Reset GuC providing us with fresh state for both GuC and HuC.
31 */
32static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
33{
34 int ret;
35 u32 guc_status;
36
37 ret = intel_guc_reset(dev_priv);
38 if (ret) {
39 DRM_ERROR("GuC reset failed, 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
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010051void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
52{
53 if (!HAS_GUC(dev_priv)) {
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000054 if (i915_modparams.enable_guc_loading > 0 ||
55 i915_modparams.enable_guc_submission > 0)
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000056 DRM_INFO("Ignoring GuC options, no hardware\n");
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010057
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000058 i915_modparams.enable_guc_loading = 0;
59 i915_modparams.enable_guc_submission = 0;
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000060 return;
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010061 }
Arkadiusz Hilerb551f612017-03-14 15:28:13 +010062
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000063 /* A negative value means "use platform default" */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000064 if (i915_modparams.enable_guc_loading < 0)
65 i915_modparams.enable_guc_loading = HAS_GUC_UCODE(dev_priv);
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000066
67 /* Verify firmware version */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000068 if (i915_modparams.enable_guc_loading) {
Arkadiusz Hilerb551f612017-03-14 15:28:13 +010069 if (HAS_HUC_UCODE(dev_priv))
70 intel_huc_select_fw(&dev_priv->huc);
71
72 if (intel_guc_select_fw(&dev_priv->guc))
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000073 i915_modparams.enable_guc_loading = 0;
Arkadiusz Hilerb551f612017-03-14 15:28:13 +010074 }
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000075
76 /* Can't enable guc submission without guc loaded */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000077 if (!i915_modparams.enable_guc_loading)
78 i915_modparams.enable_guc_submission = 0;
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000079
80 /* A negative value means "use platform default" */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000081 if (i915_modparams.enable_guc_submission < 0)
82 i915_modparams.enable_guc_submission = HAS_GUC_SCHED(dev_priv);
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010083}
84
Michal Wajdeczko3af7a9c2017-10-04 15:33:27 +000085void intel_uc_init_early(struct drm_i915_private *dev_priv)
86{
Michal Wajdeczko9bf384c2017-10-04 18:13:41 +000087 intel_guc_init_early(&dev_priv->guc);
Michal Wajdeczko3af7a9c2017-10-04 15:33:27 +000088}
89
Arkadiusz Hiler29ad6a32017-03-14 15:28:09 +010090void intel_uc_init_fw(struct drm_i915_private *dev_priv)
91{
Michal Wajdeczkoa16b4312017-10-04 15:33:25 +000092 intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
93 intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw);
Arkadiusz Hiler29ad6a32017-03-14 15:28:09 +010094}
95
Oscar Mateo3950bf32017-03-22 10:39:46 -070096void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
97{
Michal Wajdeczkoa16b4312017-10-04 15:33:25 +000098 intel_uc_fw_fini(&dev_priv->guc.fw);
99 intel_uc_fw_fini(&dev_priv->huc.fw);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700100}
101
Sagar Arun Kamble1fc556f2017-10-04 15:33:24 +0000102/**
103 * intel_uc_init_mmio - setup uC MMIO access
104 *
105 * @dev_priv: device private
106 *
107 * Setup minimal state necessary for MMIO accesses later in the
108 * initialization sequence.
109 */
110void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
111{
Michal Wajdeczko9bf384c2017-10-04 18:13:41 +0000112 intel_guc_init_send_regs(&dev_priv->guc);
Sagar Arun Kamble1fc556f2017-10-04 15:33:24 +0000113}
114
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700115static void guc_capture_load_err_log(struct intel_guc *guc)
116{
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000117 if (!guc->log.vma || i915_modparams.guc_log_level < 0)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700118 return;
119
120 if (!guc->load_err_log)
121 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
122
123 return;
124}
125
126static void guc_free_load_err_log(struct intel_guc *guc)
127{
128 if (guc->load_err_log)
129 i915_gem_object_put(guc->load_err_log);
130}
131
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000132static int guc_enable_communication(struct intel_guc *guc)
133{
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000134 struct drm_i915_private *dev_priv = guc_to_i915(guc);
135
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000136 if (HAS_GUC_CT(dev_priv))
137 return intel_guc_enable_ct(guc);
138
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000139 guc->send = intel_guc_send_mmio;
140 return 0;
141}
142
143static void guc_disable_communication(struct intel_guc *guc)
144{
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000145 struct drm_i915_private *dev_priv = guc_to_i915(guc);
146
147 if (HAS_GUC_CT(dev_priv))
148 intel_guc_disable_ct(guc);
149
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000150 guc->send = intel_guc_send_nop;
151}
152
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100153int intel_uc_init_hw(struct drm_i915_private *dev_priv)
154{
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000155 struct intel_guc *guc = &dev_priv->guc;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100156 int ret, attempts;
157
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000158 if (!i915_modparams.enable_guc_loading)
Oscar Mateob8991402017-03-28 09:53:47 -0700159 return 0;
160
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000161 guc_disable_communication(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100162 gen9_reset_guc_interrupts(dev_priv);
163
164 /* We need to notify the guc whenever we change the GGTT */
165 i915_ggtt_enable_guc(dev_priv);
166
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000167 if (i915_modparams.enable_guc_submission) {
Oscar Mateo397fce82017-03-22 10:39:52 -0700168 /*
169 * This is stuff we need to have available at fw load time
170 * if we are planning to enable submission later
171 */
172 ret = i915_guc_submission_init(dev_priv);
173 if (ret)
174 goto err_guc;
175 }
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100176
daniele.ceraolospurio@intel.com13f6c712017-04-06 17:18:52 -0700177 /* init WOPCM */
178 I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
179 I915_WRITE(DMA_GUC_WOPCM_OFFSET,
180 GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
181
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100182 /* WaEnableuKernelHeaderValidFix:skl */
183 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
184 if (IS_GEN9(dev_priv))
185 attempts = 3;
186 else
187 attempts = 1;
188
189 while (attempts--) {
190 /*
191 * Always reset the GuC just before (re)loading, so
192 * that the state and timing are fairly predictable
193 */
194 ret = __intel_uc_reset_hw(dev_priv);
195 if (ret)
196 goto err_submission;
197
198 intel_huc_init_hw(&dev_priv->huc);
199 ret = intel_guc_init_hw(&dev_priv->guc);
200 if (ret == 0 || ret != -EAGAIN)
201 break;
202
203 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
204 "retry %d more time(s)\n", ret, attempts);
205 }
206
207 /* Did we succeded or run out of retries? */
208 if (ret)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700209 goto err_log_capture;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100210
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000211 ret = guc_enable_communication(guc);
212 if (ret)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700213 goto err_log_capture;
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000214
Sagar Arun Kamble9a2cbf22017-09-26 12:47:16 +0530215 intel_huc_auth(&dev_priv->huc);
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000216 if (i915_modparams.enable_guc_submission) {
217 if (i915_modparams.guc_log_level >= 0)
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100218 gen9_enable_guc_interrupts(dev_priv);
219
220 ret = i915_guc_submission_enable(dev_priv);
221 if (ret)
Oscar Mateo3950bf32017-03-22 10:39:46 -0700222 goto err_interrupts;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100223 }
224
225 return 0;
226
227 /*
228 * We've failed to load the firmware :(
229 *
230 * Decide whether to disable GuC submission and fall back to
231 * execlist mode, and whether to hide the error by returning
232 * zero or to return -EIO, which the caller will treat as a
233 * nonfatal error (i.e. it doesn't prevent driver load, but
234 * marks the GPU as wedged until reset).
235 */
Oscar Mateo3950bf32017-03-22 10:39:46 -0700236err_interrupts:
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000237 guc_disable_communication(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700238 gen9_disable_guc_interrupts(dev_priv);
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700239err_log_capture:
240 guc_capture_load_err_log(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100241err_submission:
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000242 if (i915_modparams.enable_guc_submission)
Oscar Mateo397fce82017-03-22 10:39:52 -0700243 i915_guc_submission_fini(dev_priv);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700244err_guc:
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100245 i915_ggtt_disable_guc(dev_priv);
246
247 DRM_ERROR("GuC init failed\n");
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000248 if (i915_modparams.enable_guc_loading > 1 ||
249 i915_modparams.enable_guc_submission > 1)
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100250 ret = -EIO;
251 else
252 ret = 0;
253
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000254 if (i915_modparams.enable_guc_submission) {
255 i915_modparams.enable_guc_submission = 0;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100256 DRM_NOTE("Falling back from GuC submission to execlist mode\n");
257 }
258
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000259 i915_modparams.enable_guc_loading = 0;
Michel Thierryc4a89522017-06-05 10:12:51 -0700260 DRM_NOTE("GuC firmware loading disabled\n");
261
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100262 return ret;
263}
264
Oscar Mateo3950bf32017-03-22 10:39:46 -0700265void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
266{
Michel Thierryc4a89522017-06-05 10:12:51 -0700267 guc_free_load_err_log(&dev_priv->guc);
268
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000269 if (!i915_modparams.enable_guc_loading)
Oscar Mateob8991402017-03-28 09:53:47 -0700270 return;
271
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000272 if (i915_modparams.enable_guc_submission)
Oscar Mateo3950bf32017-03-22 10:39:46 -0700273 i915_guc_submission_disable(dev_priv);
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000274
275 guc_disable_communication(&dev_priv->guc);
276
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000277 if (i915_modparams.enable_guc_submission) {
Oscar Mateo3950bf32017-03-22 10:39:46 -0700278 gen9_disable_guc_interrupts(dev_priv);
Oscar Mateo397fce82017-03-22 10:39:52 -0700279 i915_guc_submission_fini(dev_priv);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700280 }
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000281
Oscar Mateo3950bf32017-03-22 10:39:46 -0700282 i915_ggtt_disable_guc(dev_priv);
283}