]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
drm/i915/uc: Unify uc_fw status tracking
[linux.git] / drivers / gpu / drm / i915 / gt / uc / intel_uc_fw.c
1 /*
2  * Copyright © 2016-2017 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 <linux/bitfield.h>
26 #include <linux/firmware.h>
27 #include <drm/drm_print.h>
28
29 #include "intel_uc_fw.h"
30 #include "i915_drv.h"
31
32 /*
33  * List of required GuC and HuC binaries per-platform.
34  * Must be ordered based on platform + revid, from newer to older.
35  */
36 #define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
37         fw_def(ICELAKE,    0, guc_def(icl, 33, 0, 0), huc_def(icl,  8,  4, 3238)) \
38         fw_def(COFFEELAKE, 0, guc_def(kbl, 33, 0, 0), huc_def(kbl, 02, 00, 1810)) \
39         fw_def(GEMINILAKE, 0, guc_def(glk, 33, 0, 0), huc_def(glk, 03, 01, 2893)) \
40         fw_def(KABYLAKE,   0, guc_def(kbl, 33, 0, 0), huc_def(kbl, 02, 00, 1810)) \
41         fw_def(BROXTON,    0, guc_def(bxt, 33, 0, 0), huc_def(bxt, 01,  8, 2893)) \
42         fw_def(SKYLAKE,    0, guc_def(skl, 33, 0, 0), huc_def(skl, 01, 07, 1398))
43
44 #define __MAKE_UC_FW_PATH(prefix_, name_, separator_, major_, minor_, patch_) \
45         "i915/" \
46         __stringify(prefix_) name_ \
47         __stringify(major_) separator_ \
48         __stringify(minor_) separator_ \
49         __stringify(patch_) ".bin"
50
51 #define MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_) \
52         __MAKE_UC_FW_PATH(prefix_, "_guc_", ".", major_, minor_, patch_)
53
54 #define MAKE_HUC_FW_PATH(prefix_, major_, minor_, bld_num_) \
55         __MAKE_UC_FW_PATH(prefix_, "_huc_ver", "_", major_, minor_, bld_num_)
56
57 /* All blobs need to be declared via MODULE_FIRMWARE() */
58 #define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
59         MODULE_FIRMWARE(guc_); \
60         MODULE_FIRMWARE(huc_);
61
62 INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
63
64 /* The below structs and macros are used to iterate across the list of blobs */
65 struct __packed uc_fw_blob {
66         u8 major;
67         u8 minor;
68         const char *path;
69 };
70
71 #define UC_FW_BLOB(major_, minor_, path_) \
72         { .major = major_, .minor = minor_, .path = path_ }
73
74 #define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
75         UC_FW_BLOB(major_, minor_, \
76                    MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_))
77
78 #define HUC_FW_BLOB(prefix_, major_, minor_, bld_num_) \
79         UC_FW_BLOB(major_, minor_, \
80                    MAKE_HUC_FW_PATH(prefix_, major_, minor_, bld_num_))
81
82 struct __packed uc_fw_platform_requirement {
83         enum intel_platform p;
84         u8 rev; /* first platform rev using this FW */
85         const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
86 };
87
88 #define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
89 { \
90         .p = INTEL_##platform_, \
91         .rev = revid_, \
92         .blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
93         .blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
94 },
95
96 static void
97 __uc_fw_auto_select(struct intel_uc_fw *uc_fw, enum intel_platform p, u8 rev)
98 {
99         static const struct uc_fw_platform_requirement fw_blobs[] = {
100                 INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
101         };
102         int i;
103
104         for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
105                 if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
106                         const struct uc_fw_blob *blob =
107                                         &fw_blobs[i].blobs[uc_fw->type];
108                         uc_fw->path = blob->path;
109                         uc_fw->major_ver_wanted = blob->major;
110                         uc_fw->minor_ver_wanted = blob->minor;
111                         break;
112                 }
113         }
114
115         /* make sure the list is ordered as expected */
116         if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
117                 for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
118                         if (fw_blobs[i].p < fw_blobs[i - 1].p)
119                                 continue;
120
121                         if (fw_blobs[i].p == fw_blobs[i - 1].p &&
122                             fw_blobs[i].rev < fw_blobs[i - 1].rev)
123                                 continue;
124
125                         pr_err("invalid FW blob order: %s r%u comes before %s r%u\n",
126                                intel_platform_name(fw_blobs[i - 1].p),
127                                fw_blobs[i - 1].rev,
128                                intel_platform_name(fw_blobs[i].p),
129                                fw_blobs[i].rev);
130
131                         uc_fw->path = NULL;
132                 }
133         }
134 }
135
136 static bool
137 __uc_fw_override(struct intel_uc_fw *uc_fw)
138 {
139         switch (uc_fw->type) {
140         case INTEL_UC_FW_TYPE_GUC:
141                 uc_fw->path = i915_modparams.guc_firmware_path;
142                 break;
143         case INTEL_UC_FW_TYPE_HUC:
144                 uc_fw->path = i915_modparams.huc_firmware_path;
145                 break;
146         }
147
148         return uc_fw->path;
149 }
150
151 /**
152  * intel_uc_fw_init_early - initialize the uC object and select the firmware
153  * @i915: device private
154  * @uc_fw: uC firmware
155  * @type: type of uC
156  *
157  * Initialize the state of our uC object and relevant tracking and select the
158  * firmware to fetch and load.
159  */
160 void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
161                             enum intel_uc_fw_type type,
162                             struct drm_i915_private *i915)
163 {
164         /*
165          * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
166          * before we're looked at the HW caps to see if we have uc support
167          */
168         BUILD_BUG_ON(INTEL_UC_FIRMWARE_UNINITIALIZED);
169         GEM_BUG_ON(uc_fw->status);
170         GEM_BUG_ON(uc_fw->path);
171
172         uc_fw->type = type;
173
174         if (HAS_GT_UC(i915) && likely(!__uc_fw_override(uc_fw)))
175                 __uc_fw_auto_select(uc_fw, INTEL_INFO(i915)->platform,
176                                     INTEL_REVID(i915));
177
178         if (uc_fw->path)
179                 uc_fw->status = INTEL_UC_FIRMWARE_SELECTED;
180         else
181                 uc_fw->status = INTEL_UC_FIRMWARE_NOT_SUPPORTED;
182 }
183
184 /**
185  * intel_uc_fw_fetch - fetch uC firmware
186  *
187  * @dev_priv: device private
188  * @uc_fw: uC firmware
189  *
190  * Fetch uC firmware into GEM obj.
191  */
192 void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
193                        struct intel_uc_fw *uc_fw)
194 {
195         struct pci_dev *pdev = dev_priv->drm.pdev;
196         struct drm_i915_gem_object *obj;
197         const struct firmware *fw = NULL;
198         struct uc_css_header *css;
199         size_t size;
200         int err;
201
202         GEM_BUG_ON(!intel_uc_fw_supported(uc_fw));
203
204         err = request_firmware(&fw, uc_fw->path, &pdev->dev);
205         if (err)
206                 goto fail;
207
208         DRM_DEBUG_DRIVER("%s fw size %zu ptr %p\n",
209                          intel_uc_fw_type_repr(uc_fw->type), fw->size, fw);
210
211         /* Check the size of the blob before examining buffer contents */
212         if (fw->size < sizeof(struct uc_css_header)) {
213                 DRM_WARN("%s: Unexpected firmware size (%zu, min %zu)\n",
214                          intel_uc_fw_type_repr(uc_fw->type),
215                          fw->size, sizeof(struct uc_css_header));
216                 err = -ENODATA;
217                 goto fail;
218         }
219
220         css = (struct uc_css_header *)fw->data;
221
222         /* Firmware bits always start from header */
223         uc_fw->header_offset = 0;
224         uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
225                               css->key_size_dw - css->exponent_size_dw) *
226                              sizeof(u32);
227
228         if (uc_fw->header_size != sizeof(struct uc_css_header)) {
229                 DRM_WARN("%s: Mismatched firmware header definition\n",
230                          intel_uc_fw_type_repr(uc_fw->type));
231                 err = -ENOEXEC;
232                 goto fail;
233         }
234
235         /* then, uCode */
236         uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
237         uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
238
239         /* now RSA */
240         if (css->key_size_dw != UOS_RSA_SCRATCH_COUNT) {
241                 DRM_WARN("%s: Mismatched firmware RSA key size (%u)\n",
242                          intel_uc_fw_type_repr(uc_fw->type), css->key_size_dw);
243                 err = -ENOEXEC;
244                 goto fail;
245         }
246         uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
247         uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
248
249         /* At least, it should have header, uCode and RSA. Size of all three. */
250         size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
251         if (fw->size < size) {
252                 DRM_WARN("%s: Truncated firmware (%zu, expected %zu)\n",
253                          intel_uc_fw_type_repr(uc_fw->type), fw->size, size);
254                 err = -ENOEXEC;
255                 goto fail;
256         }
257
258         /* Get version numbers from the CSS header */
259         switch (uc_fw->type) {
260         case INTEL_UC_FW_TYPE_GUC:
261                 uc_fw->major_ver_found = FIELD_GET(CSS_SW_VERSION_GUC_MAJOR,
262                                                    css->sw_version);
263                 uc_fw->minor_ver_found = FIELD_GET(CSS_SW_VERSION_GUC_MINOR,
264                                                    css->sw_version);
265                 break;
266
267         case INTEL_UC_FW_TYPE_HUC:
268                 uc_fw->major_ver_found = FIELD_GET(CSS_SW_VERSION_HUC_MAJOR,
269                                                    css->sw_version);
270                 uc_fw->minor_ver_found = FIELD_GET(CSS_SW_VERSION_HUC_MINOR,
271                                                    css->sw_version);
272                 break;
273
274         default:
275                 MISSING_CASE(uc_fw->type);
276                 break;
277         }
278
279         DRM_DEBUG_DRIVER("%s fw version %u.%u (wanted %u.%u)\n",
280                          intel_uc_fw_type_repr(uc_fw->type),
281                          uc_fw->major_ver_found, uc_fw->minor_ver_found,
282                          uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
283
284         if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0) {
285                 DRM_NOTE("%s: Skipping firmware version check\n",
286                          intel_uc_fw_type_repr(uc_fw->type));
287         } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
288                    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
289                 DRM_NOTE("%s: Wrong firmware version (%u.%u, required %u.%u)\n",
290                          intel_uc_fw_type_repr(uc_fw->type),
291                          uc_fw->major_ver_found, uc_fw->minor_ver_found,
292                          uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
293                 err = -ENOEXEC;
294                 goto fail;
295         }
296
297         obj = i915_gem_object_create_shmem_from_data(dev_priv,
298                                                      fw->data, fw->size);
299         if (IS_ERR(obj)) {
300                 err = PTR_ERR(obj);
301                 DRM_DEBUG_DRIVER("%s fw object_create err=%d\n",
302                                  intel_uc_fw_type_repr(uc_fw->type), err);
303                 goto fail;
304         }
305
306         uc_fw->obj = obj;
307         uc_fw->size = fw->size;
308         uc_fw->status = INTEL_UC_FIRMWARE_AVAILABLE;
309
310         release_firmware(fw);
311         return;
312
313 fail:
314         uc_fw->status = INTEL_UC_FIRMWARE_MISSING;
315
316         DRM_WARN("%s: Failed to fetch firmware %s (error %d)\n",
317                  intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
318         DRM_INFO("%s: Firmware can be downloaded from %s\n",
319                  intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL);
320
321         release_firmware(fw);           /* OK even if fw is NULL */
322 }
323
324 static void intel_uc_fw_ggtt_bind(struct intel_uc_fw *uc_fw)
325 {
326         struct drm_i915_gem_object *obj = uc_fw->obj;
327         struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt;
328         struct i915_vma dummy = {
329                 .node.start = intel_uc_fw_ggtt_offset(uc_fw),
330                 .node.size = obj->base.size,
331                 .pages = obj->mm.pages,
332                 .vm = &ggtt->vm,
333         };
334
335         GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
336         GEM_BUG_ON(dummy.node.size > ggtt->uc_fw.size);
337
338         /* uc_fw->obj cache domains were not controlled across suspend */
339         drm_clflush_sg(dummy.pages);
340
341         ggtt->vm.insert_entries(&ggtt->vm, &dummy, I915_CACHE_NONE, 0);
342 }
343
344 static void intel_uc_fw_ggtt_unbind(struct intel_uc_fw *uc_fw)
345 {
346         struct drm_i915_gem_object *obj = uc_fw->obj;
347         struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt;
348         u64 start = intel_uc_fw_ggtt_offset(uc_fw);
349
350         ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size);
351 }
352
353 /**
354  * intel_uc_fw_upload - load uC firmware using custom loader
355  * @uc_fw: uC firmware
356  * @xfer: custom uC firmware loader function
357  *
358  * Loads uC firmware using custom loader and updates internal flags.
359  *
360  * Return: 0 on success, non-zero on failure.
361  */
362 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
363                        int (*xfer)(struct intel_uc_fw *uc_fw))
364 {
365         int err;
366
367         DRM_DEBUG_DRIVER("%s fw load %s\n",
368                          intel_uc_fw_type_repr(uc_fw->type), uc_fw->path);
369
370         /* make sure the status was cleared the last time we reset the uc */
371         GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
372
373         if (!intel_uc_fw_is_available(uc_fw))
374                 return -ENOEXEC;
375         /* Call custom loader */
376         intel_uc_fw_ggtt_bind(uc_fw);
377         err = xfer(uc_fw);
378         intel_uc_fw_ggtt_unbind(uc_fw);
379         if (err)
380                 goto fail;
381
382         uc_fw->status = INTEL_UC_FIRMWARE_TRANSFERRED;
383         DRM_DEBUG_DRIVER("%s fw xfer completed\n",
384                          intel_uc_fw_type_repr(uc_fw->type));
385
386         DRM_INFO("%s: Loaded firmware %s (version %u.%u)\n",
387                  intel_uc_fw_type_repr(uc_fw->type),
388                  uc_fw->path,
389                  uc_fw->major_ver_found, uc_fw->minor_ver_found);
390
391         return 0;
392
393 fail:
394         uc_fw->status = INTEL_UC_FIRMWARE_FAIL;
395         DRM_DEBUG_DRIVER("%s fw load failed\n",
396                          intel_uc_fw_type_repr(uc_fw->type));
397
398         DRM_WARN("%s: Failed to load firmware %s (error %d)\n",
399                  intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
400
401         return err;
402 }
403
404 int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
405 {
406         int err;
407
408         /* this should happen before the load! */
409         GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
410
411         if (!intel_uc_fw_is_available(uc_fw))
412                 return -ENOEXEC;
413
414         err = i915_gem_object_pin_pages(uc_fw->obj);
415         if (err)
416                 DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",
417                                  intel_uc_fw_type_repr(uc_fw->type), err);
418
419         return err;
420 }
421
422 void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
423 {
424         if (!intel_uc_fw_is_available(uc_fw))
425                 return;
426
427         i915_gem_object_unpin_pages(uc_fw->obj);
428 }
429
430 u32 intel_uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
431 {
432         struct drm_i915_private *i915 = to_i915(uc_fw->obj->base.dev);
433         struct i915_ggtt *ggtt = &i915->ggtt;
434         struct drm_mm_node *node = &ggtt->uc_fw;
435
436         GEM_BUG_ON(!node->allocated);
437         GEM_BUG_ON(upper_32_bits(node->start));
438         GEM_BUG_ON(upper_32_bits(node->start + node->size - 1));
439
440         return lower_32_bits(node->start);
441 }
442
443 /**
444  * intel_uc_fw_cleanup_fetch - cleanup uC firmware
445  *
446  * @uc_fw: uC firmware
447  *
448  * Cleans up uC firmware by releasing the firmware GEM obj.
449  */
450 void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw)
451 {
452         struct drm_i915_gem_object *obj;
453
454         obj = fetch_and_zero(&uc_fw->obj);
455         if (obj)
456                 i915_gem_object_put(obj);
457
458         uc_fw->status = INTEL_UC_FIRMWARE_SELECTED;
459 }
460
461 /**
462  * intel_uc_fw_dump - dump information about uC firmware
463  * @uc_fw: uC firmware
464  * @p: the &drm_printer
465  *
466  * Pretty printer for uC firmware.
467  */
468 void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p)
469 {
470         drm_printf(p, "%s firmware: %s\n",
471                    intel_uc_fw_type_repr(uc_fw->type), uc_fw->path);
472         drm_printf(p, "\tstatus: %s\n",
473                    intel_uc_fw_status_repr(uc_fw->status));
474         drm_printf(p, "\tversion: wanted %u.%u, found %u.%u\n",
475                    uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted,
476                    uc_fw->major_ver_found, uc_fw->minor_ver_found);
477         drm_printf(p, "\theader: offset %u, size %u\n",
478                    uc_fw->header_offset, uc_fw->header_size);
479         drm_printf(p, "\tuCode: offset %u, size %u\n",
480                    uc_fw->ucode_offset, uc_fw->ucode_size);
481         drm_printf(p, "\tRSA: offset %u, size %u\n",
482                    uc_fw->rsa_offset, uc_fw->rsa_size);
483 }