blob: 95b524c9f8f3630955874645e1410771a4820e94 [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 Wajdeczkoe8668bb2017-10-16 14:47:14 +000068 if (intel_guc_fw_select(&dev_priv->guc))
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 Wajdeczkoa16b4312017-10-04 15:33:25 +000089 intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
90 intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw);
Arkadiusz Hiler29ad6a32017-03-14 15:28:09 +010091}
92
Oscar Mateo3950bf32017-03-22 10:39:46 -070093void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
94{
Michal Wajdeczkoa16b4312017-10-04 15:33:25 +000095 intel_uc_fw_fini(&dev_priv->guc.fw);
96 intel_uc_fw_fini(&dev_priv->huc.fw);
Oscar Mateo3950bf32017-03-22 10:39:46 -070097}
98
Sagar Arun Kamble1fc556f2017-10-04 15:33:24 +000099/**
100 * intel_uc_init_mmio - setup uC MMIO access
101 *
102 * @dev_priv: device private
103 *
104 * Setup minimal state necessary for MMIO accesses later in the
105 * initialization sequence.
106 */
107void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
108{
Michal Wajdeczko9bf384c2017-10-04 18:13:41 +0000109 intel_guc_init_send_regs(&dev_priv->guc);
Sagar Arun Kamble1fc556f2017-10-04 15:33:24 +0000110}
111
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700112static void guc_capture_load_err_log(struct intel_guc *guc)
113{
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000114 if (!guc->log.vma || i915_modparams.guc_log_level < 0)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700115 return;
116
117 if (!guc->load_err_log)
118 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
119
120 return;
121}
122
123static void guc_free_load_err_log(struct intel_guc *guc)
124{
125 if (guc->load_err_log)
126 i915_gem_object_put(guc->load_err_log);
127}
128
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000129static int guc_enable_communication(struct intel_guc *guc)
130{
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000131 struct drm_i915_private *dev_priv = guc_to_i915(guc);
132
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000133 if (HAS_GUC_CT(dev_priv))
134 return intel_guc_enable_ct(guc);
135
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000136 guc->send = intel_guc_send_mmio;
137 return 0;
138}
139
140static void guc_disable_communication(struct intel_guc *guc)
141{
Michal Wajdeczkof8a58d62017-05-26 11:13:25 +0000142 struct drm_i915_private *dev_priv = guc_to_i915(guc);
143
144 if (HAS_GUC_CT(dev_priv))
145 intel_guc_disable_ct(guc);
146
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000147 guc->send = intel_guc_send_nop;
148}
149
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100150int intel_uc_init_hw(struct drm_i915_private *dev_priv)
151{
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000152 struct intel_guc *guc = &dev_priv->guc;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100153 int ret, attempts;
154
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000155 if (!i915_modparams.enable_guc_loading)
Oscar Mateob8991402017-03-28 09:53:47 -0700156 return 0;
157
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000158 guc_disable_communication(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100159 gen9_reset_guc_interrupts(dev_priv);
160
161 /* We need to notify the guc whenever we change the GGTT */
162 i915_ggtt_enable_guc(dev_priv);
163
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000164 if (i915_modparams.enable_guc_submission) {
Oscar Mateo397fce82017-03-22 10:39:52 -0700165 /*
166 * This is stuff we need to have available at fw load time
167 * if we are planning to enable submission later
168 */
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530169 ret = intel_guc_submission_init(guc);
Oscar Mateo397fce82017-03-22 10:39:52 -0700170 if (ret)
171 goto err_guc;
172 }
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100173
daniele.ceraolospurio@intel.com13f6c712017-04-06 17:18:52 -0700174 /* init WOPCM */
175 I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
176 I915_WRITE(DMA_GUC_WOPCM_OFFSET,
177 GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
178
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100179 /* WaEnableuKernelHeaderValidFix:skl */
180 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
181 if (IS_GEN9(dev_priv))
182 attempts = 3;
183 else
184 attempts = 1;
185
186 while (attempts--) {
187 /*
188 * Always reset the GuC just before (re)loading, so
189 * that the state and timing are fairly predictable
190 */
191 ret = __intel_uc_reset_hw(dev_priv);
192 if (ret)
193 goto err_submission;
194
195 intel_huc_init_hw(&dev_priv->huc);
Michal Wajdeczko5d53be42017-10-16 14:47:11 +0000196 intel_guc_init_params(guc);
Michal Wajdeczkoe8668bb2017-10-16 14:47:14 +0000197 ret = intel_guc_fw_upload(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100198 if (ret == 0 || ret != -EAGAIN)
199 break;
200
201 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
202 "retry %d more time(s)\n", ret, attempts);
203 }
204
205 /* Did we succeded or run out of retries? */
206 if (ret)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700207 goto err_log_capture;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100208
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000209 ret = guc_enable_communication(guc);
210 if (ret)
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700211 goto err_log_capture;
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000212
Sagar Arun Kamble9a2cbf22017-09-26 12:47:16 +0530213 intel_huc_auth(&dev_priv->huc);
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000214 if (i915_modparams.enable_guc_submission) {
215 if (i915_modparams.guc_log_level >= 0)
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100216 gen9_enable_guc_interrupts(dev_priv);
217
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530218 ret = intel_guc_submission_enable(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100219 if (ret)
Oscar Mateo3950bf32017-03-22 10:39:46 -0700220 goto err_interrupts;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100221 }
222
Michal Wajdeczko86ffc312017-10-16 14:47:17 +0000223 dev_info(dev_priv->drm.dev, "GuC %s (firmware %s [version %u.%u])\n",
224 i915_modparams.enable_guc_submission ? "submission enabled" :
225 "loaded",
226 guc->fw.path,
227 guc->fw.major_ver_found, guc->fw.minor_ver_found);
228
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100229 return 0;
230
231 /*
232 * We've failed to load the firmware :(
233 *
234 * Decide whether to disable GuC submission and fall back to
235 * execlist mode, and whether to hide the error by returning
236 * zero or to return -EIO, which the caller will treat as a
237 * nonfatal error (i.e. it doesn't prevent driver load, but
238 * marks the GPU as wedged until reset).
239 */
Oscar Mateo3950bf32017-03-22 10:39:46 -0700240err_interrupts:
Michal Wajdeczko789a6252017-05-02 10:32:42 +0000241 guc_disable_communication(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700242 gen9_disable_guc_interrupts(dev_priv);
Daniele Ceraolo Spurioac58d2a2017-05-22 10:50:28 -0700243err_log_capture:
244 guc_capture_load_err_log(guc);
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100245err_submission:
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000246 if (i915_modparams.enable_guc_submission)
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530247 intel_guc_submission_fini(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700248err_guc:
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100249 i915_ggtt_disable_guc(dev_priv);
250
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000251 if (i915_modparams.enable_guc_loading > 1 ||
Michal Wajdeczko9f652082017-10-16 14:47:22 +0000252 i915_modparams.enable_guc_submission > 1) {
253 DRM_ERROR("GuC init failed. Firmware loading disabled.\n");
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100254 ret = -EIO;
Michal Wajdeczko9f652082017-10-16 14:47:22 +0000255 } else {
256 DRM_NOTE("GuC init failed. Firmware loading disabled.\n");
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100257 ret = 0;
Michal Wajdeczko9f652082017-10-16 14:47:22 +0000258 }
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100259
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000260 if (i915_modparams.enable_guc_submission) {
261 i915_modparams.enable_guc_submission = 0;
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100262 DRM_NOTE("Falling back from GuC submission to execlist mode\n");
263 }
264
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000265 i915_modparams.enable_guc_loading = 0;
Michel Thierryc4a89522017-06-05 10:12:51 -0700266
Arkadiusz Hiler6cd5a722017-03-14 15:28:11 +0100267 return ret;
268}
269
Oscar Mateo3950bf32017-03-22 10:39:46 -0700270void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
271{
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530272 struct intel_guc *guc = &dev_priv->guc;
273
274 guc_free_load_err_log(guc);
Michel Thierryc4a89522017-06-05 10:12:51 -0700275
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000276 if (!i915_modparams.enable_guc_loading)
Oscar Mateob8991402017-03-28 09:53:47 -0700277 return;
278
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000279 if (i915_modparams.enable_guc_submission)
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530280 intel_guc_submission_disable(guc);
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000281
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530282 guc_disable_communication(guc);
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000283
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000284 if (i915_modparams.enable_guc_submission) {
Oscar Mateo3950bf32017-03-22 10:39:46 -0700285 gen9_disable_guc_interrupts(dev_priv);
Sagar Arun Kambledb14d0c52017-11-16 19:02:39 +0530286 intel_guc_submission_fini(guc);
Oscar Mateo3950bf32017-03-22 10:39:46 -0700287 }
Michal Wajdeczko2f640852017-05-26 11:13:24 +0000288
Oscar Mateo3950bf32017-03-22 10:39:46 -0700289 i915_ggtt_disable_guc(dev_priv);
290}