blob: c3981aa4fb28b7f44b309406effcd492bec0c6e4 [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
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010025#include "intel_uc.h"
Sagar Arun Kamblea2695742017-11-16 19:02:41 +053026#include "intel_guc_submission.h"
Michal Wajdeczkoddf79d82017-10-04 18:13:42 +000027#include "i915_drv.h"
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010028
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +010029/* Reset GuC providing us with fresh state for both GuC and HuC.
30 */
31static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
32{
33 int ret;
34 u32 guc_status;
35
Michel Thierrycb20a3c2017-10-30 11:56:14 -070036 ret = intel_reset_guc(dev_priv);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +010037 if (ret) {
Michel Thierrycb20a3c2017-10-30 11:56:14 -070038 DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +010039 return ret;
40 }
41
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",
45 guc_status);
46
47 return ret;
48}
49
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010050void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
51{
52 if (!HAS_GUC(dev_priv)) {
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000053 if (i915_modparams.enable_guc_loading > 0 ||
54 i915_modparams.enable_guc_submission > 0)
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000055 DRM_INFO("Ignoring GuC options, no hardware\n");
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010056
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000057 i915_modparams.enable_guc_loading = 0;
58 i915_modparams.enable_guc_submission = 0;
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000059 return;
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010060 }
Arkadiusz Hilerb551f612017-03-14 15:28:13 +010061
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000062 /* A negative value means "use platform default" */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000063 if (i915_modparams.enable_guc_loading < 0)
64 i915_modparams.enable_guc_loading = HAS_GUC_UCODE(dev_priv);
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000065
66 /* Verify firmware version */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000067 if (i915_modparams.enable_guc_loading) {
Michal Wajdeczko0dd940c2017-12-06 13:53:11 +000068 if (!intel_uc_fw_is_selected(&dev_priv->guc.fw))
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000069 i915_modparams.enable_guc_loading = 0;
Arkadiusz Hilerb551f612017-03-14 15:28:13 +010070 }
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000071
72 /* Can't enable guc submission without guc loaded */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000073 if (!i915_modparams.enable_guc_loading)
74 i915_modparams.enable_guc_submission = 0;
Michal Wajdeczkod4a70a12017-03-15 13:37:41 +000075
76 /* A negative value means "use platform default" */
Michal Wajdeczko4f044a82017-09-19 19:38:44 +000077 if (i915_modparams.enable_guc_submission < 0)
78 i915_modparams.enable_guc_submission = HAS_GUC_SCHED(dev_priv);
Arkadiusz Hilerd2be9f22017-03-14 15:28:10 +010079}
80
Michal Wajdeczko3af7a9c2017-10-04 15:33:27 +000081void intel_uc_init_early(struct drm_i915_private *dev_priv)
82{
Michal Wajdeczko9bf384c2017-10-04 18:13:41 +000083 intel_guc_init_early(&dev_priv->guc);
Michal Wajdeczko2fe2d4e2017-12-06 13:53:10 +000084 intel_huc_init_early(&dev_priv->huc);
Michal Wajdeczko3af7a9c2017-10-04 15:33:27 +000085}
86
Arkadiusz Hiler29ad6a32017-03-14 15:28:09 +010087void intel_uc_init_fw(struct drm_i915_private *dev_priv)
88{
Michal Wajdeczkoa655aeb2017-12-06 13:53:13 +000089 if (!USES_GUC(dev_priv))
90 return;
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 Wajdeczkoa655aeb2017-12-06 13:53:13 +000098 if (!USES_GUC(dev_priv))
99 return;
100
Michal Wajdeczkoa16b4312017-10-04 15:33:25 +0000101 intel_uc_fw_fini(&dev_priv->guc.fw);
102 intel_uc_fw_fini(&dev_priv->huc.fw);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700103}
104
Sagar Arun Kamble1fc556f2017-10-04 15:33:24 +0000105/**
106 * intel_uc_init_mmio - setup uC MMIO access
107 *
108 * @dev_priv: device private
109 *
110 * Setup minimal state necessary for MMIO accesses later in the
111 * initialization sequence.
112 */
113void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
114{
Michal Wajdeczko9bf384c2017-10-04 18:13:41 +0000115 intel_guc_init_send_regs(&dev_priv->guc);
Sagar Arun Kamble1fc556f2017-10-04 15:33:24 +0000116}
117
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700118static void guc_capture_load_err_log(struct intel_guc *guc)
119{
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000120 if (!guc->log.vma || i915_modparams.guc_log_level < 0)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700121 return;
122
123 if (!guc->load_err_log)
124 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
125
126 return;
127}
128
129static void guc_free_load_err_log(struct intel_guc *guc)
130{
131 if (guc->load_err_log)
132 i915_gem_object_put(guc->load_err_log);
133}
134
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000135static int guc_enable_communication(struct intel_guc *guc)
136{
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000137 struct drm_i915_private *dev_priv = guc_to_i915(guc);
138
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000139 if (HAS_GUC_CT(dev_priv))
140 return intel_guc_enable_ct(guc);
141
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000142 guc->send = intel_guc_send_mmio;
143 return 0;
144}
145
146static void guc_disable_communication(struct intel_guc *guc)
147{
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000148 struct drm_i915_private *dev_priv = guc_to_i915(guc);
149
150 if (HAS_GUC_CT(dev_priv))
151 intel_guc_disable_ct(guc);
152
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000153 guc->send = intel_guc_send_nop;
154}
155
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100156int intel_uc_init_hw(struct drm_i915_private *dev_priv)
157{
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000158 struct intel_guc *guc = &dev_priv->guc;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100159 int ret, attempts;
160
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000161 if (!USES_GUC(dev_priv))
Oscar Mateob8991402017-03-28 09:53:47 -0700162 return 0;
163
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000164 guc_disable_communication(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100165 gen9_reset_guc_interrupts(dev_priv);
166
167 /* We need to notify the guc whenever we change the GGTT */
168 i915_ggtt_enable_guc(dev_priv);
169
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000170 if (USES_GUC_SUBMISSION(dev_priv)) {
Oscar Mateo397fce82017-03-22 10:39:52 -0700171 /*
172 * This is stuff we need to have available at fw load time
173 * if we are planning to enable submission later
174 */
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530175 ret = intel_guc_submission_init(guc);
Oscar Mateo397fce82017-03-22 10:39:52 -0700176 if (ret)
177 goto err_guc;
178 }
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100179
daniele.ceraolospurio@intel.com13f6c712017-04-06 17:18:52 -0700180 /* init WOPCM */
181 I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
182 I915_WRITE(DMA_GUC_WOPCM_OFFSET,
183 GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
184
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100185 /* WaEnableuKernelHeaderValidFix:skl */
186 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
187 if (IS_GEN9(dev_priv))
188 attempts = 3;
189 else
190 attempts = 1;
191
192 while (attempts--) {
193 /*
194 * Always reset the GuC just before (re)loading, so
195 * that the state and timing are fairly predictable
196 */
197 ret = __intel_uc_reset_hw(dev_priv);
198 if (ret)
199 goto err_submission;
200
201 intel_huc_init_hw(&dev_priv->huc);
Michal Wajdeczko5d53be42017-10-16 14:47:11 +0000202 intel_guc_init_params(guc);
Michal Wajdeczkoe8668bb2017-10-16 14:47:14 +0000203 ret = intel_guc_fw_upload(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100204 if (ret == 0 || ret != -EAGAIN)
205 break;
206
207 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
208 "retry %d more time(s)\n", ret, attempts);
209 }
210
211 /* Did we succeded or run out of retries? */
212 if (ret)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700213 goto err_log_capture;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100214
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000215 ret = guc_enable_communication(guc);
216 if (ret)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700217 goto err_log_capture;
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000218
Sagar Arun Kamble9a2cbf22017-09-26 12:47:16 +0530219 intel_huc_auth(&dev_priv->huc);
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000220 if (USES_GUC_SUBMISSION(dev_priv)) {
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000221 if (i915_modparams.guc_log_level >= 0)
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100222 gen9_enable_guc_interrupts(dev_priv);
223
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530224 ret = intel_guc_submission_enable(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100225 if (ret)
Oscar Mateo3950bf32017-03-22 10:39:46 -0700226 goto err_interrupts;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100227 }
228
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000229 dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
Michal Wajdeczko86ffc312017-10-16 14:47:17 +0000230 guc->fw.major_ver_found, guc->fw.minor_ver_found);
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000231 dev_info(dev_priv->drm.dev, "GuC submission %s\n",
232 enableddisabled(USES_GUC_SUBMISSION(dev_priv)));
Michal Wajdeczko86ffc312017-10-16 14:47:17 +0000233
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100234 return 0;
235
236 /*
237 * We've failed to load the firmware :(
238 *
239 * Decide whether to disable GuC submission and fall back to
240 * execlist mode, and whether to hide the error by returning
241 * zero or to return -EIO, which the caller will treat as a
242 * nonfatal error (i.e. it doesn't prevent driver load, but
243 * marks the GPU as wedged until reset).
244 */
Oscar Mateo3950bf32017-03-22 10:39:46 -0700245err_interrupts:
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000246 guc_disable_communication(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700247 gen9_disable_guc_interrupts(dev_priv);
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700248err_log_capture:
249 guc_capture_load_err_log(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100250err_submission:
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000251 if (USES_GUC_SUBMISSION(dev_priv))
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530252 intel_guc_submission_fini(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700253err_guc:
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100254 i915_ggtt_disable_guc(dev_priv);
255
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000256 if (i915_modparams.enable_guc_loading > 1 ||
Michal Wajdeczko9f652082017-10-16 14:47:22 +0000257 i915_modparams.enable_guc_submission > 1) {
258 DRM_ERROR("GuC init failed. Firmware loading disabled.\n");
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100259 ret = -EIO;
Michal Wajdeczko9f652082017-10-16 14:47:22 +0000260 } else {
261 DRM_NOTE("GuC init failed. Firmware loading disabled.\n");
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100262 ret = 0;
Michal Wajdeczko9f652082017-10-16 14:47:22 +0000263 }
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100264
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000265 if (USES_GUC_SUBMISSION(dev_priv)) {
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000266 i915_modparams.enable_guc_submission = 0;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100267 DRM_NOTE("Falling back from GuC submission to execlist mode\n");
268 }
269
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000270 i915_modparams.enable_guc_loading = 0;
Michel Thierryc4a89522017-06-05 10:12:51 -0700271
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100272 return ret;
273}
274
Oscar Mateo3950bf32017-03-22 10:39:46 -0700275void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
276{
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530277 struct intel_guc *guc = &dev_priv->guc;
278
279 guc_free_load_err_log(guc);
Michel Thierryc4a89522017-06-05 10:12:51 -0700280
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000281 if (!USES_GUC(dev_priv))
Oscar Mateob8991402017-03-28 09:53:47 -0700282 return;
283
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000284 if (USES_GUC_SUBMISSION(dev_priv))
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530285 intel_guc_submission_disable(guc);
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000286
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530287 guc_disable_communication(guc);
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000288
Michal Wajdeczko93ffbe82017-12-06 13:53:12 +0000289 if (USES_GUC_SUBMISSION(dev_priv)) {
Oscar Mateo3950bf32017-03-22 10:39:46 -0700290 gen9_disable_guc_interrupts(dev_priv);
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530291 intel_guc_submission_fini(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700292 }
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000293
Oscar Mateo3950bf32017-03-22 10:39:46 -0700294 i915_ggtt_disable_guc(dev_priv);
295}